CocosCreator橫版格鬥遊戲Demo(二):環遊地圖

首先給主角做了三個基本動畫,站立動畫、行走動畫、攻擊動畫。

如上圖所示,給Player加上動畫組件,並把創建的3個動畫文件分別拖拽到動畫組件中。給Player添加腳本組件,並把PlayerControl.ts腳本拖拽到腳本組件中。

在PlayerControl.ts腳本中添加上圖所示代碼。

效果如下圖:

接下來就是監聽鍵盤上下左右是個方向鍵讓主角在地圖中行走,並且監聽X鍵讓玩家攻擊"空氣"。直接上源碼:

PlaySceneControl.ts

const {ccclass, property} = cc._decorator;

import PlayerControl from "./PlayerControl"
import {PlayerDirection} from "./PlayerControl"

@ccclass
export default class PlaySceneControl extends cc.Component {

    private m_player: PlayerControl = null;

    onLoad()
    {
        //監聽鍵盤事件
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
        //獲取腳本實例
        this.m_player = this.node.getChildByName("Player").getComponent("PlayerControl");
    }

    start () {
        // init logic
    }
    //按下
    private onKeyDown(event: cc.Event.EventKeyboard): void
    {
        this.dealKeyBoardEvent(event, true);
    }
    //釋放
    private onKeyUp(event: cc.Event.EventKeyboard): void
    {
        this.dealKeyBoardEvent(event, false);
    }
    //鍵盤事件處理函數
    private dealKeyBoardEvent(event: cc.Event.EventKeyboard, isPress: boolean): void
    {
        if(event.keyCode == cc.macro.KEY.up)
        {
            this.m_player.setPlayerMoveDirectionByKeyBoard(PlayerDirection.E_Dir_Up, isPress);
        }
        else if(event.keyCode == cc.macro.KEY.down)
        {
            this.m_player.setPlayerMoveDirectionByKeyBoard(PlayerDirection.E_Dir_Down, isPress);
        }
        else if(event.keyCode == cc.macro.KEY.left)
        {
            this.m_player.setPlayerMoveDirectionByKeyBoard(PlayerDirection.E_Dir_Left, isPress);
        }
        else if(event.keyCode == cc.macro.KEY.right)
        {
            this.m_player.setPlayerMoveDirectionByKeyBoard(PlayerDirection.E_Dir_Right, isPress);
        }
        else if(event.keyCode == cc.macro.KEY.x)
        {
            this.m_player.setPlayerAttackByKeyBoard(isPress);
        }
    }
}

PlayerControl.ts

const {ccclass, property} = cc._decorator;

enum PlayerState
{
    E_State_Idle = 0,
    E_State_Walk,
    E_State_Attack,
}

export enum PlayerDirection
{
    E_Dir_Up = 0,
    E_Dir_Down,
    E_Dir_Left,
    E_Dir_Right
}


@ccclass
export default class PlayerControl extends cc.Component {

    private m_animation: cc.Animation = null;
    private m_camera: cc.Node = null;

    private m_state: PlayerState = PlayerState.E_State_Idle;
    //方向鍵是否被按下
    private m_dirUpIsPress: boolean = false;
    private m_dirDownIsPress: boolean = false;
    private m_dirLeftIsPress: boolean = false;
    private m_dirRightIsPress: boolean = false;
    //攻擊鍵是否被按下(X鍵)
    private m_attackKeyIsPress: boolean = false;
    //速度
    private m_speed: number = 5;
    //主角所能行走的範圍
    private m_minX: number = null;
    private m_maxX: number = null;
    private m_minY: number = null;
    private m_maxY: number = null;

    onLoad () 
    {
        //初始化數據
        this.m_animation = this.getComponent(cc.Animation);
        this.m_camera = cc.find("Canvas/Main Camera");
        let map: cc.Node = cc.find("Canvas/TiledMap");
        //計算範圍
        let designSize = cc.view.getDesignResolutionSize();
        this.m_minX = -designSize.width/2;
        this.m_maxX = map.width*2 + this.m_minX;
        this.m_minY = -designSize.height/2 + this.node.height;
        this.m_maxY = map.getComponent(cc.TiledMap).getTileSize().height*2*3 + this.m_minY;
    }

    start () 
    {
        //設置初始狀態
        this.setPlayerState(PlayerState.E_State_Idle);
    }

    update (dt: number) 
    {
        if(this.m_state == PlayerState.E_State_Walk)
        {
            if(this.m_dirLeftIsPress) this.node.x -= this.m_speed;
            if(this.m_dirRightIsPress) this.node.x += this.m_speed;
            if(this.m_dirUpIsPress) this.node.y += this.m_speed/2;
            if(this.m_dirDownIsPress) this.node.y -= this.m_speed/2;

            //範圍檢測
            if(this.node.x < this.m_minX)this.node.x = this.m_minX;
            if(this.node.x > this.m_maxX)this.node.x = this.m_maxX;
            if(this.node.y < this.m_minY)this.node.y = this.m_minY;
            if(this.node.y > this.m_maxY)this.node.y = this.m_maxY;

            //攝像機跟着人物移動
            if(this.node.x > 0 && this.node.x < this.m_maxX - cc.view.getDesignResolutionSize().width/2)
            {
                this.m_camera.x = this.node.x;
            }
        }
    }

    //設置人物狀態
    public setPlayerState(state: PlayerState): void
    {
        this.m_state = state;
        if(this.m_state == PlayerState.E_State_Idle)
        {
            this.m_animation.play("PlayerIdleAnim");
        }
        else if(this.m_state == PlayerState.E_State_Walk)
        {
            this.m_animation.play("PlayerWalkAnim");
        }
        else if(this.m_state == PlayerState.E_State_Attack)
        {
            this.m_animation.play("PlayerAttackAnim");
        }
    }
    //獲取人物狀態
    public getPlayerState(): PlayerState
    {
        return this.m_state;
    }

    //按下方向鍵的處理
    public setPlayerMoveDirectionByKeyBoard(direction: PlayerDirection, isPress: boolean): void
    {
        if(direction == PlayerDirection.E_Dir_Up)
        {
            this.m_dirUpIsPress = isPress;
        }else if(direction == PlayerDirection.E_Dir_Down){
            this.m_dirDownIsPress = isPress;
        }else if(direction == PlayerDirection.E_Dir_Left){
            this.m_dirLeftIsPress = isPress;
            if(this.m_dirLeftIsPress)this.node.scaleX = -Math.abs(this.node.scaleX);
        }else if(direction == PlayerDirection.E_Dir_Right){
            this.m_dirRightIsPress = isPress;
            if(this.m_dirRightIsPress)this.node.scaleX = Math.abs(this.node.scaleX);
        }

        //修改人物狀態
        if(isPress)
        {
            if(this.m_state == PlayerState.E_State_Idle)
            {
                this.setPlayerState(PlayerState.E_State_Walk)
            }
        }else{
            if(this.m_state != PlayerState.E_State_Attack)
            {
                if((!this.m_dirUpIsPress) && (!this.m_dirDownIsPress) 
                && (!this.m_dirLeftIsPress) && (!this.m_dirRightIsPress))
                {
                    this.setPlayerState(PlayerState.E_State_Idle);
                }
            }
        }

    }

    //按下攻擊鍵的處理
    public setPlayerAttackByKeyBoard(isPress: boolean): void
    {
        this.m_attackKeyIsPress = isPress;
        if(isPress)
        {
            if(this.m_state != PlayerState.E_State_Attack)
            {
                this.setPlayerState(PlayerState.E_State_Attack);
            }
        }
    }

    //攻擊動畫回調
    private attackAnimCallBack(eventName: string): void
    {
        if(eventName == "checkCrash")
        {
            //檢測是否打到敵人
            cc.log("checkCrash");
        }else if(eventName == "animEnd"){
            //動畫結束
            if(this.m_attackKeyIsPress) 
            {
                //如果攻擊鍵還處於被按下的狀態,繼續播放攻擊動畫
                this.m_animation.play("PlayerAttackAnim");
            }else{
                //如果方向鍵有被按下,進入到行走狀態,否則進入站立狀態
                if(this.m_dirUpIsPress || this.m_dirDownIsPress 
                    || this.m_dirLeftIsPress || this.m_dirRightIsPress)
                {
                    this.setPlayerState(PlayerState.E_State_Walk)
                }else{
                    this.setPlayerState(PlayerState.E_State_Idle)
                }
            }
        }
    }

}

代碼有點多,註釋我都寫好了,理解起來應該不難。

下面看下效果圖:

 

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