软件工程第一课——falppybird的创建、cocosCreator的初步使用

 cocos Creator 在创建miniGame中的良好应用以flappy Bird为例

 

班级博客 https://edu.cnblogs.com/campus/zjcsxy/SE2020
作业要求 https://edu.cnblogs.com/campus/zjcsxy/SE2020/homework/11334
作业目标

初步熟悉cocosCreator创建游戏过程,熟悉git代码管理流程

作业源代码 https://github.com/24kyou/flappy_bird-and-cocos_creator
学号    31803183
姓名    章一欧
班级 计算1802

 

 

 

 

 

 

 

 

 

作业需求:

通过制作flappy bird初步认识cocos creator(以下简称cc)游戏引擎。

为何选择cocos Creator游戏引擎的原因

1、单纯在微信小程序开发者工具开发具有3D/2D的游戏对于第一次接触前端的我太为困难,所以选择较为简单的cc作为入门工具

2、cc占微信小游戏制作所用游戏引擎比例高达50%,网上针对其教程较为充足,方便初学者上手

微信小游戏所用的游戏引擎及其比例

3、课程最终目标是设计一个和认知相关的游戏或app,而cc支持导出为其他众多类型的小游戏/app,所以上手cc有助于多平台开发

小游戏原型:

灵感来源:https://github.com/zhuayu/miniprogram-game-flyingbird

原程序不足之处:

1、小鸟运动姿态不足,下坠时/上升只有一种姿态

2、下坠速度太快

3、水管图标与实际碰撞面积不相同,下图中的图一为原来的笔杆式水管,虽有创意但其顶部碰撞面积是方型而不是看上去的锥型,在cc中可以设置实际碰撞面积

解决方案:

使用cc将flappy bird进行重写以实现改正原有不足和后续可维护

试图达成的目标:

  1. 初步认识cc,懂得cc的界面分布和cc的基础节点信息✔
  2. 创建Flappy Bird的背景,如小鸟、水管、地面✔
  3. 使得小鸟可以上下移动,并且小鸟能随着上下移动时发生小鸟姿态的变化✔
  4. 当小鸟撞击水管/地面时小鸟死亡,进入结束界面✔
  5. 点击重新开始可以将背景中的水管归零,且小鸟回到原位✔
  6. 当小鸟越过水管时,会有得分✔
  7. 统计本局游戏的分数,在游戏结束时显示本局游戏得分和最高分✔

项目部分详情:

认识cc:

cc和微信开发者有些不同:

  cc可以构建3d图形,但受限于微信要求的大小可能用不到,所以构建2d项目

  cc推荐使用的使vs和vscode,IDE工具相较于微信开发者功能更加丰富

cc的界面:

 

 此处用于创建图层背景以及节点信息.cc的节点有众多类别.本项目中使用最多的则是sprite(精灵),button(按钮),label(文本)

 

此处用于资源管理,对象包括动画编辑,脚本代码,各种图片资源(使用图片整合软件形成.plist文件将文件保存在一张图上),自身项目(把整个项目当作一个资源存储起来,由于刚上手仅仅当作保存设备),文本资源(推荐使用.fnt文件可以将所有文件保存在一张图上)

 

 

 

 此处是展示图片背景的地方,也是场景编辑的地方

 

 

 

 场景下半部分则为控制部分和绘制动画部分

 

 

 

 还有其他选项设置

脚本代码部分:

初始部分:

  官方文档连接:常用节点和组件接口 · Cocos Creator

