花了两天时间去学习Cocos Creator并看教程学习了去做第一个游戏–flappyBird。
为什么用Cocos Creator?
仅仅看书去学习挺枯燥的,这个时候如果有一个软件可以让你迅速做出东西来,你就会很有成就感! Cocos Creator 是对新人非常友好的。而且你了解后会发现官方自己在做讲解的视频,实在是太有亲和力了。
Cocos Creator有什么优势?
先上一张图
前八都是Cocos写的!
这说明它确实有自己的独到之处。而且相当有竞争力。
GitHub链接:flappyBird
核心代码
下面展示 mainControllor.ts代码片
.
const {ccclass, property} = cc._decorator;
@ccclassexport default class NewClass extends cc.Component {
@property(cc.Label)
label: cc.Label = null;
@property
text: string = 'hello';
@property(cc.Sprite)
bird0:cc.Sprite = null;
@property(cc.Sprite)
bird1:cc.Sprite = null;
@property(cc.Sprite)
bird2:cc.Sprite = null;
@property(cc.Sprite)
bird3:cc.Sprite = null;
@property(cc.Node)
birdParent:cc.Node = null;
@property(cc.Node)
bg0:cc.Node = null;
@property(cc.Node)
bg1:cc.Node = null;
@property(cc.Node)
pipeParent0:cc.Node = null;
@property(cc.Node)
pipeParent1:cc.Node = null;
@property(cc.Node)
pipeParent2:cc.Node = null;
@property(cc.Node)
pipeParent3:cc.Node = null;
@property(cc.Label)
lbscore:cc.Label = null;
@property(cc.Node)
nodeGameOver:cc.Node = null;
@property(cc.Button)
btnStart:cc.Button = null;
// LIFE-CYCLE CALLBACKS:
// onLoad () {}
time:number = 0; speed:number = 0; score:number = 0;
isGameStart:boolean = false;
start () {//初始时给管子位子赋值坐标
let pipeStartOffsetX:number = 200; let num = (800 + 52)/4;
this.pipeParent0.x = pipeStartOffsetX + num*0; this.pipeParent1.x = pipeStartOffsetX + num*1; this.pipeParent2.x = pipeStartOffsetX + num*2; this.pipeParent3.x = pipeStartOffsetX + num*3;
}
update (dt:number) {
let timeTemp = this.time + dt;
this.time = timeTemp;
if(this.time > 0.5){//小鸟扇翅膀,即同一时刻只显示一个bird,然后切换
if(this.bird0.node.active){ this.bird0.node.active = false; this.bird1.node.active = true; }else if(this.bird1.node.active){ this.bird1.node.active = false; this.bird2.node.active = true; }else if(this.bird2.node.active){ this.bird2.node.active = false; this.bird3.node.active = true; }else if(this.bird3.node.active){ this.bird3.node.active = false; this.bird0.node.active = true; }
this.time = 0;//不要忘了要清零
}
// let birdY = this.birdParent.y; //匀速下落
// this.birdParent.y = birdY - 2;
if(this.isGameStart == false){//游戏没有开始时,以下皆不运行
return; }
this.speed = this.speed - 0.05;//给定小鸟速度
this.birdParent.y = this.birdParent.y + this.speed;
this.birdParent.rotation = - this.speed * 10;//上飞,下落的时候旋转一定角度
this.moveBg(this.bg0);//调用背景移动函数
this.moveBg(this.bg1);
this.movePipe(this.pipeParent0);//调用管子移动函数
this.movePipe(this.pipeParent1);
this.movePipe(this.pipeParent2);
this.movePipe(this.pipeParent3);
this.checkCollision(this.birdParent,this.pipeParent0);//检测碰撞
this.checkCollision(this.birdParent,this.pipeParent1);
this.checkCollision(this.birdParent,this.pipeParent2);
this.checkCollision(this.birdParent,this.pipeParent3);
}
moveBg(bg:cc.Node){
bg.x = bg.x -1;
if(bg.x < -800){//当背景移动到-800(即一个屏幕宽度)时,把背景移动到两个屏幕前
bg.x = bg.x + 800*2; }
}
movePipe(pipe:cc.Node){//管子移动到屏幕外面时(屏幕一半宽度+管子一半宽度),把管子提前到一个屏幕前+管子宽度
pipe.x = pipe.x - 2;
if(pipe.x < (-400-26)){
pipe.x = pipe.x + 800+52;
pipe.y = 100 - (Math.random()*100);//给管子y轴一个随机位置,Math.random()会生成一个0-1之间的数
this.score = this.score + 1;//得分+1
this.lbscore.string = this.score.toString();//把label转成字符串,但是很遗憾我这里使用font失败
}
}
checkCollision(bird:cc.Node,pipe:cc.Node){
if(bird.x + 17 < pipe.x - 26){//小鸟的最右边x小于管子最左边
return;
}
if(bird.x -17 > pipe.x + 26){//小鸟最左边x大于管子最右边
return;
}
if((bird.y + 12 < pipe.y +100)&&(bird.y -12 > pipe.y - 100)){//两个管子y轴中间
return;
} else{
this.gameOver();
console.log("发生碰撞");//在开发者工具中可以看到“发生碰撞”
}
}
onButtonClick(){//点击时给鸟一个向上的速度
this.speed = 2.5; }
onButtonStartClick(){//点击开始按钮
this.isGameStart = true;
this.nodeGameOver.active = false;
this.btnStart.node.active = false;
this.resetGame(); }
gameOver(){
this.isGameStart = false;
this.nodeGameOver.active = true;
this.btnStart.node.active = true; }
resetGame(){//重置游戏
this.nodeGameOver.active = false;
this.btnStart.node.active = false;
this.birdParent.x = -100;
this.birdParent.y = -33;
this.speed = 0;
let pipeStartOffsetX:number = 200;
let num = (800 + 52)/4;
this.pipeParent0.x = pipeStartOffsetX + num*0;
this.pipeParent1.x = pipeStartOffsetX + num*1;
this.pipeParent2.x = pipeStartOffsetX + num*2;
this.pipeParent3.x = pipeStartOffsetX + num*3; }
}
ps:我贴代码的时候网页上并没有和原文本一致,手动回车了一些,见谅。
遇见问题及解决
- 为什么我创建的节点位置在世界坐标(0,0)而不是canvas中间?答:你需要选择canvas然后创建节点。直接在canvas外部创建节点就会初始位置在(0,0)
- 为什么我明明从两个管子之间通过了还是gameOver?答:函数没有写错的情况下。是因为你的pipeParent的具体位置没有对上!如图1是正好对上(即蓝色边框就是你要计算的区域).
图2没有重现我当时的位置,但是就是这样子并没有把pipeParent与图中管子直接的区域对齐
今天的分享就到这里谢谢大家,虽然还有很多不足,但是迈出的这一步就已经让人有些感动。这里分享额外的一点东西。没有必要买淘宝上面的教程!人家官网有!腾讯视频也有,免费的,希望大家不要向我一样略坑了一把。