cocos_creator之Flabby Bird

游戏主要逻辑

1,地板滚动

 两块地板循环滚动,没啥好说的。
核心代码:
this.groundNode[0].x += Constant.GROUND_VX;
        this.groundNode[1].x += Constant.GROUND_VX;
        if (this.groundNode[0].x + this._width/2 < - this._size.width/2) {
            this.groundNode[0].x = this.groundNode[1].x + this._width - 5;
        }
        if (this.groundNode[1].x + this._width/2 < - this._size.width/2) {
            this.groundNode[1].x = this.groundNode[0].x + this._width - 5;
        }

2,小鸟坠落与弹跳

坠落的效果需要让小鸟在Y轴负方向有一个加速度,即单位时间类的偏移量还有一个增量。弹跳只需要让原本为负的偏移值变为正。
在onLoad方法中:
this.velocity = 0; //初始下降速度为零
在onDrop方法中:
this.node.y  += this.velocity ;
this.velocity -= this.gravity;

3,管道生成逻辑

管道的定位需要五个参数
pipeMaxOffsetY   //Y轴最大偏移量
pipeMinGap        //管道最小间隙
pipeMaxGap       //管道最大间隙
pipeSpawnInterval      //管道生成时间间隔
pipeSpawnOffsetX      //管道屏幕外生成偏移量
核心代码:
spawnPipes: function() {
        // 从管道预制(上端),生成管道实例
        var pipeUp = cc.instantiate(this.pipePrefabs[Constant.PIPE_UP]);
        // 定义为上端类型
        pipeUp.getComponent('Pipe').init(Constant.PIPE_UP);
        // 获取管道的高度(上端与上端的相同)
        var pipeHeight = pipeUp.getComponent('cc.Sprite').spriteFrame.getRect().height;
        // 设置上端管道的横向起始位置(屏幕右端另加一定偏移)
        pipeUp.x = this.size.width / 2 + this.pipeSpawnOffsetX;
        // 设置上端管道的纵向起始位置(随机取偏移量)
        pipeUp.y = Math.floor(Math.random() * this.pipeMaxOffsetY) + pipeHeight/2;
        // 下端生成逻辑基本与上端相同
        var pipeDown = cc.instantiate(this.pipePrefabs[Constant.PIPE_DOWN]);
        pipeDown.getComponent('Pipe').init(Constant.PIPE_DOWN);
        pipeDown.x = this.size.width / 2 + this.pipeSpawnOffsetX;
        // 随机生成上端与下端管道之间的间隙值(pipeMinGap与pipeMaxGap之间)
        var pipeGap = Math.floor(Math.random() * (this.pipeMaxGap - this.pipeMinGap)) + this.pipeMinGap + 20;
        pipeDown.y = pipeUp.y - pipeGap - pipeHeight;
        // 添加管道到pipes节点上
        this.pipesNode.addChild(pipeUp);
        this.pipesNode.addChild(pipeDown);
        // 添加管道到管道数组中
        this.pipes.push(pipeUp);
        this.pipes.push(pipeDown);
    },
// 超出屏幕范围的管道,从数组中移除,并从节点上删除
            if ( curPipeNode.x < -(this.size.width/2 + Constant.PIPE_SPAWN_OFFSET_X)) {
                this.pipes.splice(i, 1);
                this.pipesNode.removeChild(curPipeNode, true);
            } 

4,死亡逻辑

 撞地死亡:小鸟包围盒下边界Y坐标与地板上表面Y坐标对比
 撞天花板死亡:小鸟包围盒上边界Y坐标与屏幕上边界Y坐标对比
 撞管道死亡:小鸟包围盒与管道包围盒坐标碰撞检
核心代码:
 // 获取小鸟的包围盒
            var birdBox = this.bird.node.getBoundingBox();
            // 获取当前管道的包围盒
            var pipeBox = curPipeNode.getBoundingBox();
            var birdRect = new cc.Rect(birdBox.x, birdBox.y,
                birdBox.width, birdBox.height);
            var pipeRect = new cc.Rect(pipeBox.x, pipeBox.y,
                pipeBox.width, pipeBox.height);
            // 根据两个矩形范围判断是否相交
            if (pipeRect.intersects(birdRect)) {
                this.onGameOver();
                return;
            }
// 小鸟触地,则死亡
        if (this.bird.node.y < this.groundTop || (this.bird.node.y > (this.size.height/2 + this.bird.node.height/2))) {
            this.onGameOver();
        }