cc.Class({
    extends: cc.Component,
properties: {//此处为要用到的类型设置,从此处设置类型
},

</span><span style="color: #008000;">//</span><span style="color: #008000;"> LIFE-CYCLE CALLBACKS:</span>

onLoad () {//初始时加载
},

start () {//没用到过
},
xxx:function(xxx){//方法设置<br />   },
 update (dt) {//每1/60秒执行一次 
 },

});

 

设置不同场景下的调换:

采用设置全局变量gametype,

this.gameType=0//0:begin 1:ready 2:play 3:over

 

通过getComponent()方法获得其他组件中

  官方文档:访问节点和其他组件 · Cocos Creator

水管出现的位置和出现数量的代码部分:

  此处中使用了cc自带的回收系统,可以减少加载资源所带来的消耗

createBlock: function (pos) {
        let block = null;
        if (this.blockPool.size() > 0) { // 通过 size 接口判断对象池中是否有空闲的对象
            block = this.blockPool.get();
        } else { // 如果没有空闲对象,也就是对象池中备用对象不够时,我们就用 cc.instantiate 重新创建
            block = cc.instantiate(this.pre_block);
        }
        block.parent = this.blockparent; // 将生成的敌人加入节点树
       
        block.getComponent('block').isScore()//先是获得组件在调用方法
        /*与下行调换会出现问题,5个水管叠在一起
        * */
        block.setPosition(pos)//设置block的位置坐标
    
},

onBlockKilled: </span><span style="color: #0000ff;">function</span> (block) {<span style="color: #008000;">//</span><span style="color: #008000;">回收块</span>
    <span style="color: #008000;">//</span><span style="color: #008000;"> enemy 应该是一个 cc.Node</span>
    <span style="color: #0000ff;">this</span>.blockPool.put(block); <span style="color: #008000;">//</span><span style="color: #008000;"> 和初始化时的方法一样,将节点放进对象池,这个方法会同时调用节点的 removeFromParent</span>

},
pdCreateBlock:
function(){//
var children =this.blockparent.children
var numBlock=0
var arr_x=[]
for(let i=0;i<children.length;i++){
var js_block = children[i].getComponent('block')
if(js_block){
numBlock
++
arr_x.push(children[i].x)
}
}
if(numBlock==0){
var block_y=Math.random()330-440 //-110~-440
this.createBlock(cc.v2(240,block_y))
}
if(numBlock<5){
var f_x=arr_x[arr_x.length-1]+this.betweenX
var block_y=Math.random()
330-440 //-110~-440
this.createBlock(cc.v2(f_x,block_y))
}
},
//重新开始时清理原有桌面上的管道
AllBlockClean:function(){
var children =this.blockparent.children
for(let i=children.length-1;i>=0;i--){//数组从后往前移
var js_block=children[i].getComponent('block')
if(js_block){//判断是否是block节点的,可以不用
this.onBlockKilled(children[i])
}
}
},

View Code

 这其中使用到的对象池的官方文档:使用对象池 · Cocos Creator

Button的设置:

  官方文档:Button 组件参考 · Cocos Creator

设计触摸控制:

  因为小鸟只需要对点击产生反应所以只用到touchend这个输入

setTouch:function(){
        this.node.on('touchmove', function (event) {
            cc.log('touchstart ');
        }, this);
        this.node.on('touchmove', function (event) {
            cc.log('touchmove')
        }, this);
        this.node.on('touchend', function (event) {//触屏结束之后
            if(this.gameType==1){
            this.gameType=2
            this.touch_play.active=false
            var block_y=Math.random()*330-440 //-110~-440
            this.createBlock(cc.v2(250,block_y))
            }
            if(this.gameType==2){//当点击后小鸟会向上移动
                //this.bird_real.stopAllaction()//使得bird所有动作停止
                this.bird_real.stopActionByTag(2)
                var js=this.bird_real.getComponent('bird')//获取组件的方法,不用通过window来取得
                js.fall=false
                js.time=0//让time=0使得下降速度不会太快
                js.setRotation('up')
                var act_1=cc.moveBy(0.3,cc.v2(0,50)).easing(cc.easeCubicActionOut())//easing 缓冲的动作//此处控制小鸟点击后上移动
                var act_2=cc.callFunc(function(){
                    js.fall=true
                    js.setRotation('down')
                }.bind(this))
                var end=cc.sequence(act_1,act_2)
                end.setTag(2)
                this.bird_real.runAction(end)  
            }
          }, this);
    },
View Code

 

  官方文档:系统内置事件 · Cocos Creator 中的触摸事件

设计开始界面小鸟和文本的上下跳动的代码

setTouch:function(){
        this.node.on('touchmove', function (event) {
            cc.log('touchstart ');
        }, this);
        this.node.on('touchmove', function (event) {
            cc.log('touchmove')
        }, this);
        this.node.on('touchend', function (event) {//触屏结束之后
            if(this.gameType==1){
            this.gameType=2
            this.touch_play.active=false
            var block_y=Math.random()*330-440 //-110~-440
            this.createBlock(cc.v2(250,block_y))
            }
            if(this.gameType==2){//当点击后小鸟会向上移动
                //this.bird_real.stopAllaction()//使得bird所有动作停止
                this.bird_real.stopActionByTag(2)
                var js=this.bird_real.getComponent('bird')//获取组件的方法,不用通过window来取得
                js.fall=false
                js.time=0//让time=0使得下降速度不会太快
                js.setRotation('up')
                var act_1=cc.moveBy(0.3,cc.v2(0,50)).easing(cc.easeCubicActionOut())//easing 缓冲的动作//此处控制小鸟点击后上移动
                var act_2=cc.callFunc(function(){
                    js.fall=true
                    js.setRotation('down')
                }.bind(this))
                var end=cc.sequence(act_1,act_2)
                end.setTag(2)
                this.bird_real.runAction(end)  
            }
          }, this);
    },
View Code

 

  官方文档:使用动作系统 · Cocos Creator

同时也在被另一种系统所替代:使用缓动系统 · Cocos Creator

存储在本地最高分以及调取最高分:

  代码是直接从官方文档复制的,所以直接贴官方文档:存储和读取用户数据 · Cocos Creator

 判断小鸟越过得分:

 由于不同图层的左边的坐标系并不相同,所以采用的是判断水管是否到达屏幕最左边且小鸟没有碰到水管。

addScore:function(){
        var children =this.blockparent.children
    for(let i=children.length-1;i>=0;i--){//数组从后往前移
       var js_block=children[i].getComponent('block')
       if(js_block){//判断是否是block节点的,可以不用
        if(children[i].x<-470&&js_block.canScore){//当小鸟越过管道时 +children[i].width/2 -(this.bird_real.width/2)
            js_block.canScore = false
            this.numScore++//score_play是标签不能加
            this.score_play.string=this.numScore
    }
   }
}
},</span><span style="color: #008000;">//</span><span style="color: #008000;">和前面相同的部分用于判断是否为管道</span></pre>
View Code

 

其中部分代码用于判断是否为水管,通过调用block组件来判断所经过的是否为水管来确定是否得分

 

小程序实机展示部分:

开始部分:

 

准备部分:

 

 

游戏画面:

 

 

游戏结束界面:

 

 

注意事项:

1、图层之间会存在相互遮蔽关系要注意确定哪个图层出现在上部。

;

其图层遮蔽是按节点在后顺序来遮蔽的,block节点在land之后,所以就出现水管挡住地面的现象

2、不同图层的之间的定位并不绝对相同

 

 

 即便在cancas上看起来在一起,但实际上的位置并不相近

 3、从cocos构建项目后导入微信开发者后模拟器上小程序图像不匹配的问题

注意cocos在构建微信小程序项目之后,其显示方式并不是原来显示在cocos上的竖屏显示所以要game.json中的配置进行调整

{
"deviceOrientation": "portrait",//这是竖屏,
}
/*{
"deviceOrientation":"landscape",//为横屏。
}**/

 4、在cc中设置的节点和方法重名时,会导致问题出现

设置为不重名即可

5、如何使地面和水管有移动的效果:

为了简化小鸟运动方式,可以使得地板和水管以固定速率移动,而小鸟就保持在固定x上下移动,以避开水管。

发布微信小程序:

官方文档:发布到微信小游戏 · Cocos Creator

 用好官方文档和官方api

微信官方文档:小游戏配置 | 微信开放文档 (qq.com)

cc官方文档:Introduction · Cocos Creator 

 

 

posted @ 2020-10-22 00:04  zyo-n  阅读(457)  评论(1)    收藏  举报