-
一月 16
很多游戏中,能看到很多的效果,今天,我们来看一个最简单的效果,旋转,先来看一个GIF,在石头剪子布游戏中,我们为了模拟真实场景,让手可以上下旋转。
首先,我们创建一个精灵,来表示左手,然后把它加入到场景中去:
lefthand = CCSprite::create("finger-guessing/hand/1.png"); lefthand->setAnchorPoint(ccp(0.5,0.5)); lefthand->setPosition(ccp(10,284)); this->addChild(lefthand);
上面有个很重要的方法:setAnchorPoint,设置注册点,这个请参考前面的文章,这个点很重要,因为我们旋转一个精灵,是要按照一个点来旋转的,这个点就是注册点,我们把它设置为图片的中心
我们按照同样的方法,创建右手,但是,这里有一个小技巧,因为左右手其实是一样的,只是方向不一样,我们就没必要再弄一张图片了,为了节省资源和内存,我们可以用同一张图片,然后把它翻转180°来实现:
righthand = CCSprite::create("finger-guessing/hand/1.png"); righthand->setAnchorPoint(ccp(0.5,0.5)); righthand->setPosition(ccp(350,284)); this->addChild(righthand); righthand->setScaleX(-1);
注意上面的方法,多了一句setScaleX,这个是设置水平方向的缩放比例的,-1表示水平翻转,这样,我们就实现了右手的效果,当然,对应的还有 setScaleY。表示设置垂直缩放比例
现在,我们已经创建了左右手,并把它们添加到舞台中了,下面就是怎么旋转了。
旋转非常简单,我们可以用CCSprite的一个现成方法:setRotation来实现,它可以设置一个精灵的旋转角度,为了实现上下连续旋转,我们来写一个函数:
void HelloWorld::rotationHand(float dt){ times++;//首先来记个次数,执行前为0 if(rotation == 30){//判断是不是向下旋转到了30°,正数表示顺时针旋转 flag = true; } if(rotation == -30){//同理,判断是不是向上旋转了30°,负数表示逆时针旋转 flag=false; } if(flag){ rotation -= 5;//每次旋转5°如果flag是true,表示目前在顺时针30°的位置,所以需要逆时针旋转回来 }else{ rotation += 5;//同理,如果flag是false,表示目前在逆时针30°位置,需要顺时针旋转回来,这两个地方需要好好理解一下 } righthand->setRotation(-rotation);//旋转右手,这里为什么是个相反的呢?大家还记得不,我们之前用setScaleX把右手给翻转了,所以,这里需要一个反向操作,保持左右手同时同向旋转 lefthand->setRotation(rotation);//旋转左手 if(times>=80){//这里是判断,达到一定次数以后,停止旋转,清除计时器 righthand->setRotation(0); lefthand->setRotation(0); times =0; CCNode::unschedule(schedule_selector(HelloWorld::rotationHand));//清除计时器 } }
上面,我们写了一个方法来同时旋转两个手,并且在旋转一定次数后停止,我们把上面的方法加入到一个计时器中:
CCNode::schedule(schedule_selector(HelloWorld::rotationHand),0.01f);
我们是用CCNode的一个方法 schedule来实现类似其他语言中Timer的作用,最后一个参数表示间隔的时间,这样,我们就把旋转函数加入到了定时器可以自动执行,我们来看下这个函数的原型:
//更新定时器,每帧调用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);
注意我们的方法需要用schedule_selector来进行转换
通过这节,我们就知道了2个重要的方法,旋转一个精灵和是用计时器
- 评论(0)
发表评论 TrackBack
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。