架构属于您自己的WebApp-2048游戏
来源:互联网 发布:如何解绑淘宝手机号码 编辑:程序博客网 时间:2024/06/06 07:44
我利用了周六,周日两天的时间,完完整整地写出一个2048的web游戏,其中所涉及的技术:Html+css+javascript。演示地址:
http://jyuan.sinaapp.com/games/2048/
首先,我们拿到这样一个任务,肯定是要玩一下2048这个游戏的。并不是单纯地玩,要想一下这个游戏的布局,思路等等 2048这个游戏是这样的:根据你的交互而进行下一步动作,这是什么意思呢?就是这个游戏的是否进行是根据你的按键来判断的,你所按的键分别是:上下左右。每一个格子移动的时候会做判断,例如向左移动:左边是没有数字的格子还是有数字的格子,这个数字是与当前移动的格子数字相等还是不相等,然后找到在哪个格子上显示对应的数,游戏的大概流程就是这样。
接着我们按照分析→设计→实现的思路:把我们的代码结构设计一下:首先我们需要一个index.html文件:里面存放着主页的布局:生成两个4*4的格子布局,第一个是没有数字的,宽高确定的能显示的;第二个是动态显示的,即是一开始不给它设置宽高,当用户移动的时候再动态显示出来。第二,需要一个样式表文件:2048.css。
接着重点是js文件,这里我们分为了三个不同功能的文件:①main2048.js:保存主体动作代码②shownumberAnimation.js:这个是包含数字出现和移动的动画代码
③support2048.js:这个是提供一些判断是否能够移动的代码。
接着,我们来看看代码的具体实现
index.html
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0,minimum-scale=1.0,user-scalable=no" /> <title>2048</title> <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="css/2048.css"/> <script type="text/javascript" src="js/shownumberAnimation.js"></script> <script type="text/javascript" src="js/support2048.js"></script> <script type="text/javascript" src="js/main2048.js"></script> </head> <body> <header><h1>2048</h1> <a href="javascript:newGame();" id="newGameButton">NewGame</a> <p>score:<span id="score">0</span></p> </header> <div id="grid-container"> <div class="grid-cell" id="grid-cell-0-0"></div> <div class="grid-cell" id="grid-cell-0-1"></div> <div class="grid-cell" id="grid-cell-0-2"></div> <div class="grid-cell" id="grid-cell-0-3"></div> <div class="grid-cell" id="grid-cell-1-0"></div> <div class="grid-cell" id="grid-cell-1-1"></div> <div class="grid-cell" id="grid-cell-1-2"></div> <div class="grid-cell" id="grid-cell-1-3"></div> <div class="grid-cell" id="grid-cell-2-0"></div> <div class="grid-cell" id="grid-cell-2-1"></div> <div class="grid-cell" id="grid-cell-2-2"></div> <div class="grid-cell" id="grid-cell-2-3"></div> <div class="grid-cell" id="grid-cell-3-0"></div> <div class="grid-cell" id="grid-cell-3-1"></div> <div class="grid-cell" id="grid-cell-3-2"></div> <div class="grid-cell" id="grid-cell-3-3"></div> </div> </body></html>
2048.css
header{ display: block; width: 100%; text-align: center; margin: 0 auto;}header h1{ font-family: "微软雅黑"; font-size: 40px; font-weight: bold;}header #newGameButton{ display: block; width:100px; margin: 20px auto; background-color: #c00; border-radius:10px; color: wheat; text-decoration: none; text-align: center;}header p{ text-align: center;}#grid-container{ width: 460px; height: 460px; padding: 20px; margin: 20px auto; border-radius:10px ; background-color:#bbada0 ; position: relative;}.grid-cell{ width: 100px; height: 100px; background-color: #ccc0b3; border-radius: 6px; position: absolute;}.number-cell{ position: absolute; text-align: center; border-radius:6px ; line-height: 100px; font-weight: bold; font-family:arial;}
main2048.js
var board=new Array();var score=0;var hasConflicted=new Array();var startx=0;var starty=0;var endx=0;var endy=0;$(document).ready(function(){ newGame(); //自适应 forMobile();});function newGame(){ //初始化布局 init(); //随机生成数字 generateOnenumber(); generateOnenumber(); score=0;}function forMobile(){ $('#grid-container').css('width',gridContainerWidth-2*cellSpace); $('#grid-container').css('height',gridContainerWidth-2*cellSpace); $('#grid-container').css('padding',cellSpace); $('#grid-container').css('border-radius',0.02*gridContainerWidth); $('.grid-cell').css('width',cellSideLength); $('.grid-cell').css('height',cellSideLength); $('.grid-cell').css('border-radius',0.02*cellSideLength);}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)); gridcell.css('left',getLeft(j)); } } for(i=0;i<4;i++){ board[i]=new Array(); hasConflicted[i]=new Array(); for(j=0;j<4;j++){ board[i][j]=0; hasConflicted[i][j]=false; } } updateboardView();}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 numbercell=$("#number-cell-"+i+"-"+j) if(board[i][j]==0){ numbercell.css("width",'0'); numbercell.css("height",'0'); numbercell.css("top",getTop(i)+cellSideLength/2); numbercell.css("left",getLeft(j)+cellSideLength/2); } else{ numbercell.css("width",cellSideLength); numbercell.css("height",cellSideLength); numbercell.css("top",getTop(i)); numbercell.css("left",getLeft(j)); numbercell.css("background-color",getNumberCellBgcolor(board[i][j])); numbercell.css("color",getNumberCellColor(board[i][j])); numbercell.text(rank(board[i][j])); } hasConflicted[i][j]=false; } $('.number-cell').css('line-height',cellSideLength+'px'); $('.number-cell').css('font-size',0.2*cellSideLength+'px');}function generateOnenumber(){ //首先判断有没有空间可用 if(nospace(board)){ return false; } //生成随机位置 var randomx=parseInt(Math.floor(Math.random()*4)); var randomy=parseInt(Math.floor(Math.random()*4)); var times=0; while(times<50){ if(board[randomx][randomy]==0) break; else{ randomx=parseInt(Math.floor(Math.random()*4)); randomy=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(board[i][j]==0){ randomx=i; randomy=j; } } } //生成随机数字 var randomnum=Math.random()<0.5?2:4; //在随机位置上显示随机数字 board[randomx][randomy]=randomnum; showNumberwithAnimation(randomx,randomy,randomnum); return true;}$(document).keydown(function(event){ switch(event.keyCode){ case 37: if(moveLeft()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); } break;//左按键 case 38: if(moveUp()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); }break;//上按键 case 39: if(moveRight()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); }break;//右按键 case 40: if(moveDown()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); }break;//下按键 }})//触控交互document.addEventListener('touchstart',function(event){ event.preventDefault(); startx=event.touches[0].pageX; starty=event.touches[0].pageY;});document.addEventListener('touchend',function(event){ event.preventDefault(); endx=event.changedTouches[0].pageX; endy=event.changedTouches[0].pageY; var deltax=endx-startx; var deltay=endy-starty; //判断方向 if(Math.abs(deltax)>=Math.abs(deltay)){ if(deltax>0){ //moveRight if(moveRight()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); } } else{ //moveLeft if(moveLeft()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); } } } else{ if(deltay>0){ //moveDown if(moveDown()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); } } else{ //moveUp if(moveUp()){ setTimeout('generateOnenumber()',210); setTimeout("isGameOver()",300); } }}});function isGameOver(){ if(nospace(board)&&nomove(board)){ alert("GameOver"); newGame(); }}function moveLeft(){ if(!canMoveLeft(board)) return false; //moveleft for(var i=0;i<4;i++){ for(var j=0;j<4;j++){ if(board[i][j]!=0){ for(var k=0;k<j;k++){ if(board[i][k]==0 &&noBlockHorizonta(i,k,j,board)){ //move showMoveAnimation(i,j,i,k); board[i][k]=board[i][j]; board[i][j]=0; continue; } else if(board[i][k]==board[i][j]&&noBlockHorizonta(i,k,j,board)&&!hasConflicted[i][k]){ //move board[i][k]+=board[i][j]; showMoveAnimation(i,j,i,k); board[i][j]=0; //add score+=board[i][k]; updatescore(score); hasConflicted[i][k]=true; continue; } } } } } setTimeout('updateboardView()',200); return true;}function moveUp(){ if(!canMoveUp(board)) return false; //moveup /*for(var i=1;i<4;i++){ for(var j=0;i<4;j++){ if(board[i][j]!=0){ for(var k=0;k<i;k++){ if(board[k][j]==0 &&noBlockVertical(i,j,k,board)){ //move showMoveAnimaiton(i,j,k,j); board[k][j]=board[i][j]; board[i][j]=0; continue; } else if(board[k][j]==board[i][j]&& noBlockVertical(i,j,k,board)){ //move showMoveAnimaiton(i,j,k,j); board[k][j]+=board[i][j]; board[i][j]=0; continue; } } } } } setTimeout('updateboardView()',200); return true;*/ //moveUp for( var j = 0 ; j < 4 ; j ++ ) for( var i = 1 ; i < 4 ; i ++ ){ if( board[i][j] != 0 ){ for( var k = 0 ; k < i ; k ++ ){ if( board[k][j] == 0 && noBlockVertical(j,k,i,board)){ //move showMoveAnimation(i,j,k,j); board[k][j] = board[i][j]; board[i][j] = 0; continue; } else if( board[k][j] == board[i][j] && noBlockVertical(j,k,i,board)&&!hasConflicted[k][j] ){ //move showMoveAnimation(i,j,k,j); //add board[k][j] += board[i][j]; board[i][j] = 0; score+=board[k][j]; updatescore(score); hasConflicted[k][j]=true; continue; } } } } setTimeout("updateboardView()",200); return true;}function moveRight(){ if(!canMoveRight(board)) return false; //moveright for(var i=0;i<4;i++){ for(var j=2;j>=0;j--){ if(board[i][j]!=0){ for(var k=3;k>j;k--){ if(board[i][k]==0 &&noBlockHorizonta(i,j,k,board)){ //move showMoveAnimation(i,j,i,k); board[i][k]=board[i][j]; board[i][j]=0; continue; } else if(board[i][k]==board[i][j]&&noBlockHorizonta(i,j,k,board)&& !hasConflicted[i][k]){ //move board[i][k]+=board[i][j]; showMoveAnimation(i,j,i,k); board[i][j]=0; score+=board[i][k]; updatescore(score); hasConflicted[i][k]=true; continue; } } } } } setTimeout('updateboardView()',200); return true;}function moveDown(){ if(!canMoveDown(board)) return false; //movedown for(var j=0;j<4;j++){ for(var i=2;i>=0;i--){ if(board[i][j]!=0){ for(var k=3;k>i;k--){ if(board[k][j]==0 &&noBlockVertical(j,i,k,board)){ //move showMoveAnimation(i,j,k,j); board[k][j]=board[i][j]; board[i][j]=0; continue; } else if(board[k][j]==board[i][j]&&noBlockVertical(j,i,k,board)&&!hasConflicted[k][j]){ //move showMoveAnimation(i,j,k,j); board[k][j]+=board[i][j]; board[i][j]=0; score+=board[k][j]; updatescore(score); hasConflicted[k][j]=true; continue; } } } } } setTimeout('updateboardView()',200); return true;}
shownumberAnimation.js
function showNumberwithAnimation(i,j,number){ var numbercell=$("#number-cell-"+i+"-"+j); numbercell.css("background-color",getNumberCellBgcolor(number)); numbercell.css("color",getNumberCellColor(number)); numbercell.text(rank(number)); numbercell.animate( { width:cellSideLength, height:cellSideLength, top:getTop(i), left:getLeft(j) },300);}function showMoveAnimation(fromi,fromj,tox,toy){ var numbercell=$("#number-cell-"+fromi+"-"+fromj); numbercell.animate( { top:getTop(tox), left:getLeft(toy) } ,200);}function updatescore(score){ $('#score').text(score);}
support2048.js
documentWidth=window.screen.availWidth;if(documentWidth>500){ gridContainerWidth=500; cellSideLength=100; cellSpace=20; }else{gridContainerWidth=0.92*documentWidth;cellSideLength=0.18*documentWidth;cellSpace=0.04*documentWidth;}function getTop(i){ return cellSpace+(cellSideLength+cellSpace)*i;}function getLeft(j){ return cellSpace+(cellSideLength+cellSpace)*j;}function getNumberCellBgcolor(number){ switch(number){ case 2: return '#EEE9BF';break; case 4:return '#EEC900';break; case 8:return '#EEE9BF';break; case 16:return '#EE3A8C';break; case 32:return '#EEE9BF';break; case 64:return '#CDAD00';break; case 128:return '#EE1289';break; case 256:return '#AEEEEE';break; case 512:return '#8B0000';break; } return "#EEE9BF";}function getNumberCellColor(number){ if(number==4){ return '#EE1289'; } return 'black';}function nospace(borad){ for(var i=0;i<4;i++){ for(var j=0;j<4;j++){ if(borad[i][j]==0) return false; } } return true;}function canMoveLeft(board){ for(var i=0;i<4;i++){ for(var j=1;j<=3;j++){ if(board[i][j-1]==0 ||(board[i][j-1]==board[i][j])){ return true; } } } return false;}function canMoveUp(board){ for(var i=1;i<4;i++){ for(var j=0;j<4;j++){ if(board[i-1][j]==0 ||(board[i-1][j] == board[i][j])){ return true; } } } return false;}function canMoveRight(board){ for(var i=0;i<4;i++){ for(var j=0;j<3;j++){ if(board[i][j+1]==0 ||(board[i][j+1]==board[i][j])){ return true; } } } return false;}function canMoveDown(board){ for(var i=0;i<=3;i++){ for(var j=0;j<3;j++){ if(board[j+1][i]==0 ||(board[j+1][i]==board[j][i])){ return true; } } } return false;}function noBlockHorizonta(row,col1,col2,board){ for(var i=col1+1;i<col2;i++) { if(board[row][i]!=0) return false; } return true;}function noBlockVertical(col,row1,row2,board){ for(var i=row1+1;i<row2;i++) { if(board[i][col]!=0) return false; } return true;}function nomove(board){ if(canMoveDown(board)||canMoveLeft(board)||canMoveRight(board)||canMoveUp(board)){ return false; } return true;}function rank(number){switch(number){ case 2: return '青铜';break; case 4:return '白银';break; case 8:return '黄金';break; case 16:return '白金';break; case 32:return '钻石';break; case 64:return '超凡大师';break; case 128:return '最强王者';break; } return "最强王者";}
其实最重要的是分析→设计→实现这三个步骤想明白了,就迎刃而解了。
本文作者: By:罗坚元 http://blog.csdn.net/sunyuan_software
- 架构属于您自己的WebApp-2048游戏
- 我写一个游戏,属于自己的游戏
- 如何用PhoneGap Build 在线搭建一个属于自己的webAPP
- 想做属于自己的三国类的游戏
- 如何设计属于自己的游戏服务器(一)
- 如何设计属于自己的游戏服务器(二)
- 做一款属于自己的体感游戏
- 属于自己的Blog
- 属于自己的Blog
- 属于自己的世界
- 属于自己的道路
- 属于我自己的总结——看楚云暮的《疯狂游戏》读后感
- 游戏编程之DirectX的修炼:二(创建属于自己的windows窗口程序:上)
- 游戏编程之DirectX的修炼:二(创建属于自己的windows窗口程序:下)
- 选择属于自己的ERP
- 寻找属于自己的香味
- 找到属于自己的路
- [导入]属于自己的历史
- ANSYS命令
- oralce无法删除用户ORA-01940 无法删除连接用户
- Python的简介、下载及安装
- 从源码带看Volley的缓存机制
- DMLC深盟分布式深度机器学习开源平台解析
- 架构属于您自己的WebApp-2048游戏
- xargs 命令
- 图的存储结构——邻接表
- 透过浏览器看HTTP缓存
- Linked List Cycle
- 【转】Linux read命令用法详解
- TCP/IP的三次握手与四次挥手
- 图的遍历——深度优先遍历——邻接矩阵
- 第十二周 【项目1 - 教师兼干部类】