Cocos2d-x游戏开发实战精解
上QQ阅读APP看书,第一时间看更新

5.3 在Cocos2d-x中实现动作的监听

在上一节中,已经实现了使用Cocos2d-x实现动作组合的功能,相信读者也已经可以通过组合完成一些比较复杂的动作了。但是在实际使用Cocos2d-x时,还会经常需要改变动作的状态以达到某些连贯性的操作,比如英雄先向前冲刺,然后翻一个跟头,这就需要使用连续性的组合运动。那么本节将学习在Cocos2d-x中连续运行不同动作的功能,其核心代码如范例5-3所示,完整项目需查看源文件中的ChapterFive03项目进行参考。

【范例5-3】连续执行不同的动作。

01 bool HelloWorld::init()
02      {
03              if ( !Layer::init() )
04          {
05              return false;
06          }
07              //设置背景颜色为白色,并加入到场景中
08              auto* background = LayerColor::create(ccc4(255, 255, 255, 255));
09              addChild(background);
10              //将两张卡片插入到场景中去,其中一张卡片使其旋转90度达到“看不见”的目的
11              myCard1 = Sprite::create("mycard01.png");
12              myCard2 = Sprite::create("mycard02.png");
13              myCard1->setPosition(360, 180);
14              myCard1->setScale(0.5f);
15              myCard1->setAnchorPoint(Vec2(0.5f, 0.5f));
16              addChild(myCard1);
17              myCard2->setPosition(360, 180);
18              myCard2->setScale(0.5f);
19              myCard2->setAnchorPoint(Vec2(0.5f, 0.5f));
20              myCard2->setRotation3D(Vec3(0, 82.5f, 0));                   
                //实际效果为以y轴为轴心旋转90度
21              addChild(myCard2);
22              auto* rotateby = RotateBy::create(1.5f, Vec3(0, 82.5f, 0));
                //实际动作为以y轴为轴心旋转90度
23              //创建动作监听
24              auto* callFunc = CallFunc::create(CC_CALLBACK_0(HelloWorld:: 
                rotateCard, this));
25              auto* sequence = Sequence::create(rotateby, callFunc,NULL);
26              myCard1->runAction(sequence);
27          return true;
28      }
29      void HelloWorld::rotateCard()                   
        //回调函数,内容为使第二张卡片以y轴为轴心旋转90度
30      {
31              auto* rotateby = RotateBy::create(1.5f, Vec3(0, 97.5f, 0));
32              myCard2->runAction(rotateby);
33      }

运行程序之后可以看到,在初始状态下一张卡牌显示在场景中央,而当它转动到90度时,将会显示出另一面的图案,如图5-6和图5-7所示。

图5-6 卡牌正面

图5-7 卡牌背面

实现这个效果的原理很简单,只需要在场景中插入两张尺寸、位置均相同的卡牌。其中第一张作为正面,直接放置在场景中,而第二张卡牌先旋转90度,因为这是2D游戏,卡牌是没有厚度的,因此在用户的角度看来第二张卡牌是看不见的。这一部分在范例中是由第11~21行处的代码实现的。

当动作开始时,首先让第一张卡牌执行动作翻转90度,如范例第26行所示。该动作在第22行被定义,虽然执行的是旋转90度,但是经过试验发现默认情况下由于渲染的原因,其旋转的前半个圆周(视觉效果上的)实际上是使用82.5作为参数。

在第24行中创建了一个动作触发器,实际上并没有监听的功能,而是在被执行时触发其中的rotateCard方法,如范例29~33行所示。创建动作触发器之后还要将它绑定在动作上,如第25行所示。实际上这并不能认为是一种绑定,而是将两个动作加入到了一个队列中,当执行完一个动作之后再执行下一个,只不过其中的动作是调用某个方法,看起来很像是事件监听而已。

提示:Sequence类的create方法中可以包含多个参数,即可以连续执行多个动作,只要最终以NULL作为最后一个参数结尾即可。

在本章最后所介绍的RPG回合制游戏的战斗场景中,也将会使用该方法来演示如何保证战斗的不断进行。