菜鸟笔记:利用定时器创建一个无限滚动的背景图片。
cocos2dx中三种定时器:schedule,scheduleUpdate,scheduleOnce:
API:
//更新定时器,每帧调用1次。每个节点只能有1个被调度的update函数 void scheduleUpdate(void); //卸载更新定时器 void unscheduleUpdate(void); //自定义定时器,如果重复调用,那调用间隔会更新,而不会再次调用 //interval,调用时间间隔,如果为0,建议使用scheduleUpdate //repeat,回调函数会被执行repeat+1次,kCCRepeatForever是无限次调用 //delay,第一次执行前的延时 void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay); void schedule(SEL_SCHEDULE selector, float interval); void scheduleOnce(SEL_SCHEDULE selector, float delay); void schedule(SEL_SCHEDULE selector); //卸载自定义定时器 void unschedule(SEL_SCHEDULE selector); void unscheduleAllSelectors(void); //恢复所有定时器和动作,OnEnter调用 void resumeSchedulerAndActions(void); //暂停所有定时器和动作,OnExit调用 void pauseSchedulerAndActions(void); //scheduleUpdate每帧调用 virtual void update(float delta);
定时器的因能力有限就不做介绍了,我主要想介绍怎样实现如题动画,闲话不多说,看步骤:
1、准备两张可拼接的背景图片;
2、代码实现:
bool HelloWorld::init() { if ( !Layer::init() ) { return false; } auto visibleSize = Director::getInstance()->getVisibleSize(); //滚动的背景 bg_1 = Sprite::create("image/rollbg/bg1.jpg"); bg_2 = Sprite::create("image/rollbg/bg2.jpg"); //为了填满屏幕所以进行适当的缩放 bg_1->setScaleX(visibleSize.width/ bg_1->getContentSize().width); bg_1->setScaleY(visibleSize.height / bg_1->getContentSize().height); bg_2->setScaleX(visibleSize.width/ bg_2->getContentSize().width); bg_2->setScaleY(visibleSize.height / bg_2->getContentSize().height); //设置精灵的位置 bg_1->setPosition(Vec2(visibleSize.width / 2, visibleSize.height / 2)); bg_2->setPosition(Vec2(visibleSize.width / 2 +bg_1->getContentSize().width, visibleSize.height / 2)); //可适当加入不同速率的云彩作呼应 bg_3->setPosition(Vec2(visibleSize.width / 2 +bg_3->getContentSize().width, visibleSize.height / 2+100)); addChild(bg_1); addChild(bg_2); addChild(bg_3); //定时器,不填写参数,默认每帧都要执行一次moveBg方法 this->schedule(schedule_selector(HelloWorld::moveBg)); return true; }
3、关键处:设置背景移动的速度,即每次调用moveBg方法,要移动多少距离
void HelloWorld::moveBg(float ft) { //每次调用将精灵位置的x轴移动0.5 bg_1->setPosition(Vec2(bg_1->getPositionX()-0.5,bg_1->getPositionY())); bg_2->setPosition(Vec2(bg_2->getPositionX() - 0.5, bg_2->getPositionY())); //设置不同速率的云彩 bg_3->setPosition(Vec2(bg_3->getPositionX() - 0.3, bg_3->getPositionY())); //当背景1刚好移出屏幕,则将背景1的位置重新设置到背景2的后面,以此类推 /* *注意:区分getPosition()方法所对应的位置 */ if (bg_1->getPositionX()<=-bg_1->getContentSize().width/2) { bg_1->setPosition(Vec2(bg_1->getContentSize().width*3/2,bg_1->getPositionY())); } if (bg_2->getPositionX()<=-bg_2->getContentSize().width/2) { bg_2->setPosition(Vec2(bg_2->getContentSize().width * 3 / 2, bg_1->getPositionY())); } if (bg_3->getPositionX() <= -bg_3->getContentSize().width / 2) { bg_3->setPosition(Vec2(bg_1->getContentSize().width * 3 / 2, bg_3->getPositionY())); } }
4、停止背景的移动:即取消定时器
//取消执行的定时器 unschedule(schedule_selector(HelloWorld::moveBg));
注:bg_3是我添加的一朵云彩(数量可自己定义),为的是让整体运动的界面有层次感
OK,代码就这样,接下来看看运行的效果: