cocos creator实例--CocosCreator实现左右跳游戏

  • 时间:
  • 来源:互联网

 

1玩法说明

    

游戏开始后,点击屏幕左右两侧,机器人朝左上方或右上方跳一步,如果下一步有石块,成功得1分,否则游戏结束。

 

2模块介绍

    

游戏场景分为2个:主页场景(home)、游戏场景(game)。

主页场景(home)作为游戏入口,没有其他功能,单纯提供游戏入口。

游戏场景(game)实现游戏玩法以及游戏逻辑控制,界面如下:

游戏的主体功能,都在游戏场景内,游戏场景的主要功能结构如下图:

 

3开发说明

这里主要介绍游戏场景的逻辑,按照上面功能结构进行介绍,先看一下游戏场景内的所有课件UI组件:

下面分模块介绍:

1石块逻辑(Box)

 

脚本挂载在石块预制上,实现石块相关逻辑,主要有2个:

1. 石块往下运动

根据机器人当前屏幕位置,机器人跳动后,无论成功还是失败,让石块往下方运动,运动到屏幕外,对应代码如下:

down(y: number){    this.node.runAction(cc.sequence(        cc.moveBy(0.4, 0, y),        cc.callFunc( () => {            NodeMgr.putBox(this.node);        })    ));}

 

2. 记录数据

private mPrevBox: cc.Node = null; // 上一个石块private mNextBox: cc.Node = null; // 下一个石块private mOffset: number = 0; // 左右偏移量 [-4,4]

上下石块主要是为了提供给机器人使用,让机器知道下一个跳过去的位置在哪里,而偏移量则记录石块在屏幕水平方向上的位置,从左到右,取值[-4,4]整数。

 

2节点管理逻辑(NodeMgr)

 

游戏中的石块,最多的时候,只铺满3个屏幕高度,超出了以后,幕布会移动到最下,石块重绘,如此循环,以达到一直玩下去的目的,所以石块是反复的移除和添加的,使用节电池,能让游戏有更好的表现。

1. 获取石块节点

判断节电池中是否已经有,有就去现成的,没有则返回空,让游戏逻辑自己生成一个新的节点,代码如下:

​​​​​​​

public static putBox(box: cc.Node){    if(this.mBoxNodePool == null){        this.mBoxNodePool = new cc.NodePool('boxs');    }
    if(box != null){        this.mBoxNodePool.put(box);    } }

 

2. 回收石块节点

移除节点时,直接把节点放入节点池,提供下次需要时使用,代码如下:

​​​​​​​

public static getBox(){    if(this.mBoxNodePool != null && this.mBoxNodePool.size() > 0){        let box = this.mBoxNodePool.get();        box.stopAllActions();        return box;    }else{        return null;    }}

 

 

3游戏逻辑(Game)

Game脚本组件挂载在游戏场景的根节点上,石块管理脚本组件也一样,如下图:

 

主要功能有3个:

1. 点击事件逻辑

根据点击位置的x坐标判断,在屏幕左边往左跳,在屏幕右边往右跳。能不能跳之前,需要判断机器人现在是否正在跳,需要注意,代码如下:​​​​​​​

onTouchCallback(event: any){    if(!this.mIsPlaying){        return;    }
    if(this.nodeRobot.getComponent('Robot').isJumping()){        return;    }
    this.bgDown();
    this.mIsPlaying = true;    let location = event.getLocation();    if(location.x < cc.winSize.width / 2){        this.robotJumpLeft();    }else{        this.robotJumpRight();    }       }

 

2.游戏背景运动控制

游戏开始时,计算背景运动的最大y坐标,运动前,判定跳以后是否超过最大坐标,移动到第一屏位置,类似石块摆放逻辑,主要代码如下:​​​​​​​

bgDown(){    let maxY = -cc.winSize.height / 2 - 2 * cc.winSize.height;    let interval = this.node.getComponent('BoxMgr').getIntervalY();        // 超出了,刷屏    if(this.nodeBg.y - interval <= maxY){        this.nodeBg.y += 2 * cc.winSize.height;        this.reloadBoxs();    }
    // 下移    this.nodeBg.runAction(cc.sequence(        cc.moveBy(0.2, 0, -interval),        cc.callFunc( () => {                    })    ));}

 

3.控制石块重绘

结合游戏背景控制逻辑,判断所有石块是否需要重绘制。

 

4石块管理逻辑(BoxMgr)

 

挂载在游戏场景根节点,主要完成以下3项功能:

1. 生成新的石块

对应代码中的 reloadNew函数,代码太多,就不贴代码了,需要的话,下载工程代码看。

2. 加载所有石块

先判断有没有上一屏保留的,有的话,先绘制上一屏,再绘制新的,新的在第三屏能显示的,需要保留,用来下次切屏的时候绘制。

3. 清理石块

清理所有石块,保留在NodeMgr中,代码如下:​​​​​​​

clearAll(){    if(this.mMemBoxs != null){        for(let i = 0; i < this.mMemBoxs.length; i++){            this.putBox(this.mMemBoxs[i]);        }        this.mMemBoxs = [];    }
    if(this.mNewBoxs != null){        for(let i = 0; i < this.mNewBoxs.length; i++){            this.putBox(this.mNewBoxs[i]);        }        this.mNewBoxs = [];    }}

 

5机器人逻辑(Robot)

 

主要功能

根据下一跳方向,判断机器人能否跳过去,对应代码中的jump函数。

 

 

 

//------------Box.ts--------------------

import NodeMgr from "./NodeMgr";

/*
 * @Copyright: Copyright (c) 2019
 * @Author: 
 * @Version: 1.0
 * @Date: 2019-11-22 19:05:49
 */
// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class Box extends cc.Component {
    @property(cc.Label)
    txtNum: cc.Label = null;

    private mPrevBox: cc.Node = null;
    private mNextBox: cc.Node = null;
    private mOffset: number = 0; // [-4,4]

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    start () {

    }

    // update (dt) {}

    setOffset(offset: number){
        this.mOffset = offset;
    }

    getOffset(){
        return this.mOffset;
    }

    setPrev(prev: cc.Node){
        this.mPrevBox = prev;
    }

    getPrev(){
        return this.mPrevBox;
    }

    setNext(next: cc.Node){
        this.mNextBox = next;
    }

    getNext(){
        return this.mNextBox;
    }

    setNum(num: number){
        this.txtNum.string = `${num}`;
    }

    down(y: number){
        this.node.runAction(cc.sequence(
            cc.moveBy(0.4, 0, y),
            cc.callFunc( () => {
                NodeMgr.putBox(this.node);
            })
        ));
    }
}




//-------------BoxMgr.ts-------------------

import NodeMgr from "./NodeMgr";

/*
 * @Copyright: Copyright (c) 2019
 * @Author: 
 * @Version: 1.0
 * @Date: 
 */
// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class BoxMgr extends cc.Component {
    // 障碍物父节点
    @property(cc.Node)
    nodeParent: cc.Node = null;

    // 障碍物预制
    @property(cc.Prefab)
    prefabBox: cc.Prefab = null;

    private mMaxY: number = 0; // 最大Y坐标
    private mMemMinY: number = 0; // 需要保留的最小Y值
    private mStartY: number = 200; // 起始位置
    private mNewBoxs: cc.Node[] = []; // 所有的障碍物
    private mMemBoxs: cc.Node[] = []; // 需要保存的障碍物
    private mMaxOffset: number = 3; // 最大偏移量
    private mCurrOffset: number = 0; // 当前偏移量
    private mMaxZIndex:number = 10000; // 最大层级
    private mCurrZIndex: number = 0; // 当前层级
    private mIntervalX: number = 0; // X间距
    private mIntervalY: number = 0; // Y间距
    private mStandBox: cc.Node = null; // 障碍物链头
    private mIsNew: boolean = true;
    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.mMaxY = 3 * cc.winSize.height + this.prefabBox.data.height / 2;
        this.mMemMinY = 2* cc.winSize.height - this.prefabBox.data.height / 2;
        this.mIntervalX = this.prefabBox.data.width * 0.5;
        this.mIntervalY = this.prefabBox.data.height * 0.5;
    }

    start () {
        // this.reloadAll();
    }

    /**
     * @description: 生成一个障碍物
     * @param {type} 
     * @return: 
     */
    getBox(){
        let box = NodeMgr.getBox();
        if(box == null){
            box = cc.instantiate(this.prefabBox);
        }
        return box;
    }

    /**
     * @description: 回收一个障碍物
     * @param {type} 
     * @return: 
     */
    putBox(box: cc.Node){
        if(box != null){
            NodeMgr.putBox(box);
        }        
    }

    clearAll(){
        if(this.mMemBoxs != null){
            for(let i = 0; i < this.mMemBoxs.length; i++){
                this.putBox(this.mMemBoxs[i]);
            }
            this.mMemBoxs = [];
        }

        if(this.mNewBoxs != null){
            for(let i = 0; i < this.mNewBoxs.length; i++){
                this.putBox(this.mNewBoxs[i]);
            }
            this.mNewBoxs = [];
        }
    }

    /**
     * @description: 重新加载所有障碍物
     * @param {type} 
     * @return: 
     */
    reloadAll(){
        for(let i = 0; i < this.mNewBoxs.length; i++){
            this.putBox(this.mNewBoxs[i]);
        }
        this.mNewBoxs = [];

        this.mCurrZIndex = this.mMaxZIndex;
        if(this.mMemBoxs.length <= 0){
            this.mIsNew = true;
            this.mCurrOffset = 0;
            this.reloadNew(this.mStartY);
        }else{
            this.mIsNew = false;
            let i = 0;
            while(i < this.mMemBoxs.length){                
                this.mMemBoxs[i].y -= (2 * cc.winSize.height);
                this.mMemBoxs[i].zIndex = this.mCurrZIndex;
                this.mMemBoxs[i].getComponent('Box').setNum(this.mCurrZIndex);
                this.mCurrZIndex--;
                this.mNewBoxs.push(this.mMemBoxs[i]);
                i++;
            }

            let last = this.mMemBoxs[this.mMemBoxs.length - 1];
            this.mMemBoxs = [];

            this.mCurrOffset = last.getComponent('Box').getOffset();
            cc.log('CurrOffset', this.mCurrOffset);

            this.reloadNew(last.y);
        }
    }

    /**
     * @description: 重新加载新的障碍物(不包含换屏的)
     * @param {type} 
     * @return: 
     */
    reloadNew(startY: number){
        let y = startY + this.mIntervalY;
        while(y < this.mMaxY){            
            let box = this.getBox();
            
            // 障碍物链
            if(this.mStandBox == null){
                this.mStandBox = box;
            }

            let random = this.getRandom();
            // 第一个居中
            if(!this.mIsNew){
                // 最右
                if(this.mCurrOffset + random > this.mMaxOffset){
                    this.mCurrOffset -= random;
                }
                // 最左
                else if(this.mCurrOffset + random < -this.mMaxOffset){
                    this.mCurrOffset -= random;
                }
                // 合法
                else{
                    this.mCurrOffset += random;
                }
            }                
            
            this.mIsNew = false;
            let js = box.getComponent('Box');            
            box.x = this.mCurrOffset * this.mIntervalX;
            box.y = y;
            box.zIndex = this.mCurrZIndex;
            js.setNum(this.mCurrZIndex);
            this.mCurrZIndex--;
            box.parent = this.nodeParent;            

            // 切屏保留           
            if(y >= this.mMemMinY){
                if(this.mMemBoxs.length > 0){
                    this.mMemBoxs[this.mMemBoxs.length - 1].getComponent('Box').setNext(box);                
                    js.setPrev(this.mMemBoxs[this.mMemBoxs.length - 1]);
                }else{
                    this.mNewBoxs[this.mNewBoxs.length - 1].getComponent('Box').setNext(box);                
                    js.setPrev(this.mNewBoxs[this.mNewBoxs.length - 1]);
                }
                this.mMemBoxs.push(box);
            }else{
                if(this.mNewBoxs.length > 0){
                    this.mNewBoxs[this.mNewBoxs.length - 1].getComponent('Box').setNext(box);                
                    js.setPrev(this.mNewBoxs[this.mNewBoxs.length - 1]);
                }else{
                    js.setPrev(null);
                }
                this.mNewBoxs.push(box);
            }

            y += this.mIntervalY;
        }
    }

    /**
     * @description: 获取随机数
     * @param {type} 
     * @return: 
     */
    getRandom(){
        let ran = Math.random(); //[0,1)
        return (ran < 0.5)? -1: 1;
    }

    getIntervalX(){
        return this.mIntervalX;
    }

    getIntervalY(){
        return this.mIntervalY;
    }

    getStandBox(){
        return this.mStandBox;
    }

    // update (dt) {}
}







//-----------Game.ts---------------------


// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class Game extends cc.Component {

    @property(cc.Node)
    nodeBg: cc.Node = null;

    @property(cc.Node)
    nodeRobot: cc.Node = null;

    @property(cc.Node)
    nodeEnd: cc.Node = null;

    @property(cc.Label)
    txtPoints: cc.Label = null;

    // 是否正在移动
    private mIsPlaying: boolean = false;
    private mPoints: number = 0;

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        this.node.on(cc.Node.EventType.TOUCH_START, (event: any) => {
            event.stopPropagation();
            this.onTouchCallback(event);
        });

        this.mPoints = 0;
    }

    start () {
        this.reloadBoxs();

        let robot = this.nodeRobot.getComponent('Robot');
        robot.setAddCallback( () => {
            this.onAddPoints();
        });
        robot.setFailedCallback( () => {
            this.onGameEnd();
        });

        this.mIsPlaying = true;
    }

    onAddPoints(){
        this.mPoints++;
    }

    onGameEnd(){
        this.mIsPlaying = false;

        this.txtPoints.string = `得分:${this.mPoints}`;
        this.nodeEnd.active = true;
    }

    reloadBoxs(){
        let boxMgr = this.getComponent('BoxMgr');
        boxMgr.reloadAll();

        let robot = this.nodeRobot.getComponent('Robot');
        if(robot.getCurrent() == null){
            let standBox = boxMgr.getStandBox();
            let nextBox = standBox.getComponent('Box').getNext();

            robot.setCurrent(standBox);
            robot.setNext(nextBox);

            if(nextBox.x > standBox.x){
                robot.turnRight();
            }else{
                robot.turnLeft();
            }
        }else{
            robot.setCurrent(robot.getCurrent());
        }
    }

    robotJumpLeft(){
        let js = this.nodeRobot.getComponent('Robot');
        js.turnLeft();
        js.jump();
    }

    robotJumpRight(){
        let js = this.nodeRobot.getComponent('Robot');
        js.turnRight();
        js.jump();
    }

    // update (dt) {}

    /**
     * @description: 背景下移
     * @param {type} 
     * @return: 
     */
    bgDown(){
        let maxY = -cc.winSize.height / 2 - 2 * cc.winSize.height;
        let interval = this.node.getComponent('BoxMgr').getIntervalY();
        
        // 超出了,刷屏
        if(this.nodeBg.y - interval <= maxY){
            this.nodeBg.y += 2 * cc.winSize.height;
            this.reloadBoxs();
        }

        // 下移
        this.nodeBg.runAction(cc.sequence(
            cc.moveBy(0.2, 0, -interval),
            cc.callFunc( () => {
                
            })
        ));
    }

    /**
     * @description: 点击屏幕
     * @param {type} 
     * @return: 
     */
    onTouchCallback(event: any){
        if(!this.mIsPlaying){
            return;
        }

        if(this.nodeRobot.getComponent('Robot').isJumping()){
            return;
        }

        this.bgDown();

        this.mIsPlaying = true;
        let location = event.getLocation();
        if(location.x < cc.winSize.width / 2){
            this.robotJumpLeft();
        }else{
            this.robotJumpRight();
        }       
    }

    onClick(){
        this.nodeEnd.active = false;
        cc.director.loadScene('game');
    }
}





//------------Home.ts--------------------


// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    @property(cc.Label)
    label: cc.Label = null;

    @property
    text: string = 'hello';

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    start () {

    }

    // update (dt) {}

    onClick(event, data){
        switch(data){
            case 'start':{
                cc.director.loadScene('game');
                break;
            }
        }
    }
}






//-------------NodeMgr.ts-------------------

// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

@ccclass
export default class NodeMgr {
    private static mBoxNodePool: cc.NodePool = null;

    public static putBox(box: cc.Node){
        if(this.mBoxNodePool == null){
            this.mBoxNodePool = new cc.NodePool('boxs');
        }

        if(box != null){
            this.mBoxNodePool.put(box);
        } 
    }

    public static getBox(){
        if(this.mBoxNodePool != null && this.mBoxNodePool.size() > 0){
            let box = this.mBoxNodePool.get();
            box.stopAllActions();
            return box;
        }else{
            return null;
        }
    }
}







//--------------Robot.ts------------------

// Learn TypeScript:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/typescript.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
//  - [English] http://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html

const {ccclass, property} = cc._decorator;

enum RobotFace{
    Left,
    Right
}

@ccclass
export default class Robot extends cc.Component {
    @property(cc.SpriteFrame)
    spfLeft: cc.SpriteFrame = null;

    @property(cc.SpriteFrame)
    spfRight: cc.SpriteFrame = null;

    @property(cc.Label)
    txtPoints: cc.Label = null;

    private mPrevNode: cc.Node = null; // 上一次站着的节点
    private mCurrNode: cc.Node = null; // 当前站着的节点
    private mNextNode: cc.Node = null; // 下一个节点
    private mOffset: cc.Vec2 = cc.v2(11, 120); // 机器人与障碍物中心间隔
    private mRobotFace:number = -1; // -1朝左,1朝右
    private mAddCallback: any = null;
    private mFailedCallback: any = null;
    private mJumping: boolean = false;
    private mPoints: number = 0;

    // LIFE-CYCLE CALLBACKS:

    // onLoad () {}

    start () {
        this.node.zIndex = 20000;
        this.txtPoints.string = `${this.mPoints}`;
    }

    // update (dt) {}
    /**
     * @description: 向左转
     * @param {type} 
     * @return: 
     */
    turnLeft(){
        this.mRobotFace = RobotFace.Left;
        this.node.getComponent(cc.Sprite).spriteFrame = this.spfLeft;
    }

    /**
     * @description: 向右转
     * @param {type} 
     * @return: 
     */
    turnRight(){
        this.mRobotFace = RobotFace.Right;
        this.node.getComponent(cc.Sprite).spriteFrame = this.spfRight;
    }

    /**
     * @description: 设置下一个节点
     * @param {type} 
     * @return: 
     */
    setNext(node: cc.Node){
        this.mNextNode = node;
    }

    /**
     * @description: 设置当前节点
     * @param {type} 
     * @return: 
     */
    setCurrent(node: cc.Node){
        this.mCurrNode = node;
        this.node.position = this.mCurrNode.position.add(this.mOffset);
    }

    getCurrent(){
        return this.mCurrNode;
    }

    setAddCallback(callback: any){
        this.mAddCallback = callback;
    }

    setFailedCallback(callback: any){
        this.mFailedCallback = callback;
    }

    /**
     * @description: 跳
     * @param {type} 
     * @return: 
     */
    jump(){
        if(this.mNextNode == null){
            return;
        }
        this.mJumping = true;

        let curPos = this.node.position;       
        let nextPos = this.mNextNode.position;
        nextPos = nextPos.add(this.mOffset);

        // 能跳上去
        if((this.mRobotFace == RobotFace.Left && nextPos.x < curPos.x) || 
            (this.mRobotFace == RobotFace.Right && nextPos.x > curPos.x)){
            this.node.runAction(cc.sequence(
                cc.jumpTo(0.2, nextPos, 30, 1),
                cc.callFunc( () => {
                    this.mPrevNode = this.mCurrNode;
                    this.mCurrNode = this.mNextNode;
                    this.mNextNode = this.mCurrNode.getComponent('Box').getNext();
                    this.mJumping = false;
                }),
                cc.callFunc( () => {
                    if(this.mPrevNode != null){
                        this.mPrevNode.getComponent('Box').down(-this.getDownY(this.mPrevNode));
                        this.mPrevNode = null;
                    }

                    if(this.mAddCallback != null){
                        this.mAddCallback();
                    }
                    this.mPoints++;
                    this.txtPoints.string = `${this.mPoints}`;
                })
            )); 
        }
        // 跳不上去
        else{
            let targetPos = curPos;
            if(nextPos.x > curPos.x){
                targetPos.x -= 130;
            }else{
                targetPos.x += 130;
            }
            targetPos.y += 65;

            this.node.runAction(cc.sequence(
                cc.jumpTo(0.2, targetPos, 30, 1),
                cc.callFunc( () => {
                    this.mJumping = false;
                    if(this.mPrevNode != null){
                        this.mPrevNode.getComponent('Box').down(-this.getDownY(this.mPrevNode));
                        this.mPrevNode = null;
                    }                   

                    this.node.runAction(cc.sequence(
                        cc.moveBy(0.5, 0, -this.getDownY(this.node)),
                        cc.callFunc( () => {
                            if(this.mFailedCallback != null){
                                this.mFailedCallback();
                            }
                        })
                    ));
                }),
            ));
        }        
    }

    getDownY(node: cc.Node){        
        let pos = node.parent.convertToWorldSpace(node.position);
        let y = pos.y + node.height;
        return y;
    }

    isJumping(){
        return this.mJumping;
    }
}







 

 

 

 

 


感谢:

本文参考自https://mp.weixin.qq.com/s/34vJUZR7XIfkZDsBATqJGQ这篇文章,这里感谢原作者对于技术的分享。

下载:

本文章源码和资源下载地址

^随风~~
发布了298 篇原创文章 · 获赞 12 · 访问量 1万+
私信 关注

本文链接http://element-ui.cn/news/show-1328.aspx