5,计分逻辑

  通过管道加分:通关管道判断为小鸟X坐标是否超过管道的X坐标。加分的辅助判断条件,小鸟的通过状态是否及时改变,否则通过以后会不停加分。小鸟通过的管道时只能以上或下其中一根管道的坐标作为参考标准,否则每通过一组管道会加两分。
  最高纪录分:游戏开始前显示,如果此前纪录为0则不显示。游戏结束时检查是否有新纪录产生,有则修改,无则保持。
核心代码:
// 获取当前管道对象
            var curPipe = curPipeNode.getComponent('Pipe');
            // 判断小鸟是否顺利通过管道,是则加分
            if ( curPipeNode.x < this.bird.node.x && curPipe.isPassed === false 
                && curPipe.type === Constant.PIPE_UP) {
                curPipe.isPassed = true;
                this.addScore();
            }
var Storage = {
    getHighScore: function() {
        var score = cc.sys.localStorage.getItem('HighScore') || 0;
        return parseInt(score);
    },

    setHighScore: function(score) {
        cc.sys.localStorage.setItem('HighScore', score);
    }
};

module.exports = Storage;

涉及到cocos2D_JS知识点:

属性成员定义时的类型说明

    groundImag: cc.Sprite,  //精灵节点类型
    groundNode: [cc.Node],  //节点数组类型
    AnimName: ' ',   // 字符串类型
    gravity: 0.5  //数值类型
    pipesPrefabs: [cc.Prefab],  //预制件类型
    gameOverText: cc.Label,   //文本类型
    jumpAudio:{
        default: null,
        url: cc.AudioClip      //音频文件
    }

关闭节点显示

// 关闭菜单节点显示
        this.gameMenu.active = false;

播放动画

// 获取本身的cc.Animation对象,并播放AnimName动画
this.getComponent(cc.Animation).play(this.AnimName);

播放音效,单次

// 播放弹跳音效
cc.audioEngine.playEffect(this.jumpAudio, false);

添加计时器

this.schedule(this.函数名, 时间间隔)   //标准格式
this.schedule(this.spawnPipes, this.pipeSpawnInterval);  //示例

获取屏幕尺寸

// 获取屏幕尺寸
this._size = cc.winSize;     

获取精灵节点尺寸

// 获取地板图片的宽度
this._width = this.groundImg.spriteFrame.getRect().width;

往节点添加组件,往数组添加元素

var pipeUp = cc.instantiate(this.pipePrefabs[Constant.PIPE_UP]);
this.pipesNode.addChild(pipeUp);

往数组添加和删除元素

this.pipes.push(pipeUp);
this.pipes.splice(i, 1);
this.pipesNode.removeChild(curPipeNode, true);

引用和创建对象,并使用对象

const Bird = require('Bird');   //写在当前类的最上面
 // 小鸟对象
 bird: Bird,      //写在propertity中
 this.bird.OnDrop();    // 引用类的成员函数调用

本地数据配置

//方便参数集中管理
var Constant = cc.Enum({
    // 地板移动时间间隔
    GROUND_MOVE_INTERVAL: 0.05,
    // 单位时间地板移动速度
    GROUND_VX: -5,
    // 上端管道序号为0
    PIPE_UP: 0,
    // 下端管道序号为1
    PIPE_DOWN: 1,
    // 游戏失败文字
    GAMEOVER_TXT: 'GAME OVER',
    // 最高分文字
    HIGHSCORE_TXT: 'HighScore: ',
});

module.exports = Constant;    //没有这一句将无法再外部引用

设置点击事件

setInputControl: function() {
        var self = this;
        cc.eventManager.addListener({
            event: cc.EventListener.TOUCH_ONE_BY_ONE,
            onTouchBegan: self._onTouchBegan.bind(self)
        }, self.node);
    },

    _onTouchBegan: function( touch, event ) {
        if ( this.isGameOver === true )
            return;
        this.bird.onJump();
    },    

项目中cocos creator 反馈出来的常见错误及原因

1,游戏运行按钮不可点,无法进入浏览器界面。说明角码存在编译器无法通过的错误,通常会有明显的红叉提示。

2,脚本丢失,说明对应的脚本中存在错误。比如,类型定义是出现书写错误(如将,cc.Node,写成了cc.node)

3,其他组件丢失,通常发生在组件发生纠错修改之后。

你可能感兴趣的:(云创动力)