【cocos2d-js 3.0】制作2048
2048:在一个4X4的方阵中,玩家需要滑动上面的数字,如果俩个数字相邻并且相等,则相加,需要达到2048,方可胜利。
因为在浏览器操作,所以此例的操作方法为:键盘上的w,s,a,d代表上下左右,也可用小键盘左边的上下左右键。
下面给一张游戏截图,也可以点击这里进行试玩:)
IDE:webstorm
好,现在开始讲解我的制作过程。
首先,新建一个项目,名字叫mini2048。我是用终端cocos new Project出来的,所以要删除一些不必要的代码,并且添加一些游戏相关的资源。
因为这个游戏主要是用做demo并且分享制作过程,所以美术啥的也没好好搞,就一个标题的2048字体用了外部的fnt资源。大家粗略看看就行~
添加游戏背景
/*一个灰色的背景和白色的线组成的方格*/
var background = new cc.LayerColor(cc.color(180,170,160,255),size.width,size.height); //灰色背景
this.addChild(background,0);
var draw = cc.DrawNode.create();
this.addChild(draw, 1);
for(var index=0; index<5; index++){
draw.drawSegment(cc.p(40+index*60, 20), cc.p(40+index*60, 260), 1, cc.color(255, 255, 255, 255)); //竖线
draw.drawSegment(cc.p(40, 20+index*60), cc.p(280, 20+index*60), 1, cc.color(255, 255, 255, 255)); //横线
}
再继续添加一些界面元素,标题,得分,重新游戏什么的
//标题
var title = cc.LabelBMFont.create("2 0 4 8", res.LabelFont_Fnt);
title.x = size.width/2;
title.y = size.height-40;
this.addChild(title,1); //得分
var scoreLabelText = cc.LabelTTF.create("score","Scissor Cuts",20);
scoreLabelText.x = 60;
scoreLabelText.y = size.height*4/5;
scoreLabelText.setColor(cc.color(0,0,0,255));
this.addChild(scoreLabelText,1);
this.scoreLabel = cc.LabelTTF.create("0","Scissor Cuts",20);
this.scoreLabel.x = 60;
this.scoreLabel.y = size.height*4/5-25;
this.scoreLabel.setColor(cc.color(0,0,0));
this.addChild(this.scoreLabel,1); //重新游戏
cc.MenuItemFont.setFontName("Arial");
var restartItem = cc.MenuItemFont.create("restart", this.restartGame, this);
restartItem.setColor(cc.color(22,100,255));
restartItem.x = size.width - 60;
restartItem.y = size.height*4/5-12.5;
var restartMenu = cc.Menu.create(restartItem);
restartMenu.x = 0;
restartMenu.y = 0;
this.addChild(restartMenu,1); //结束label
var gameOverLabel = cc.LabelTTF.create(" 游戏结束! ","Scissor Cuts",50);
gameOverLabel.setColor(cc.color(255,0,255));
gameOverLabel.x = size.width/2;
gameOverLabel.y = size.height/2+60;
gameOverLabel.visible = false;
this.addChild(gameOverLabel,11,5); //通关label
var passTheGameLabel = cc.LabelTTF.create(" 恭喜通关!","Scissor Cuts",50);
passTheGameLabel.setColor(cc.color(255,255,0));
passTheGameLabel.x = size.width/2;
passTheGameLabel.y = size.height/2+60;
passTheGameLabel.visible = false;
this.addChild(passTheGameLabel,11,6);
随后添加键盘事件来相应w,s,a,d和小键盘旁上下左右键的操作。
if (cc.sys.capabilities.hasOwnProperty('keyboard'))
cc.eventManager.addListener({
event: cc.EventListener.KEYBOARD,
onKeyReleased:function (key, event) {
if(key==[cc.KEY.w] || key==[cc.KEY.up] ){
event.getCurrentTarget().slideUp(); //向上滑
}
else if(key==[cc.KEY.a] || key==[cc.KEY.left] ){
event.getCurrentTarget().slideLeft(); //向左滑
}
else if(key==[cc.KEY.d] || key==[cc.KEY.right] ){
event.getCurrentTarget().slideRight(); //向右滑
}
else if(key==[cc.KEY.s] || key==[cc.KEY.down] ){
event.getCurrentTarget().slideDown(); //向下滑
}
}
}, this);
然后制作Card类,继承cc.Sprite,用来做游戏中的卡片。我这里的逻辑是这样的,游戏开始前,初始化4X4的16张卡片,并且每张卡片在对应的位置,并且卡片数字都设置为0,
当游戏运作的时候,不移动卡片,只改变对应卡片上的数字,并且对改变后的数字进行判断,如果是0,则隐藏数字,如果是>0的值,则显示数字并根据值来对数字进行美化。
this.backgroundPic = new cc.LayerColor(cc.color(0, 0, 255, 111), 50, 50); //卡片底色
this.labelText = cc.LabelTTF.create("0", "Trebuchet MS", 21); //卡片数字
this.backgroundPic.ignoreAnchorPointForPosition(false);
this.addChild(this.backgroundPic, 0);
this.addChild(this.labelText,1);
并且给Card类添加一些方法,如设置卡片数字,获取卡片数字的值,对卡片数字大小和卡片背景进行美化等等,因为这些比较简单,所以就不贴码了,尽量避免此博文显得过于冗长。
下面介绍下2048的算法,我觉得也是这部游戏唯一的难点~
因为游戏是上下左右进行滑动,所以只要知道一个方向上是如何运作的,那么也就可以举一反三了,譬如向左滑动这个操作,再对其进行剖析,
我们会发现算法对4排上的数字都是进行同样的操作,所以我们只研究一行数字的算法就可以了。其他的只要循环3次就行。
/*因为算法比较简单,所以我就用注释解释下*/
for(var y=0; y<4; y++){
for(var x=0; x<4; x++){
for(var xRight=x+1; xRight<4; xRight++){
if(game2048array[xRight][y].getCardNumber() != 0){ //game2048array是存放16张卡片的数组,y代表某一行,如果对应卡片右边的卡片数值为0,则对下一个右边的卡片进行循环判断
if(game2048array[x][y].getCardNumber() == 0){ //如果对应卡片右边的值不为0,并且对应卡片的值为0,则将对应卡片的值改为其右边卡片的值
game2048array[x][y].setCardNumber(game2048array[xRight][y].getCardNumber());
game2048array[xRight][y].setCardNumber(0); //然后设置其右边卡片的值为0
this.zeroCardIndex.removeZeroCard(x,y); //this.zeroCardIndex是一个存放值为0的卡片的数组,后面会用到
this.zeroCardIndex.push({coordX:xRight,coordY:y});
x--;
}
else if(game2048array[x][y].getCardNumber() == game2048array[xRight][y].getCardNumber()){
game2048array[x][y].setCardNumber(game2048array[x][y].getCardNumber()*2); //如果对应卡片右边的值不为0,并且对应卡片的值和其右边卡片的值相等,则对应卡片的值位置为原来的两倍
game2048array[xRight][y].setCardNumber(0); //同样设置其右边卡片的值为0
if(game2048array[x][y].getCardNumber()==2048){ //进行判断,如果对应卡片的值达到2048,则游戏通关
this.gameStop = true;
this.passGameLabelAppear(); //通关
}
else{
this.zeroCardIndex.push({coordX:xRight,coordY:y});
}
}
break; //如果对应卡片其右边的卡片值非0,并且对应卡片的值和其右边卡片的值不相等,那么跳出此轮循环,继续判断下一个卡片
}
}
}
}
OK,2048的核心算法已经充分展示,接着,每滑动一次就需要添加一张值为2或者4的卡片。我是这么做的,把游戏中非0卡片的位置都记录到一个数组this.zeroCardIndex中,然后每一次滑动后在此数组中随机取一个元素,
并且在元素上对应的位置信息上添加2或者4的数字。看代码
addOneCard:function(){
var cardIndex = parseInt(Math.random()*this.zeroCardIndex.length); //随机获取一张值为0的卡片
var card = game2048array[this.zeroCardIndex[cardIndex].coordX][this.zeroCardIndex[cardIndex].coordY]; //获取对应位置信息上的卡片
card.setCardNumber(Math.random()<0.2?4:2); //给卡片设置数字 20%的几率会随机到4的卡片
this.zeroCardIndex.splice(cardIndex, 1); //从数组中删除此张卡片
},
最后,对游戏“死亡”进行判定,首先对卡片0的数组的长度(this.zeroCardIndex.lenght)进行判断,如果为0,则判断横向或者竖向的数字,俩俩是不是都不相同,如果是,则表示游戏结束。
isGameOver:function(){
for(var x=0;x<4;x++){
for(var y=0;y<4;y++){
if(x<3 && (game2048array[x][y].getCardNumber()==game2048array[x+1][y].getCardNumber())){ //横向俩俩判断
return false;
}
if(y<3 && (game2048array[x][y].getCardNumber()==game2048array[x][y+1].getCardNumber())){ //竖向俩俩判断
return false;
}
}
}
return true;
}
OK!至此,2048的基本游戏逻辑都介绍完毕,剩下的譬如分数累加什么的简单逻辑就不罗列了,第一次写博客教程,大家多多包涵,有不合适的地方尽管吐槽砸墙!
希望每一个游戏人都能实现自己的游戏梦!:)
【cocos2d-js 3.0】制作2048的更多相关文章
- cocos2d js ClippingNode 制作标题闪亮特效
1.效果图: 之前在<Android 高仿 IOS7 IPhone 解锁 Slide To Unlock>中制作了文字上闪亮移动的效果,这次我们来看下怎样在cocos2d js 中做出类似 ...
- 【翻译】Ext JS 5.0.1 中的新功能
原文:What's New in Ext JS 5.0.1 今天,我们很高兴的宣布Ext JS 5.0.1发布了!此维护版本基于Sencha社区的反馈做了一些改进.下面让我们来了解一下这些改变. 可访 ...
- (15)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第三部分(完)
引言 程序截图: 在第二部分教程中,Ray教大家如何在地图中制作可碰撞的区域,如何使用tile属性,如何制作可以拾取的物品以及如何动态修改地图.如何使用“Heads up display”来显示分数. ...
- (14)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第二部分
引言 程序截图: 这篇教程是<如何使用Cocos2d-x 3.0制作基于tilemap的游戏>的第二部分.在上一个教程中,我们创建了一个简单的基于tiled地图的游戏,里面有一个忍者在沙漠 ...
- (13)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第一部分
引言 程序截图: 本教程将会教大家如何使用Cocos2d-x来做一个基于tile地图的游戏,当然还有Tiled地图编辑器.(我们小时候玩的小霸王小学机里面的游戏,大部分都是基于tile地图的游戏,如坦 ...
- cocos2d js jsb XMLHttpRequest 中文乱码
1.首先讲下怎样使用XMLHttpRequest 下面所说的是在cocos2d-x 2.2.2 或者 2.3 版本号中. 首先要明确cocos2d js事实上分两个版本号,一个是html5的版本号,另 ...
- 更轻更快的Vue.js 2.0与其他框架对比(转)
更轻更快的Vue.js 2.0 崭露头角的JavaScript框架Vue.js 2.0版本已经发布,在狂热的JavaScript世界里带来了让人耳目一新的变化. Vue创建者尤雨溪称,Vue 2.0 ...
- js傻瓜式制作电子时钟
js傻瓜式制作电子时间 使用到的知识点 setInterval函数 构建函数new Date if判断 demo: //css样式请自行设置 <span id="timer" ...
- 窥探Vue.js 2.0 - Virtual DOM到底是个什么鬼?
引言 你可能听说在Vue.js 2.0已经发布,并且在其中新添加如了一些新功能.其中一个功能就是"Virtual DOM". Virtual DOM是什么 在之前,React和Em ...
- 窥探Vue.js 2.0
title: 窥探Vue.js2.0 date: 2016-09-27 10:22:34 tags: vue category: 技术总结 --- 窥探Vue.js2.0 令人兴奋的Vue.js 2. ...
随机推荐
- Composite C1是一个.Net平台上开源专业的CMS开源项目
CompositeC1 4 发布 Composite C1是一个.Net平台上开源专业的CMS开源项目,很多的功能用户界面,面向任务的支持与各种工具协作.当编辑内容时在用户端体验很友好.编辑器与开发者 ...
- .NET依托CLR进行的内存的管理
看了http://www.cnblogs.com/liulun/p/3145351.html 不错,补习下相关技术.. 正文: .NET依托CLR进行的内存的管理 有了CLR 基本不需要担心.net ...
- 关于模型的合法性,Entity.IsValid()合理吗?
关于模型的合法性,Entity.IsValid()合理吗? 背景 见过很多框架(包括我自己的)都会在实体的定义中包含一个IsValid()方法,用来判断实体的合法性,是否应该这样设计呢?本文就这个问题 ...
- 为outlook增加“邮件召回”功能
outlook 2007开始软件自带邮件召回功能.2003版本没有,可惜此版本盗版最厉害,用户很广,这次项目中用户分布很广,其中outlook2003版本用户数甚多,达到397人. 不可能让他们新装2 ...
- SESSION会话技术
以下对session会话技术详解: 要了解点http协议理解更佳--->http请求头和http相应头 在session_start的时候,浏览器会向服务器发出请求 在请求的同时,如果是第一次a ...
- 偏执的我从Linux到Windows的感受
可能很多人知道一个比我还偏执的技术狂人,也就是当年被知乎很多谈论的王垠. 他曾经写过好几篇轰动一时的文章,比如<完全用linux工作>.此文也影响了一批人拥抱Linux.不过不久之后他又写 ...
- BIOS详解:什么是BIOS ?BIOS的作用?CMOS及其与BIOS的关系?
1.什么是BIOS ? BIOS是英文Basic Input Output System的缩略语,直译过来后中文名称就是基本输入输出系统.它的全称应该是ROM-BIOS,意思是只读存储器基本输入输出系 ...
- HashMap 死循环的探究
大家都知道,HashMap采用链表解决Hash冲突,具体的HashMap的分析可以参考一下http://zhangshixi.iteye.com/blog/672697 的分析.因为是链表结构,那么就 ...
- Hexo+NextT第三方服务调用【4】
该系列博客列表请访问:http://www.cnblogs.com/penglei-it/category/934299.html 摘要 静态站点与动态站点有很大的不一样,它拥有一定的局 ...
- 【转】经典!python中使用xlrd、xlwt操作excel表格详解
最近遇到一个情景,就是定期生成并发送服务器使用情况报表,按照不同维度统计,涉及python对excel的操作,上网搜罗了一番,大多大同小异,而且不太能满足需求,不过经过一番对源码的"研究&q ...