CocosEditor版源代码下载:
cocos2d-js源代码请到集中营下载:http://blog.makeapp.co/?p=523
github版本管理:https://github.com/makeapp/cocoseditor-2048
不同平台下的效果图:
windows
html5网页
android平台(各种主题版本)
代码分析:
1初始化;进入游戏,初始化4*4表格,并随机产生两个2;
# 二维数组this.tables表格循环存入数据
#random1, random2 ,random11, random22四个随机数可以确定两个2的xy位置;
#方法newNumber里面,根据位置i,j和级别num可以确定一个新的数字;创建背景cell和cell上面的数字标签cellLabel;并根据num确定是否显示cellLabel;最后给cell关联一个data数据;特别说明这里的number:num不是精灵上面的数字而是精灵的级别,比如number=11 则数字是1024
- MainLayer.prototype.onEnter = function () {
- //version
- this.versionNum = indexVersions;
- this.indexVersion = VERSIONS[this.versionNum];
- this.title.setString(this.indexVersion.name + "目标:" + this.indexVersion.array[this.indexVersion.array.length - 1] + "");
- var random1 = getRandom(4);
- var random2 = getRandom(4);
- while (random1 == random2) {
- random2 = getRandom(4);
- }
- var random11 = getRandom(4);
- var random22 = getRandom(4);
- this.tables = new Array(4);
- for (var i = 0; i < 4; i++) {
- var sprites = new Array(4);
- for (var j = 0; j < 4; j++) {
- if (i == random1 && j == random11) {
- sprites[j] = this.newNumber(i, j, 1);
- } else if (i == random2 && j == random22) {
- sprites[j] = this.newNumber(i, j, 1);
- } else {
- sprites[j] = this.newNumber(i, j, 0);
- }
- }
- this.tables[i] = sprites;
- }
- this.totalScore = 0;
- };
- MainLayer.prototype.newNumber = function (i, j, num) {
- var cell = cc.MySprite.create(this.rootNode, "5.png", this.getPosition(i, j), 1);
- var cellLabel = cc.MySprite.createLabel(cell, "");
- if (num > 0) {
- cell.setColor(COLOR[num]);
- cellLabel.setVisible(true);
- cellLabel.setString(this.indexVersion.array[num]);
- cellLabel.setFontSize(this.indexVersion.labelFontSize);
- } else {
- cellLabel.setVisible(false);
- }
- cell.data = {col: i, row: j, numberLabel: cellLabel, number: num};
- return cell;
- };
2 四个方向算法;玩游戏的时候触摸四个方向,表格就向四个方向合并靠拢leftCombineNumber,rightCombineNumber,downCombineNumber,upCombineNumber,四个方法函数的算法都是一样的,我只分析一个leftCombineNumber;
第一步 相同数据叠加 :
#j从左到右变大,i从下到上变大;也就初始位置是左下角;
#如果该单元格级别不是空背景 cell.data.number != 0 ;
#从它的右边开始var k = i + 1; 循环遍历while (k < 4) {k++};
#如果遍历到单元格级别也不是空背景 if (nextCell.data.number != 0) 遍历结束 k = 4; break;;
#而且如果发现两个单元的级别一样if (cell.data.number == nextCell.data.number)
#级别数据number刷新变化
cell.data.number += 1;
nextCell.data.number = 0;
第二步 填充空数据;
#同理第一步,如果是空背景if (cell.data.number == 0),也是循环遍历while (k < 4) {k++};
#如果遍历到单元格级别不是空背景 if (nextCell.data.number != 0) ,空背景获得该单元格的数据,而该单元格则设为空背景;
cell.data.number = nextCell.data.number;
nextCell.data.number = 0;
- //direction left
- MainLayer.prototype.leftCombineNumber = function () {
- for (var j = 0; j < 4; j++) {
- for (var i = 0; i < 4; i++) {
- var cell = this.tables[i][j];
- if (cell.data.number != 0) {
- var k = i + 1;
- while (k < 4) {
- var nextCell = this.tables[k][j];
- if (nextCell.data.number != 0) {
- if (cell.data.number == nextCell.data.number) {
- cell.data.number += 1;
- nextCell.data.number = 0;
- this.totalScore += SCORES[cell.data.number];
- }
- k = 4;
- break;
- }
- k++;
- }
- }
- }
- }
- for (j = 0; j < 4; j++) {
- for (i = 0; i < 4; i++) {
- cell = this.tables[i][j];
- if (cell.data.number == 0) {
- k = i + 1;
- while (k < 4) {
- nextCell = this.tables[k][j];
- if (nextCell.data.number != 0) {
- cell.data.number = nextCell.data.number;
- nextCell.data.number = 0;
- k = 4;
- }
- k++;
- }
- }
- }
- }
- this.refreshNumber();
- };
- //direction right
- MainLayer.prototype.rightCombineNumber = function () {
- for (var j = 0; j < 4; j++) {
- for (var i = 3; i >= 0; i--) {
- var cell = this.tables[i][j];
- if (cell.data.number != 0) {
- var k = i - 1;
- while (k >= 0) {
- var nextCell = this.tables[k][j];
- if (nextCell.data.number != 0) {
- if (cell.data.number == nextCell.data.number) {
- cell.data.number += 1;
- nextCell.data.number = 0;
- this.totalScore += SCORES[cell.data.number];
- }
- k = -1;
- break;
- }
- k--;
- }
- }
- }
- }
- for (j = 0; j < 4; j++) {
- for (i = 3; i >= 0; i--) {
- cell = this.tables[i][j];
- if (cell.data.number == 0) {
- k = i - 1;
- while (k >= 0) {
- nextCell = this.tables[k][j];
- if (nextCell.data.number != 0) {
- cell.data.number = nextCell.data.number;
- nextCell.data.number = 0;
- k = -1;
- }
- k--;
- }
- }
- }
- }
- this.refreshNumber();
- };
- MainLayer.prototype.downCombineNumber = function () {
- for (var i = 0; i < 4; i++) {
- for (var j = 0; j < 4; j++) {
- var cell = this.tables[i][j];
- if (cell.data.number != 0) {
- var k = j + 1;
- while (k < 4) {
- var nextCell = this.tables[i][k];
- if (nextCell.data.number != 0) {
- if (cell.data.number == nextCell.data.number) {
- cell.data.number += 1;
- nextCell.data.number = 0;
- this.totalScore += SCORES[cell.data.number];
- }
- k = 4;
- break;
- }
- k++;
- }
- }
- }
- }
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- cell = this.tables[i][j];
- if (cell.data.number == 0) {
- k = j + 1;
- while (k < 4) {
- nextCell = this.tables[i][k];
- if (nextCell.data.number != 0) {
- cell.data.number = nextCell.data.number;
- nextCell.data.number = 0;
- k = 4;
- }
- k++;
- }
- }
- }
- }
- this.refreshNumber();
- };
- //touch up
- MainLayer.prototype.upCombineNumber = function () {
- for (var i = 0; i < 4; i++) {
- for (var j = 3; j >= 0; j--) {
- var cell = this.tables[i][j];
- if (cell.data.number != 0) {
- var k = j - 1;
- while (k >= 0) {
- var nextCell = this.tables[i][k];
- if (nextCell.data.number != 0) {
- if (cell.data.number == nextCell.data.number) {
- cell.data.number += 1;
- nextCell.data.number = 0;
- this.totalScore += SCORES[cell.data.number];
- }
- k = -1;
- break;
- }
- k--;
- }
- }
- }
- }
- for (i = 0; i < 4; i++) {
- for (j = 3; j >= 0; j--) {
- cell = this.tables[i][j];
- if (cell.data.number == 0) {
- k = j - 1;
- while (k >= 0) {
- nextCell = this.tables[i][k];
- if (nextCell.data.number != 0) {
- cell.data.number = nextCell.data.number;
- nextCell.data.number = 0;
- k = -1;
- }
- k--;
- }
- }
- }
- }
- this.refreshNumber();
- };
3 刷新数据和颜色;
上面的算法完成了,只是该精灵的data里面的数据发生了变化,但视觉上没有任何变化,所以需要刷新数据和颜色
#新建一个空背景数组emptyCellList;
#又是循环二维数组this.tables
#得到单元格的文字标签label,和级别cellNumber
#如果不是空背景cellNumber!=0,label显示和设置文字内容和大小,同时如果检测到是最高级别,游戏成功结束
#如果是空背景,label隐藏 emptyCellList添加该元素emptyCellList.push(cell);;
#得到一个emptyCellList后,如果发现该数组大小为空,也就无法再产生一个数字2了,游戏over;
#而如果数组大小不是空,随机取一个位置randomCell,设置数据等级为0,数字为2,并播放缩放动画runAction;
- MainLayer.prototype.refreshNumber = function () {
- var emptyCellList = [];
- for (var i = 0; i < 4; i++) {
- var numbers = " ";
- for (var j = 0; j < 4; j++) {
- var cell = this.tables[i][j];
- var label = cell.data.numberLabel;
- var cellNumber = cell.data.number;
- if (cellNumber != 0) {
- cell.setColor(COLOR[cellNumber]);
- label.setString(this.indexVersion.array[cellNumber] + " ");
- label.setFontSize(this.indexVersion.labelFontSize);
- label.setVisible(true);
- if (cellNumber == (this.indexVersion.array.length - 1)) {
- //check success
- var toast = cc.Toast.create(this.rootNode, "成功到达:" + this.indexVersion.array[cellNumber], 2);
- toast.setColor(cc.c3b(255, 0, 0));
- this.rootNode.scheduleOnce(function () {
- cc.BuilderReader.runScene("", "MainLayer");
- }, 2)
- }
- } else {
- cell.setColor(COLOR[cellNumber]);
- label.setVisible(false);
- emptyCellList.push(cell);
- }
- numbers += " " + cellNumber;
- }
- cc.log("numbers==" + numbers);
- }
- //score
- this.scoreLabel.setString("分数:" + this.totalScore);
- if (emptyCellList.length < 1) {
- //check fail
- var toast = cc.Toast.create(this.rootNode, "失败!", 2);
- toast.setColor(cc.c3b(255, 0, 0));
- this.rootNode.scheduleOnce(function () {
- cc.BuilderReader.runScene("", "MainLayer");
- }, 2)
- } else {
- //create random cell
- var randomCell = emptyCellList[getRandom(emptyCellList.length)];
- randomCell.data.number = 1;
- randomCell.data.numberLabel.setVisible(true);
- randomCell.data.numberLabel.setString(VERSIONS[this.versionNum].array[1] + "");
- randomCell.data.numberLabel.setFontSize(this.indexVersion.labelFontSize);
- randomCell.setColor(COLOR[1]);
- randomCell.runAction(cc.Sequence.create(cc.ScaleTo.create(0, 0.8), cc.ScaleTo.create(0.5, 1)));
- }
- };
4 触摸检测 两个触摸点this.pEnded this.pBegan 根据x y确定方向,再根据距离确定左右和上下;
- MainLayer.prototype.onTouchesEnded = function (touches, event) {
- this.pEnded = touches[0].getLocation();
- if (this.pBegan) {
- if (this.pEnded.x - this.pBegan.x > 50) {
- this.rightCombineNumber();
- }
- else if (this.pEnded.x - this.pBegan.x < -50) {
- this.leftCombineNumber();
- }
- else if (this.pEnded.y - this.pBegan.y > 50) {
- this.upCombineNumber();
- }
- else if (this.pEnded.y - this.pBegan.y < -50) {
- this.downCombineNumber();
- }
- }
- };
思路很清晰简单,游戏却是简约不简单;
CocosEditor开发工具:
CocosEditor,它是开发跨平台的手机游戏工具,运行window/mac系统上,javascript脚本语言,基于cocos2d-x跨平台游戏引擎, 集合代码编辑,场景设计,动画制作,字体设计,还有粒子,物理系统,地图等等的,而且调试方便,和实时模拟;
CocosEditor 下载,介绍和教程:http://blog.csdn.net/touchsnow/article/details/19070665;
CocosEditor官方博客:http://blog.makeapp.co/;
笔者语:
想了解更多请进入官方博客,最新博客和代码在官方博客首发;请持续关注,还有更多CocosEditor游戏源码即将放出;
联系笔者:zuowen@makeapp.co(邮箱) 扣扣群:232361142
附录:
整理各种版本的2048在线玩,狂欢起来吧;
1、2048原始版
http://gabrielecirulli.github.io/2048/
2、2048进阶版(有乘法和继续玩下去的功能)
http://baiqiang.github.io/2048-advanced/
3、2048汉化版1:甲乙丙丁
http://tiansh.github.io/2048/zhong/
4、2048汉化版2:商周秦汉
http://oprilzeng.github.io/2048/
5、2048喵喵版:色弱慎入
http://hczhcz.github.io/2048/20mu/
6、2048丧病版:8*8
http://cyberzhg.github.io/2048/
7、2048flappy版
http://hczhcz.github.io/Flappy-2048/
8、2048六角形版
http://baiqiang.github.io/2048-hexagon/
9、2048cross版
http://baiqiang.github.io/2048-cross/
10、2048double版
http://baiqiang.github.io/2048-double/
11、2048哲学版
http://learn.tsinghua.edu.cn:8080/2013310744/philosopher2048/
12、2048一步登天版
http://jennypeng.me/2048/
13、2048斐波那契数列版
http://mike199515.free3v.com/1597/2.htm
14、2048双人对战版
http://emils.github.io/2048-multiplayer/
15、2048变2版
https://www.prism.gatech.edu/~hli362/
16、2048直线版
http://tiansh.github.io/2048/
17、新增3D版的2048:
http://baiqiang.github.io/2048-3d/
18、2048的一个合集:
http://get2048.com/
相关推荐
微信购票小程序源代码.zip是一个包含微信小程序开发的完整源代码包。这个压缩文件的核心内容是“cinema_wx-code”,这很可能是一个名为“cinema_wx”的微信小程序项目的源代码目录。下面将详细阐述微信小程序的基本...
智能门锁小程序源代码是专为现代科技生活设计的一款应用程序,它主要运行在微信小程序平台上。这个源代码的核心功能在于生成临时动态密码,为用户提供安全、便捷的门锁控制方式。临时动态密码技术是一种增强安全性的...
本篇文章将深入探讨如何使用JDOM解析包含同名多节点且带有多个属性的XML源代码,以及如何从HTTP返回流中直接获取并解析XML数据。 首先,让我们理解XML文档的基本结构。XML文档由元素、属性、文本和注释等组成。同名...
BR大逃杀游戏,全称为Battle Royale(大逃杀)类型的游戏,是一种多人在线竞技生存游戏,灵感来源于日本作家高见广春的小说《大逃杀》和同名电影。玩家通常被投放到一个封闭的环境中,需要通过搜集资源、对抗其他...
根据提供的文件信息,我们可以推断出这是一份关于使用Java编程语言开发的“火影忍者”游戏的源代码。接下来,我们将详细分析并总结出与该标题、描述及部分内容相关的知识点。 ### Java编程语言 Java是一种广泛使用...
仙境传说(RO)是一款深受玩家喜爱的大型多人在线角色扮演游戏,其私人服务器端源代码是开发者们研究游戏机制、自定义游戏规则的重要参考资料。本资源提供的"仙境传说(RO)私人服务器端源代码delphi",是使用Delphi...
"Anthem"源代码指的是由著名游戏开发商Bioware开发的同名游戏——《Anthem》背后的编程语言和逻辑。这款游戏以其独特的世界观、动态的飞行战斗和丰富的角色定制系统吸引着全球玩家。本文将深入探讨Anthem源代码中的...
扫雷游戏是一款经典的桌面益智游戏,其C++源代码为初学者提供了深入理解编程语言特性和算法设计的宝贵资源。下面将详细解释这个扫雷项目中的关键知识点,并且探讨如何通过它来学习C++编程。 1. **基础C++语法**:...
学习Java的第一步通常是理解这些基本概念,比如声明变量、使用控制结构(如if语句和for循环)以及创建函数。 2. **类与对象**:Java是面向对象的,这意味着它基于类和对象的概念。类是对象的蓝图,定义了对象的属性...
本资源“全面培训asp.net程序设计源代码”是一个针对初学者的优秀学习材料,通过实例源代码深入浅出地讲解ASP.NET程序设计的核心概念和技术。 在学习ASP.NET时,首要理解的是其基本架构。ASP.NET页面生命周期是关键...
在Android平台上,贪吃蛇游戏是一款经典的休闲娱乐应用,它基于早期诺基亚手机上的同名游戏进行开发。本文将深入解析这个Android贪吃蛇游戏的源代码,并探讨其核心概念和技术实现。 首先,让我们从游戏的基本框架...
《VC6+DirectX开发的游戏Koules》是一款基于Visual C++ 6.0和DirectX技术开发的小型游戏,其源代码小巧却能实现精彩的效果。本游戏的开发是受到LINUX平台同名游戏的启发,但在Windows环境下运行,需要安装DirectX ...
标题 "用VC编写的邮件客户端源代码" 描述了一个使用C++编程语言,在Microsoft Visual C++(简称VC)开发环境中构建的邮件客户端程序。这个项目包含了一系列与邮件发送和接收相关的源代码文件,旨在帮助C++程序员理解...
把生成的放在kele8中就行了,有个同名的文件在里面的. 另外里面有很多不同的文件名的执行文件,但它们的字节数都一样的,那个就是微软公司的jview文件了.它是用执行java程式的.用它来打开同样名的.zip文件,后面再加个有...
《C++入门经典源代码(第3版)\2271》是一本旨在引导初学者进入C++编程世界的书籍,其附带的源代码文件集合为读者提供了实践和理解编程概念的重要资源。在这个压缩包中,包含了一系列与书中章节相关的程序示例,帮助...
有时,开发者可能需要对已发布的APK进行反编译,以查看或修改其内部结构,例如Java源代码,这在逆向工程、安全分析或学习他人代码时尤为常见。本文将详细介绍如何通过ApkTool工具进行APK反编译。 首先,理解什么是...
这个"Android 扫雷源代码"提供了一个实现扫雷游戏的基础框架,适用于Android开发人员学习和研究。下面将详细介绍这个源代码中涉及到的主要技术点、设计思路以及可能包含的优化技巧。 1. **基本逻辑实现**: - 游戏...
【中国象棋源代码C++】是一份使用C++编程语言实现的中国象棋游戏的源代码。在学习和分析这份源代码时,我们可以深入理解C++编程的基础知识,以及如何利用面向对象编程来设计一个复杂的棋类游戏。以下是这份源代码中...
1. **PropertyGenerator**: 从文件名推测,这可能是一个用于生成属性代码的工具,比如在面向对象编程中自动生成类的getter和setter方法。这在快速开发或模板编程中非常有用,可以减少重复的编码工作。 2. **...
随书源代码分成了多个部分,这里我们关注的是"part 2",包含两个文件:part2.txt和一个同名的ZIP压缩包。 part2.txt可能是作者提供的额外说明、代码注解或者教程中的练习解答,对于理解和实践书中内容有辅助作用。...