这是我第一个游戏项目,使用的工具大概有:
① CocosCreator 2.3.1
② sdk+ndk
③ studio64(这个并不是必须的,因为项目完成后构建发布出了问题,所以这是我用来找问题的)
游戏完成后的展示:
一、开始界面
二、通过钢管加分:
三、飞出边界或者碰到钢管游戏结束
① 就是这个小鸟飞过钢管的游戏,应该很多人都玩过。
② 游戏开始:小鸟往前飞行,点击小鸟向上飞,不点小鸟就会往下落,下落的速度越来越快,即有下落加速度
③游戏结束:当小鸟飞出上下边界或者碰到钢管时,游戏结束
④游戏玩法:当小鸟穿过一个钢管障碍物时会加分。
① 小鸟往前飞? No 背景往后退? Yes
首先当然是先想如何实现小鸟往前飞行,换个思路,就是不给小鸟赋予X方向的速度,而是去移动背景图,背景图以一定的速度向左移动,这样看起来就像是小鸟向右移动,一个简单的障眼法。为了避免穿帮,这里要弄两张相同的背景图并行排列并且相连接的地方的内容一定要相互吻合。而摄像机视口一定要在第一张背景图上并且不能大于背景图的大小,两张背景图一起往左移动,当第一张背景图完全移出视口外时,就将它立马放在第二张背景图之后。这样就可以实现背景图一直在往左边移动的效果。
② 钢管移动:
钢管移动的原理与背景图移动差不多。并且速度要控制为相同的。
③ 小鸟飞行:
小鸟在x方向上不动,但是在y方向上要有改变:点击的时候向上飞,不点的时候下落,这里可以通过控制小鸟的y坐标来实现
④钢管随机高度:
作为游戏,一定要增强它的趣味性,所以要随机钢管通过的高度。这里可以用到Math.random();来实现
⑤如何判断游戏结束?
当小鸟飞出上下边界或者碰撞到钢管时,游戏结束;这个可以通过小鸟的y坐标与背景图y来比较和小鸟与钢管的碰撞检测来实现
⑥ 加分:
当小鸟的通过钢管且没有与钢管发生碰撞时可以加分。先判断这根钢管是否与小鸟发生碰撞,且当钢管最右边的x小于小鸟最左边的x时实现加分
一、背景图和钢管的循环移动
1.在CocosCreator新建一个空白项目,在assets目录下分别新建resources(资源文件)、scene(场景)、script(脚本)三个文件夹,并将项目所需的资源导入值resources文件夹下。
2、在scene文件夹下新建一个Flybrid场景,将背景图sky分两次拖入层级管理器下的Canvas,并命名为bj1和bj2,同时在script文件夹下新建一个JS脚本,命名为brid,也拖入Canvas下,改变bj1和bj2的大小和坐标,入下图所示:
3、打开新建的brid脚本,创建背景图节点和spead(游戏速度)并在Crertor中与之关联。通过x坐标减去spead实现背景图移动,当有背景图x坐标==-960的时候,就设置其x坐标=960,实现背景图循环。
cc.Class({
extends: cc.Component,
properties: {
bj1: cc.Node,
bj2: cc.Node,
spead: 3, //游戏速度
},
start() {
},
update(dt) {
this.bj1.x -= this.spead; // 实现移动
this.bj2.x -= this.spead;
if (this.bj1.x == -960) { //循环移动
this.bj1.x = 960;
}
if (this.bj2.x == -960) {
this.bj2.x = 960;
}
},
});
4、将钢管图片拖入至Canvas中,上下两根钢管属于一个父节点,总共添加6组钢管节点,并且要在编辑器中调整每组钢管的x坐标,这里我采用的间距为200.完成后如图所示:
5、接下来在脚本里用同样的方法控制钢管的循环移动:创建pipe节点,并将编辑器中p1与之关联。 并且设置钢管开始为隐藏;(因为游戏开始不可能就出现了钢管)这个需要在start()中写脚本:
for (let idx = 0; idx < this.pipe.children.length; idx++) { ``
this.pipe.children[idx].active = false;
}
用一个for循环实现钢管的循环移动:
for (let i = 0; i < this.pipe.children.length; i++) {
let child = this.pipe.children[i]; // 当前钢管赋给变量
child.x -= this.speed; // 钢管移动实现
if (child.x <= -600) { // 移出屏幕外时重置x坐标
child.active = true; //设置当前孩子钢管可视为真!
child.x = 600;
child.y = (Math.random() * 2 - 1) * 100; //Math.random() 返回0-1之间的一个随机值
}
}
this.pipe.children.length :意思为pipe节点子节点的个数,我这边是6
child.active = true; 当钢管移出移出时将其设为可见
child.y = (Math.random() * 2 - 1) * 100; 这行代码的意思就是控制每组钢管上下随机高度(-100~100)
二、实现小鸟飞行效果
1、将小鸟资源拖入,并在脚本中创建bird节点,
2、实现小鸟下落: 现实生活中,小鸟下落的速度是越来越快的,是有一个加速度。所以在start()创建一个加速度power变量=0,在update()实现小鸟的重力下落,update()代码如下
this.power -= 0.1; // 模拟重力加速度,即小鸟飞行的能量
this.bird.y += this.speed / 2 * this.power; // 小鸟往下掉落的速度=速度x加速度
this.bird.angle = this.power * 10; // 通过能量控制小鸟抬头角度变化
三、实现点击屏幕小鸟向上飞行
1、首先在编辑器里创建一个点击层clickLayer,在脚本中也创建。
2、在start()中编写代码控制小鸟飞行:
this.clickLayer.on(cc.Node.EventType.TOUCH_START, () => {
this.power = 2.5; //当点击时小鸟上升的大小
});
实现监听的步骤为:
谁(节点).on(谁的类型.EventType.怎样触发,要干什么);
这样就可以实现点击屏幕小鸟飞行了
四、小鸟与上下边界、钢管的碰撞检测
1、首先要创建一个函数,即gameOve(),当发生碰撞的时候,就调用这个函数,在start()函数中创建一个标记this.isPlaying = true,在update()中首先判断isPlaying是否为true,否则return,在gameOver()中改变his.isPlaying = flase.这里的作用是为了当发生碰撞时能调用这个函数结束游戏。
gameOver(){
this.isPlaying = false;
},
if(this.isPlaying == false){
return;
}
2、实现小鸟与上下边界碰撞检测
直接上代码:
if (this.bird.y > cc.winSize.height / 2 || this.bird.y < -cc.winSize.height / 2) {
this.gameOver();
return;
}
cc.winSize.获取当前设备视口的大小
原理:当小鸟的y大于上边界的y或者小于下边界的y,则发生碰撞游戏结束。
3、实现小鸟与钢管的碰撞检测(较难)
在update(){}中求出小鸟的上下左右的具体值:
let birdLeft = this.bird.x - this.bird.width / 2; // 小鸟矩形的左边界
let birdRight = this.bird.x + this.bird.width / 2; // 小鸟矩形的右边界
let birdTop = this.bird.y + this.bird.height / 2; //小鸟上边界
let birdBottom = this.bird.y - this.bird.height / 2; // 小鸟 下边界
let checkNode = null;
在控制钢管循环移动的for循环中,求出当前钢管的上下边界即
let subChild = child.getChildByName("pipe1"); // 获取最底层的钢管节点
let cLeft = child.x - subChild.width / 2; // 当前钢管矩形的左边界
let cRight = child.x + subChild.width / 2; // 当前钢管矩形的右边界
新建一个checkNode = null; 如果当前这组钢管与小鸟的x坐标相交,就代表小鸟正在通过钢管,就可以将当前钢管赋予一个循环外的节点中,方便后面对它进行操作;
if (child.active == true && birdLeft <= cRight && birdRight >= cLeft) { // 判断钢管和小鸟x是否相交
checkNode = child;
}
然后如果checkNode里面有值那么if(checkNode)就为true,然后就计算小鸟上下边界是否与当前钢管的上下边界相交就完成了碰撞检测
if (checkNode) { // 这个节点进入碰撞检测
//碰撞检测
let childBottom = checkNode.getChildByName("pipe1"); // 获取当前两根钢管的下钢管
let childTop = checkNode.getChildByName("pipe2"); // 获取当前两根钢管的上钢管
let top = checkNode.y + childTop.y - childTop.height / 2; // 获取上钢管的下边界
let bottom = checkNode.y + childBottom.y + childBottom.height / 2; // 获取下钢管的上边界
if (birdTop >= top || birdBottom <= bottom) { // 如果小鸟的上大于上边界或者小鸟的下小于下边界则有碰撞
// 有碰撞
this.gameOver();
}
}
到这里,游戏的主体功能已经完成!但是还有很多的游戏细节没有做好,继续做优化