CreatorPrimer | 飛機大戰(二)

之前的飛機大戰一我們實現了地圖場景的滾動和簡單的直上直下的子彈的發射,在之前的基礎上,對線性發射器做了簡單的修改,實現瞭如下效果:

子彈發射.gif

子彈發射.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”獲取,感謝你的閱讀!


歡迎關注「奎特爾星球」微信公衆號,有代碼、有教程、有視頻、有故事,邀你一起共同成長!

奎特爾星球

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章