Clutter学习(十):多个timeline——ClutterScore

来源:互联网 发布:发明知乎 编辑:程序博客网 时间:2024/05/05 13:27

  在上一次的学习中,我们学习了ClutterTimeline,我们通过ClutterScore加入多个ClutterTimeline,这些timeline可以同时触发,也可以依次触发。我们将在这里讨论他们。学习资料来源:Grouping Timelines in ScoreExample

  使用方法:先创建一个ClutterScore,然后通过clutter_score_append()将各个timeline加入。这个函数的第二个参数如果为NULL,表示作为第一个timeline执行,可以同时又多个第一个timeline,第二个参数也可以是某个timeline,表明这个timeline在某个timeline后面依次执行。这两种方式可以分别表述为并行和串行。假设我们有两个timeline,间隔时间分别是她t1 和t2,他们都分别设置了maker-reached的触发,时间分别为a1和a2,他们也同时具有new-frame的帧刷新触发。

clutter1

  上图是串行,即依次执行的说明,一个循环的时间为作为timeline的时间总和,即t1+t2+t3+……+tn,我们需要注意的是有效的new-frame时间,一个timeline的刷屏触发,只在其有效时间内。我们在t1的new-frame中设置的动态效果,会在t2开始的时候暂停,并在t1重新还是的时候继续执行。

clutter2

  右图是并行,即同时触发的例子,一个循环时间为MAX(t1,t2,t3,……,tn),同样如果使用new-frame时,需要注意只在timeline自己有效的时间范围内。这一点必须强调。通过并行和串行的两种方式的组合可以构造符合我们需求复制的timeline方式。不过根据编程思想,我们应尽量减少复制度,力求简洁。通过增加复杂度来渲染自己编程能力是无知者无畏。

  下面是我们的一个例子。我们设置了两个timeline,即timeline1和timeliness2,他们的new-frame触发分别为旋转和平移一个png的图像。同时通过mark-reached的触发,将timestamp打印出来,来跟踪他们的执行方式。

#include <clutter/clutter.h>
#include <stdlib.h>
#include <time.h>

long offset = 0;
long get_time(){
    return time(0)-offset;
}

/*这是timline1的new-frame触发*/
void on_timeline_new_frame1(ClutterTimeline * timeline, gint frame_num, gpointer data){
    static float step = 0;

    step +=1.0;
    if(step >= 360)
        step = 0;
    clutter_actor_set_rotation((ClutterActor *) data,CLUTTER_X_AXIS, step,0,0,0);
}

/*这是timline2的new-frame触发*/
void on_timeline_new_frame2(ClutterTimeline * timeline, gint frame_num, gpointer data){
    clutter_actor_move_by((ClutterActor *) data,0.4,0);
}

/*这是timeline1和 timeline2的mark-reached的触发*/
void on_timeline_marker_reached(ClutterTimeline * timeline,
gchar * marker_name, gint msecs_num,  gpointer data){
    printf("%03ld marker %s reached : msec-num = %d /n",get_time(),marker_name,msecs_num);
}

int main(int argc, char* argv[]){
    ClutterColor stage_color = {0x00,0x00,0x00,0xff};

    clutter_init(&argc,&argv);
   /*Clutter stage and rect*/
    ClutterActor *stage = clutter_stage_get_default();
    clutter_actor_set_size(stage,800,300);
    clutter_stage_set_color(CLUTTER_STAGE(stage), & stage_color);
    ClutterActor * rect = clutter_texture_new_from_file("20.png",NULL);
    if(rect == NULL){
         printf("Can't locate the texture file : 20.png/n");
         return -1;
    }
    clutter_actor_set_position(rect,50,150);
    clutter_container_add_actor(CLUTTER_CONTAINER(stage),rect);
    clutter_actor_show(rect);
    clutter_actor_show(stage);

    /*Clutter Score study */
    ClutterScore  *score = clutter_score_new();
    clutter_score_set_loop(score,TRUE);

    ClutterTimeline * timeline1 = clutter_timeline_new(5000);
    clutter_timeline_add_marker_at_time(timeline1, "my-mark",1000);
    g_signal_connect(timeline1,"new-frame",G_CALLBACK(on_timeline_new_frame1),rect);
    g_signal_connect(timeline1,"marker-reached", G_CALLBACK(on_timeline_marker_reached),NULL);   
    clutter_score_append(score,NULL,timeline1);

    ClutterTimeline * timeline2 = clutter_timeline_new(6000);
    clutter_timeline_add_marker_at_time(timeline2,"timeline2",2000);
    g_signal_connect(timeline2,"new-frame",G_CALLBACK(on_timeline_new_frame2),rect);
    g_signal_connect(timeline2,"marker-reached", G_CALLBACK(on_timeline_marker_reached),NULL);   
    clutter_score_append(score,NULL,timeline2);/*并行测试*/
    //clutter_score_append(score,timeline1,timeline2); /*串行测试*/

    offset = time(0);
    clutter_score_start(score);

    clutter_main();

    g_object_unref(timeline1);
    g_object_unref(timeline2);
    g_object_unref(score);

    return EXIT_SUCCESS;
}

相关链接:
我的Clutter相关博客