之前的飞机大战(一)我们实现了地图场景的滚动和简单的直上直下的子弹的发射,在之前的基础上,对线性发射器做了简单的修改,实现了如下效果:

CreatorPrimer|飞机大战(二)_飞机大战CreatorPrimer|飞机大战(二)_调用函数_02

1、子弹角度计算 CreatorPrimer|飞机大战(二)_javascript_03

这里为子弹发射器增加了一个rotation属性用于控制子弹发射的角度,但是如何计算子弹的飞行终点坐标呢?

CreatorPrimer|飞机大战(二)_javascript_04

不好意思,请允许我重新翻开初中的数学关于三角函数章节,通过直角三角形中,角度与边的关系可以计算出飞行终点,我们根据上图,看下我们已知的参数:

  1. 子弹角度β,是我们的组件属性

  2. 飞行距离r,这里为了简单我使用了常用cc.winSize.height

因此通过三角公式可以得出:

x = r * sin(β) y = r * cos(β)

需要注意的是 JavaScript 中 Math.sin\Math.cos 函数中的参数是弧度单位,每1角度为 Math.PI / 180 弧度,下面看终点的计算代码:

  1. _emmitNode() {

  2. //创建子弹

  3. let node = cc.instantiate(this.prefab);

  4. node.position = this.offset.add(this.node.position);

  5. node.parent = this.node.parent;

  6. node.rotation = this.rotation;

  7.  

  8. //计算终点

  9. let endPoint = cc.v2();

  10. endPoint.x = cc.winSize.height * Math.sin(this.rotation * RADIAN);

  11. endPoint.y = cc.winSize.height * Math.cos(this.rotation * RADIAN);

  12.  

  13. //计算飞行持续时间

  14. let distance = endPoint.sub(node.position).mag();

  15. let duration = distance / this.speed;

  16.  

  17. //运行动作

  18. let moveBy = cc.moveBy(duration, endPoint);

  19. let removeSelf = cc.removeSelf();

  20. let sequence = cc.sequence(moveBy, removeSelf);

  21. node.runAction(sequence);

  22. }

2. 动态旋转

动态旋转很简单,在update每帧调用函数中,不断修改rotation属性值,看下面代码:

  1. update(dt) {

  2. if (this.spin === 0) {

  3. return;

  4. }

  5. this.rotation += dt * this.spin;

  6. }

spin在这里是一个旋绕速度参数,相同于电风扇上的摇头马达,通过子弹产生速度、飞行速度、旋转速度你可以创造了各种样式花丽的子弹效果,下面是我弄的几张截图:

CreatorPrimer|飞机大战(二)_javascript_05

给飞机挂了两个带spin参数的发射器,一个spin为360顺时针旋转,一个spin值为-360逆时针旋转,像对一凤凰的翅膀。

CreatorPrimer|飞机大战(二)_飞机大战_06

这个是挂了4个发射器,起始rotation分别为0、90、180、270,飞行速度快一些,spin值都是一样的,像刮起的凤凰旋风。

3. 小结

我们看似复杂的子弹效果,其实每一个都是用的直线动作,通过挂载多个子弹发射器,调节枪口角度、角度动态旋转可以生成出各式花样。

最后还是录制了一个视频,看看实现上面效果到底有多简单CreatorPrimer|飞机大战(二)_javascript_07