1. 程式人生 > >Cocos Creator 3D 打磚塊教程(二) | 子彈發射與攝像機平滑移動

Cocos Creator 3D 打磚塊教程(二) | 子彈發射與攝像機平滑移動

線上體驗連結:
http://example.creator-star.cn/block3d/

前面一篇文章,我們講了【打磚塊】遊戲中的3D物體的場景佈局、材質資源、物理剛體與碰撞元件,接下來本篇文章重點介紹“子彈的發射”與“攝像機移動”,有了這兩部分我們的【打磚塊】遊戲就可以初步玩起來了。

子彈的發射

子彈是由 3D 物體 Sphere 球體建立,並將節點改名為 bullet,看下圖:

在層級管理器中將 bullet 節點拖動到資源管理器中,將它建立成一個 Prefab 預製體。同時在 bullet 子彈節點上掛載球體碰撞元件(cc.SphereColliderComponent)和剛體元件 (cc.RigidBodyComponent),如下圖所示:

有了 bullet 預製體,我們就可以用程式碼去例項化它,並將他發射出去,建立一個 shoot 的TypeScript 指令碼並將它掛載到 Camera 攝像機節點上:

將shoot元件的子彈預製體拖動過去,子彈的移動速度設定為 50,我們通過點選螢幕來進行發射,下面是具體的程式碼:

import { _decorator, Component, Node, CCObject, Prefab, instantiate, RigidBodyComponent, Vec3 } from "cc";
const { ccclass, property } = _decorator;

@ccclass("shoot")
export class shoot extends Component {
  
    @property(Prefab)
    bullet: Prefab;

    @property(cc.Float)
    speed = 0;
 
    start () {
        //註冊全域性觸控點選事件
        cc.systemEvent.on(Node.EventType.TOUCH_END, () => {
            this.shoot();
        });
    }

    shoot() {
        //例項化 bullet 預製體
        let node = instantiate(this.bullet);
        node.parent = this.node.parent;
        node.position = this.node.position;
        //為剛體施加衝量
        let bullet:RigidBodyComponent = node.getComponent(RigidBodyComponent);
        bullet.applyImpulse(new Vec3(0, 2.29, -1 * this.speed));
    }

這裡需要注意兩點:

  1. 觸控事件是使用cc.systemEvent進行註冊的;
  2. 工程中沒有程式碼提示,需要從引擎安裝目錄中複製cc.d.ts檔案到工程中,我是在Mac系統上,可以用下面命令複製:
cp /Applications/CocosCreator3D.app/Contents/Resources/resources/3d/engine/bin/.declarations/cc.d.ts ./

預製體的例項化使用instantiate 與我們在Creator 2D中使用的API完全相同,就不在贅述。這時我們就可以執行預覽,通過點選滑鼠或觸控式螢幕幕發射子彈了。

攝像機移動

在3D遊戲中,通常的做法是使用WSAD四個鍵進行上下左右的移動,其核心是控制攝像機節點的位置。在我們這個遊戲中為了簡化遊戲操作,我們只控制攝像的 x 和 y 方向的移動:

  • w:y方向增加
  • s:y方向減小
  • a:x方向減小
  • d:x方向增加

建立一個 movement 的指令碼用於控制攝像機的移動,下面是元件的設定:

下面重點分析使用鍵盤控制攝像機移動的相關程式碼:

//使用 cc.systemEvent.on 註冊全域性鍵盤事件
start() {
    cc.systemEvent.on(Node.EventType.KEY_DOWN, this.onKeyDown, this);
    cc.systemEvent.on(Node.EventType.KEY_UP, this.onKeyUp, this);
        ... 
}

在按鈕下鍵盤事件 onKeyDown 中標記移動的方向:

onKeyDown(event) {
    cc.log(event);
    let rotation = this.node.eulerAngles;
    let position = this.node.getPosition();
    switch(event.keyCode) {
        case cc.macro.KEY.w:
            this.offset.y = 1;
            break;
        case cc.macro.KEY.s:
            this.offset.y = -1;
            break;
        case cc.macro.KEY.a:
            this.offset.x = -1;
            break;
        case cc.macro.KEY.d:
            this.offset.x = 1;
            break;
    }
}

當按鍵鬆開時,將 offset 變數歸 0:

onKeyUp() {
    this.offset.x = 0;
    this.offset.y = 0;    
    this.offset.z = 0;    
}

重點是在元件的每幀事件 update 中真正控制攝像機節點的移動:

update (deltaTime: number) { 
    //計算要移動的目標位置
    Vec3.add(this.point, this.node.position, this.offset);
        //插值計算
    Vec3.lerp(this.point, this.node.position, this.point, deltaTime * this.speed);
        //移動節點
    this.node.setPosition(this.point);
}

為了平滑移動,Shawn這裡參考了官方Demo案例中的做法,使用 Vec3.lerp 對當前座標到要移動的座標進行插值計算。

小結

Creator3D 打磚塊是 Shawn 製作的第一個 3D 遊戲,也是公眾號上第一次寫的 3D 相關的教程,目前他只能算是一個 DEMO,還有很多不足的地方,如有不正之處還請大家多多指正。

原創不易,特別是一個新的東西,如果文章對你有用,也感謝你點個在再看或分享給朋友,你的鼓勵是我創作的動力,願我們在前進的道路上砥礪前行,共同成長!

本文由部落格一文多發平臺 OpenWrite 釋出!