CocosEditor开源版
笔者历时一个晚上,终于完成了cocos2d-js开源版本,编码虽易,创意不易,且行且珍惜;
此版本包含了网上流行的各种版本。包括原版,朝代版,金庸版,星座,豪车等等近10个版本,代码开源,希望读者基于开源代码做出各种版本,供全名娱乐;
运行demo需要配置好CocosEditor,暂不支持其他工具。demo是跨平台的,可移植运行android,ios,html5网页等,代码是基于javascript语言,cocos2d-x游戏引擎,CocosEditor手游开发工具完成的。
已发布上线apk演示效果
几个小时开发,一天审核上线,这就是CocosEditor开发游戏的速度
360应用市场(2048 聚合版):http://zhushou.360.cn/detail/index/soft_id/1634607?recrefer=SE_D_2048%20%E8%81%9A%E5%90%88
豌豆荚应用市场 :http://www.wandoujia.com/apps/com.touchsnow.game.sudoku
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(); } } };
思路很清晰简单,游戏却是简约不简单;
——————————————游戏基础教程篇—————————————已完成————————— cocos2d-x editor工具下载和基础教程JS篇: 一 手游开发神器 cocos2d-x editor初识 二 手游开发神器 cocos2d-x editor工具下载和安装配置 三 手游开发神器 cocos2d-x editor 之基础工具 intellij idea 四 手游开发神器 cocos
本文向大家介绍javascript版2048小游戏,包括了javascript版2048小游戏的使用技巧和注意事项,需要的朋友参考一下 没有技术含量,只是用来练习代码逻辑的。为了代码结构清晰,我把逻辑控制部分写在全局变量里,用户界面操作封装在UI对象里,大概就这样了。仅供参考。工作时候,我的编码风格有人吐槽太乱了,所以我想试着写一个不是那么乱的东西出来。。 以上就是本文所述的全部内容了,希望大家能
实现一个简单的2048小游戏。手指上下左右滑动屏幕可以移动方块。 2048游戏是什么:每次控制所有方块向同一个方向运动,两个相同数字的方块撞在一起之后合并成为他们的和,每次操作之后会在空白的方格处随机生成一个2或者4,最终得到一个“2048”的方块就算胜利了。如果16个格子全部填满并且相邻的格子都不相同也就是无法移动的话,那么游戏就会结束。
本文向大家介绍java版实现2048游戏功能,包括了java版实现2048游戏功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java实现2048游戏功能的具体代码,供大家参考,具体内容如下 功能要求:2048的基本界面,能够实现2048的游戏功能。 总思路:两个类:Game和GameListener。 Game负责界面的实现和paint方法的重写 GameListener负责实
我正在尝试用C重新创建游戏2048,但我无法让算法移动或合并瓷砖在一起以正常运作。在最初的2048游戏中,你会像这样移动瓷砖: 所以两个相同的瓷砖可以合并成一个两倍大小的瓷砖。我的版本几乎是相同的,但我没有使用数字,而是使用合并时递增1的字符,因此将合并到等。我这样做只是为了不必处理不同大小的瓷砖。 所以我的板存储为一个4*4字符数组,在一个我称之为网格的结构中(我知道可能有点多余) 我曾经尝试过
本文向大家介绍javascript制作2048游戏,包括了javascript制作2048游戏的使用技巧和注意事项,需要的朋友参考一下 2048.html 2048.css 2048.js 以上所诉就是本文的全部内容了,希望大家能够喜欢。
此为在原版2048的基础上,添加了电脑AI解题,并稍微修改了UI添加按钮来触发AI。 AI的核心在/js/myAI.js里,相关函数在window.myPlugin里 核心算法是用dfs搜3步后使代价函数window.myPlugin.evalCost期望值最小的走法, 代价函数的设计目的是让块尽量按由大到小顺序堆叠在右上角,并合并。 实验效果是基本能保证到2048,偶尔到4096甚至8192(概率较小)。