软件工程第一课——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进行重写以实现改正原有不足和后续可维护
试图达成的目标:
- 初步认识cc,懂得cc的界面分布和cc的基础节点信息✔
- 创建Flappy Bird的背景,如小鸟、水管、地面✔
- 使得小鸟可以上下移动,并且小鸟能随着上下移动时发生小鸟姿态的变化✔
- 当小鸟撞击水管/地面时小鸟死亡,进入结束界面✔
- 点击重新开始可以将背景中的水管归零,且小鸟回到原位✔
- 当小鸟越过水管时,会有得分✔
- 统计本局游戏的分数,在游戏结束时显示本局游戏得分和最高分✔
项目部分详情:
认识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])
}
}
},
这其中使用到的对象池的官方文档:使用对象池 · 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); },
官方文档:系统内置事件 · 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); },
同时也在被另一种系统所替代:使用缓动系统 · 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>
其中部分代码用于判断是否为水管,通过调用block组件来判断所经过的是否为水管来确定是否得分
小程序实机展示部分:
开始部分:

准备部分:

游戏画面:
游戏结束界面:

注意事项:
1、图层之间会存在相互遮蔽关系要注意确定哪个图层出现在上部。
;
其图层遮蔽是按节点在后顺序来遮蔽的,block节点在land之后,所以就出现水管挡住地面的现象
2、不同图层的之间的定位并不绝对相同
![]()
![]()
![]()
即便在cancas上看起来在一起,但实际上的位置并不相近
3、从cocos构建项目后导入微信开发者后模拟器上小程序图像不匹配的问题
注意cocos在构建微信小程序项目之后,其显示方式并不是原来显示在cocos上的竖屏显示所以要game.json中的配置进行调整
{ "deviceOrientation": "portrait",//这是竖屏,
}
/*{
"deviceOrientation":"landscape",//为横屏。
}**/
4、在cc中设置的节点和方法重名时,会导致问题出现
设置为不重名即可
5、如何使地面和水管有移动的效果:
为了简化小鸟运动方式,可以使得地板和水管以固定速率移动,而小鸟就保持在固定x上下移动,以避开水管。
发布微信小程序:
用好官方文档和官方api
微信官方文档:小游戏配置 | 微信开放文档 (qq.com)
cc官方文档:Introduction · Cocos Creator


浙公网安备 33010602011771号