Web APP-2048游戏.doc
实 习 设 计(论文)题目名称 Web APP-2048游戏 学生学部(系) 机电与信息工程学部 专业班级 学 号 学生姓名 指导老师 2015 年 01 月 25 日目 录1概念 1.1游戏背景-1 1.2游戏开发-1 1.3论文内容安排-12 功能设计2.1界面设计-2 2.2游戏架构-4 2.3游戏设计-4 3 结果展示 3.1游戏开始界面-11 3.2游戏结束界面-134 结论 4.1结论心得-145 参考文献 5参考文献-141 概述1.1 游戏背景2048的祖先是一款名为Threes(中文名为小3传奇)的手游。小3传奇的两位开发者花了近一年半时间才开发出这个游戏的核心玩法,却在其上架App store后仅21天就被1024抄了过去。最让人意想不到的是,2048则更为迅速,19岁的Gabriele Cirulli只用了一个星期改编前两者游戏,却获得最大的成功,Threes却不被人知。而到了现在,这类游戏从发布到现在,不管是App Store还是Android市场,下载量已经远远超越了千万,网上各种版本的都有,比如朝代版,后宫版,甲乙丙版,生肖版等。1.2 游戏开发由于本人十分喜欢2048这款手游,所以我就想在电脑的浏览器也能玩这款游戏,在此次课程论文的制作过程中,我将运用我学习到的知识以及javascript和jQuery知识通过网上现有的资料尝试完成此次课程的开发,让这款游戏同时支持电脑浏览器和手机浏览器。1.3论文内容安排要开发这一款游戏,要根据以下几步来完成:1) 首先是要对这款游戏的代码分析。对整一个游戏,要将各个部位分割成其对应部位的功能代码,并且逐一去分析实现其中不同的功能。2) 其次是游戏的流程。在做好每一个部分的代码之后,就需要把所创造的各个关键部分拼接起来,因此,就需要先把该游戏的流程一步一步的弄清楚。3) 再者是对2048这一款游戏的算法分析。对于整个游戏而言,最主要的心脏就是这一款游戏的算法。2048这一款游戏的算法分为上下左右自个方向的。4) 2048中每个格子的数据和颜色的刷新。在每一次移动之后,几乎在这4*4的每一个方格上的数据都会变化,因此在每一次移动之后,每一个方格上的数据都要刷新一次。相对的,每一个数的背景颜色是不同的,也就是说,在每一次数据刷新的时候,每一个方格上的颜色也要同样的刷新一次。5) 最后是可不可以继续游戏的检测。当屏幕上没有没有写有数据的方格并且屏幕上的数据没有哪两个相邻的数据是一样的两个数,那么就判定为游戏结束。2 功能设计2.1 设计界面在设计整个2048游戏之前先得设计一个2048的游戏界面,有了游戏界面,才能够进行2048这一款游戏的下一步设计,这是创建2048小游戏的最基础的步骤。2048这一款游戏的界面是4*4方格的,于是就需要在界面上设置4*4的方格,有了这些方格之后才能在方格上面装数字,然后才能继续游戏。main.js部分代码:function newGame()init();/初始化棋盘function init()for (var i = 0; i < 4; i+) for (var j = 0; j < 4;j+) var gridCell=$("#grid_cell_"+i+"_"+j);gridCell.css('top',getTop(i,j);gridCell.css('left',getLeft(i,j);support.js部分代码:function getTop(i, j) var top = cellSpace + i *( cellSpace + cellSideLength ); return top;function getLeft(i, j) return cellSpace + j *( cellSpace + cellSideLength );2.2 游戏架构2.3 游戏设计游戏逻辑定义board数组,调用updateBoardView();函数根据变量board的值对NumberCell元素进行操作,动态的把NumberCell元素添加到index.html中。function updateBoardView()$(".number_cell").remove();for (var i = 0; i < 4; i+) for (var j = 0; j <4; j+)$("#grid_Container").append('<div class="number_cell" id="number_cell_'+i+'_'+j+'"></div>');var theNumberCell=$('#number_cell_'+i+'_'+j+'');if (boardij=0) theNumberCell.css('width', '0px');theNumberCell.css('height', '0px');theNumberCell.css('left', getLeft(i,j)+cellSideLength/2);theNumberCell.css('top', getTop(i,j)+cellSideLength/2);elsetheNumberCell.css('width', cellSideLength);theNumberCell.css('height', cellSideLength);theNumberCell.css('top',getTop(i,j);theNumberCell.css('left',getLeft(i,j);theNumberCell.css('color',getNumberColol(boardij);theNumberCell.css('background-color',getBackgroundColor(boardij); theNumberCell.text(boardij)hasConflictedij=false;$('.number_cell').css('line-height',cellSideLength+'px')$('.number_cell').css('font-size',0.6*cellSideLength+'px')$('.number_cell').css('border-radius',0.1*cellSideLength);/获取数字的背景颜色function getBackgroundColor(number) switch (number) case 2: return "#eee4da"break; case 4: return "#ede0c8"break; case 8: return "#f2b179"break; case 16: return "#f59563"break; case 32: return "#f67c5f"break; case 64: return "#f65e3b"break; case 128: return "#edcf72"break; case 256: return "#edcc61"break; case 512: return "#9c0"break; case 1024: return "#33b5e5"break; case 2048: return "#09c"break; case 4096: return "#a6c"break; case 8192: return "#93c"break; return "black"function getNumberColol(number) if (number <= 4) return "#776e65" ; return "white"页面初始化定义函数generateOneNumber();在16个格子中随机找一个格子生成一个数字function generateOneNumber() if (nospace(board) return false; /取随机位置var randx=parseInt(Math.floor(Math.random()*4);var randy=parseInt(Math.floor(Math.random()*4);var times=0;while(times<50)if(boardrandxrandy=0)break;var randx=parseInt(Math.floor(Math.random()*4);var randy=parseInt(Math.floor(Math.random()*4);times+;if (times=50) for(var i=0;i<4;i+)for(var j=0;j<4;j+)if (boardij=0) randx=i;randy=j;var randomNum= parseInt(Math.floor(Math.random()*4) +1;if (randomNum=3) randomNum=4else if (randomNum=1) randomNum=2;/在随机位置显示随机数字boardrandxrandy=randomNum;showNumberAnimate(randx,randy,randomNum);return true;生成随机数的动画动画效果利用jQuery的animate函数完成function showNumberAnimate(i,j,randomNum)var numberCell=$('#number_cell_'+i+'_'+j+'');numberCell.css('color', getNumberColol(randomNum);numberCell.css('background-color',getBackgroundColor(randomNum);numberCell.text(randomNum);numberCell.animate(width:cellSideLength,height:cellSideLength,top:getTop(i,j),left:getLeft(i,j),122)游戏的循环/玩家按下按键之后的操作$(document).keydown(function(event) switch(event.keyCode) case (37):if(moveLeft()setTimeout('generateOneNumber()',130);elsesetTimeout('isGameOver()',170);/leftbreak;case 38:if(moveUp()setTimeout('generateOneNumber()',130);/ generateOneNumber();event.preventDefault();elsesetTimeout('isGameOver()',170); /upbreak;case 39:if(moveRight()setTimeout('generateOneNumber()',130);elsesetTimeout('isGameOver()',170); /rightbreak;case 40:if(moveDown()setTimeout('generateOneNumber()',130);event.preventDefault();elsesetTimeout('isGameOver()',170); /downbreak;default:break;)交互细节/判断向左右移动时是否有阻挡function noBlockHorizontal(row,col1,col2,board) for(var i=col1+1;i<col2;i+) if (boardrowi!=0) return false; ; return true/判断向上向下移动时是否有阻挡function noBlockVertical(col,row1,row2,board) for(var i=row1+1;i<row2;i+) if (boardicol!=0) return false; ; return true支持移动端/前端支持:屏幕自适应<meta name="viewport" content="width=device-width, height =device-height,initial-scale = 1.0 , minimum-scale = 1.0 ,maximum-scale = 1.0 ,user-scalable = no" />/支持移动端$(document).ready(function()forMobile();newGame();)function forMobile()if (documentWidth>500) grid_ContainerWidth=500;cellSideLength=100;cellSpace=20;$("#grid_Container").css('width',grid_ContainerWidth-2*cellSpace);$("#grid_Container").css('height',grid_ContainerWidth-2*cellSpace);$('#grid_Container').css('padding',cellSpace);$('#grid_Container').css('border-radius',0.02*grid_ContainerWidth);$('.cell').css('width',cellSideLength);$('.cell').css('height',cellSideLength);$('.cell').css('border-radius',0.1*cellSideLength);$('.top').css('width',grid_ContainerWidth);$('#newGame_btn').css('padding',0.13*cellSideLength+'px'+' 0px')/触碰屏幕进行游戏document.addEventListener('touchstart',function(event)startX=event.touches0.pageX;startY=event.touches0.pageY;);document.addEventListener('touchend',function(event)endX=event.changedTouches0.pageX;endY=event.changedTouches0.pageY;var moveX=endX - startX;var moveY=endY - startY;if (Math.abs(moveX)<0.13*documentWidth&&Math.abs(moveY)<0.13*documentWidth) return;if(Math.abs(moveX)>=Math.abs(moveY)/xif(moveX>0)/move rightif(moveRight()setTimeout('generateOneNumber()',130);elsesetTimeout('isGameOver()',170);else/move leftif(moveLeft()setTimeout('generateOneNumber()',130);elsesetTimeout('isGameOver()',170);else/yif(moveY>0)/move downevent.preventDefault();if(moveDown()setTimeout('generateOneNumber()',130);event.preventDefault();elsesetTimeout('isGameOver()',170);else/move upevent.preventDefault();if(moveUp()setTimeout('generateOneNumber()',130);/ generateOneNumber();event.preventDefault();elsesetTimeout('isGameOver()',170););/判断游戏是否结束function isGameOver()if (nospace(board)&&noMove(board) gameOver();3 结果展示3.1 游戏开始界面电脑端利用谷歌浏览器的开发者工具模拟iPhone4进行游戏3.2 游戏结束界面游戏结束,提示是否再试一次,调用confirm,点击确定则进入新的游戏function gameOver()var result = confirm('Try Again?');if(result = true)newGame();4 结论经过了几天的努力终于把2048这个游戏完成了,想当初看这个游戏玩法简单又内容简单,没想到制作起来是这样“浩大”的一个工程。在这短短的几天时间里,参考了许多的相关资料,有时候感觉很辛苦不想再做下去了,但是又想试试看挑战一下自己的能力能不能完成这样一个任务,于是又在网上找到了不少对我很有帮助的材料、视频,为了自己的目标就这样一点一点地去完成这个项目。这几天里让我学习到了制作小游戏的基本步骤,首先要创建一个页面,然后再对页面进行相应的设置,再者要对对象进行设置,最后要使游戏能够听我们的指挥我们要插入一个事件监听,而且其中还需要结合各种算法才能实现这样的一个小小的小游戏,真是“麻雀虽小,五脏俱全”。最终运行出来的结果因为本人能力实在有限,所以有很多东西还是有缺陷,这让我意识到自身能力的不足,还有许许多多的知识等待着我去了解、去学习。虽然如此,但是看着最终运行出来的结果,还是给了我很大的鼓舞和安慰,这一次制作2048小游戏的经验让我受益匪浅,感受到了这个项目是我要正真用心认认真真完成的一件事,这真是一个难得的学习的过程。5 参考文献: 1 达内科技.JavaScript学员用书.达内集团教学研发部.2014.12 杨涛/王建桥/杨晓云. JavaScript DOM编程艺术. 人民邮电出版社. 2006.123 (美国)BearBibeault (美国)YehudaKatz. jQuery实战.人民邮电出版社.2009.14 丁琛/赵泽欣. 高性能JavaScript. 电子工业出版社.2010.115 (美)Eric A.Meyer. CSS权威指南. 东南大学出版社.2007.616