CreatorPrimer|飞机大战(二)

CreatorPrimer|飞机大战(二)

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

飞机大战-子弹发射1.gif

飞机大战-子弹发射2.gif

下面我来就介绍一下,实现上面效果是如何实现的,先看视频:

1、子弹角度计算

子弹发射器

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

image.png

不好意思,请允许我重新翻开初中的数学关于三角函数章节,通过直角三角形中,角度与边的关系可以计算出飞行终点,我们根据上图,看下我们已知的参数:
1. 子弹角度β,是我们的组件属性
2. 飞行距离r,这里为了简单我使用了常用cc.winSize.height

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

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

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

 _emmitNode() {
        //创建子弹
        let node = cc.instantiate(this.prefab);
        node.position = this.offset.add(this.node.position);
        node.parent = this.node.parent;
        node.rotation = this.rotation;

        //计算终点
        let endPoint = cc.v2();
        endPoint.x = cc.winSize.height * Math.sin(this.rotation * RADIAN);
        endPoint.y = cc.winSize.height * Math.cos(this.rotation * RADIAN);

        //计算飞行持续时间
        let distance = endPoint.sub(node.position).mag();
        let duration = distance / this.speed;

        //运行动作
        let moveBy = cc.moveBy(duration, endPoint);
        let removeSelf = cc.removeSelf();
        let sequence = cc.sequence(moveBy, removeSelf);
        node.runAction(sequence);
    }

2. 动态旋转

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

update(dt) {
     if (this.spin === 0) {
         return;
    }
    this.rotation += dt * this.spin;
}

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

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

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

3. 小结

我们看似复杂的子弹效果,其实每一个都是用的直线动作,通过挂载多个子弹发射器,调节枪口角度、角度动态旋转可以生成出各式花样。工程源码可以在公众上回复“子弹发射器”或“LineEmmiter”获取,感谢你的阅读!