前言:
一年来一直做得是后端的东西,没有写前端代码,忘干净了,之前也只用jQuery,好歹还能做点效果。想着捡起来一点,要不然枉费了师傅的栽培。
一直在看博客,但没有属于自己的东西。this has to change.
why not start now?俗话说只要代码敲得够快,悲伤就追不上我。
此篇开博,从简单小游戏开始。目的是做出一些可以快点看到效果的东西,捡回一点程序员的信心。
先看最终效果:
1. 2048游戏功能分析:
核心是4个方向的移动的处理。
往一个方向移动,先看是否有数字的合并。一次移动,一行只允许合并一次,且从终点往起点合并。
合并完成之后,将合并后的数字和其他数字移动,贴边。
在空白位置随机生成一个数字2,移动结束。
算法实现:
考虑采用二维数组存储4*4个格子中的值,如果移动,只需要更新数组,然后用数组的值来更新dom元素即可。
(这种想法不太面向对象。要是将每个格子都理解为一个对象,不知道好不好做,等以后研究--TODO)
2. 要用到的东西
2.1 html页面布局,4*4个方块得整出来
2.2 简单css:不同的数字设置不同颜色
2.3 简单dom操作:取元素,变换显示的数字,改变class
2.4 取随机数算法
2.5 按键事件监听
2.6 一点点交互操作考虑,比如判定游戏失败结束,成功结束,返回上一步。
3. 代码结构:
较为粗糙,js几乎全部是直接用html引用了,不会其他方式。先实现功能;
几个图片是:返回上一步按钮,上下左右按钮,重新开始按钮。
js区分:
arrayHelper是操作数组的;
domOperation顾文思意,操作dom;
eventListener,处理按键事件
common:页面初始化,随机数生成等
4. 核心代码
4.1 向方向【左】移动的逻辑
评论:写的比较死,一步一步,按照规则来即可
// 向一个方向移动,更新数组(左),其他方向也是一样的 function moveLeft(arrayCopy){ var gameSuccess = false; // 是否有合并或者移动,如果没有合并也没有移动,就是没有操作那就不要生成新的数字 var anyChange = false; // 每一行,从【左】往【右】对比是否有一样的数字(排除0)--并不需要挨着!中间隔了空气也可以合并 for (var i=0;i<4;i++){ var firstIndex = 0; var secondIndex = 1; while (secondIndex<4){ if (arrayCopy[i][firstIndex] == 0){ // 第一个是0,不可能有合并,往后移动 firstIndex++; secondIndex++; continue; } if (arrayCopy[i][secondIndex] == 0){ // 第二个是0,第二个继续往后找,第一个不变 secondIndex++; // 1. 后面找不到数字,一直往后找,结束循环 continue; } // 有一次一样的数字:计算得到和,放到第一个位置,这一行完了 else if (arrayCopy[i][firstIndex] == arrayCopy[i][secondIndex]){ arrayCopy[i][firstIndex] = arrayCopy[i][firstIndex] * 2; arrayCopy[i][secondIndex] = 0; anyChange = true; if (arrayCopy[i][firstIndex] >= 2048){ // 得到了2048,游戏结束 gameSuccess = true; } // 2. 后面找到数字,且可以合并,就合并,结束循环 break; } else{ // 3. 后面找到数字,但是不能合并,更新第一个数字为当前数字,第二个数字为下一个数字 firstIndex = secondIndex; secondIndex += 1; continue; } } } // 将每一行数字向【左】挪动 for (var i=0;i<4;i++){ var newLine = [];//临时存储从【左】到【右】的非0数字 var index = 0; for (var j=0;j<4;j++){ if (arrayCopy[i][j] != 0){ newLine[index] = arrayCopy[i][j]; index++; } } // 用临时存储的数字给数组更新 for (var m=0;m<index;m++){ if (arrayCopy[i][m] != newLine[m]){ anyChange = true; } arrayCopy[i][m] = newLine[m]; } // 剩余的位置给0 for (var n=index;n<4;n++){ if (arrayCopy[i][n] != 0){ anyChange = true; } arrayCopy[i][n] = 0; } } if (!anyChange){ console.log("no change after this move!"); if (!isEmptyCell(arrayCopy)){ // 本步不能移动,且没有剩余格子,且任意相邻格子没有相同的,就结束游戏 if (!canMerge(arrayCopy)){ console.log("Game Over! Try again."); return \'fail\'; } } if (gameSuccess){ return \'success\'; } // 没有移动 return \'unmoved\'; } // 给空闲位置设置数字2 if (isEmptyCell(arrayCopy)) { initOnePosition(arrayCopy); } if (gameSuccess){ return \'success\'; } return \'moved\'; }
4.2. 通用的移动处理。
因为往一个方向移动,和往其他方向移动处理是一样的,不可能复制以上代码4次吧。
换个方向看:往左移动和往右移动对数组的操作,只是行处理相反,列处理一样;
其他方向移动类似,不值得copy整个方法。
// 通用方法 // 所有移动都转换成一个方向上的移动:例如,都想象成向左移动,只需要倒转数组即可,完成移动再倒转回来! function move(direction){ if (flagSuccess){ if (confirm("You\'ve got your 2048! Start Another One?\n已经通关!开始新游戏?")){ gameRestart(); } return; } // 移动之前,记录上一步的内容,移动失败之后可以恢复 var lastStepUnchange = createNewArray(); updateFrontArray(lastStepUnchange,lastStepArray); // 将上一步状态设置为当前的 updateFrontArray(lastStepArray,arrayInit); // 将当前的去更新,更新失败则回滚上一步的状态 // 1. 数组倒转复制 var arrayCopy = new Array(); if (direction == \'left\'){ arrayCopy = copyArrayLeft(); }else if (direction == \'right\'){ arrayCopy = copyArrayRight(); }else if (direction == \'up\'){ arrayCopy = copyArrayUp(); }else if (direction == \'down\'){ arrayCopy = copyArrayDown(); } // 2. 都向一个方向移动 var moveResult = moveLeft(arrayCopy); if (\'fail\' == moveResult){ updateFrontArray(lastStepArray,lastStepUnchange); // 移动失败,没有任何改变 if (confirm(\'Game Over! Try again?\n游戏结束,再来一次?\')){ gameRestart(); return; }else{ // 最后一步了,允许回退 clickedLastStep = false; return; } return; } if (\'unmoved\' == moveResult){ return; } // 3. 从倒转的数组更新原数组 if (direction == \'left\'){ restoreArrayLeft(arrayCopy); }else if (direction == \'right\'){ restoreArrayRight(arrayCopy); }else if (direction == \'up\'){ restoreArrayUp(arrayCopy); }else if (direction == \'down\'){ restoreArrayDown(arrayCopy); } // 4. 根据数字更新页面元素 updatePageByArray(); updateColor(); if (\'success\' == moveResult){ // 因为操作DOM不是实时的,所以要等一段事件操作完成之后再弹出确认框 setTimeout(function(){ // 游戏通关,是否重新开始 if (confirm(\'Congragulations! Start Another Game?\n恭喜通关!是否再来一把?\')){ gameRestart(); }else{ flagSuccess = true; } },200); return; } // 移动完成 clickedLastStep = false; }
4.3 随机数的生成:
开始做的是生成一个随机数,16个位置的任意一个,如果这个位置已经有人了,就放弃,重新生成一个,直到找到空位为止。
但是到空位变少的时候,这样效率低下。
优化:只在空位中找随机位置。
// 生成随机数,转化成0-15的整数; function getRamdom(count) { // 0-1 var r0 = Math.random(); // 0-16 var r1 = r0 * count; // 只取整数位数的数 return Math.floor(r1); } // 改进:只在当前可用位置中随机找,不用找不可用的位置 function getOneEmptyCoordinate(array) { // 1. 得到当前数组 var countEmptyCells = 0; var mapIndex2Coordinate = {}; var coordinates = null; for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ if (array[i][j] == 0){ countEmptyCells++; coordinates = new Array(); coordinates.push(i); coordinates.push(j); mapIndex2Coordinate[countEmptyCells] = coordinates; } } } // 取可用位置的随机位置 var random = getRamdom(countEmptyCells); return mapIndex2Coordinate[random]; }
5. 欠缺:
5.1 布局,样式的调整比较嫌麻烦,瞎调的。
5.2 js代码关系--没什么关系,忘了前端是怎么组织的了;
5.3 刷新页面多次,可能出现从初始化异常,可能是文件加载顺序问题,初始化时dom操作比较慢等原因
5.4 看看别人实现思路如何
-- http://www.cnblogs.com/-lizi/p/8431030.html 这个写的很漂亮
6. 总结:
开发时间:5天下班时间,实际投入:15个小时左右。
代码规模:js400行;
7. 完整代码粘贴
index.html
<head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> </head> <link href="../css/common.css" rel="stylesheet"> <body> <script type="text/javascript" src="../js/common.js"></script> <script type="text/javascript" src="../js/eventListener.js"></script> <script type="text/javascript" src="../js/domOperation.js"></script> <div id="main"> <div id="refreshDiv" onclick="gameRestart()"> <span id="refreshButton"> <img src="../resource/refreshButton.png" alt="refresh" /> <a>重新开始</a> </span> </div> <div id="mainTable"> </div> <div id="explation"> <span> 2048游戏说明:<br> 按上下左右方向键可以移动有数字的方块,<br> 相邻的相同数字的方块往一个方向移动会合并成更大的数字。<br> 当最大数字出现2048时,游戏胜利!<br> 温馨提示:你可以使用空格键回退上一步。 </span> </div> <div id="rights"> <span> All rights reserved to S.C. Contact me at 857025773@qq.com. </span> </div> </div> <!-- 操作 --> <div id="keys"> <div> <span id="moveUpButton"onclick="move(\'up\')"> <img src="../resource/direction.png" alt="direction" /> </span> </div> <div> <span id="moveLeftButton"onclick="move(\'left\')"> <img src="../resource/direction.png" alt="direction" /> </span> <span id="moveBackButton" onclick="eventSpaceKey()"> <img src="../resource/moveBack.png" alt="moveBack" /> </span> <span id="moveRightButton"onclick="move(\'right\')"> <img src="../resource/direction.png" alt="direction" /> </span> </div> <div> <span id="moveDownButton"onclick="move(\'down\')"> <img src="../resource/direction.png" alt="direction" /> </span> </div> </div> <script type="text/javascript"> window.onload = function(){ pageInit(); } </script> </body>
common.css
#main
{
margin-left:500px;
margin-top:100px;
width:404px;
heignt:400px;
border: 0px solid gray;
border-radius: 1px;
}
#keys
{
margin-left:1150px;
margin-top:-430px;
width:303px;
heignt:300px;
border: 3px solid green;
border-radius: 20px;
}
#keys div
{
display:flex;
height:75px;
}
#keys div span
{
height:75px;
width:100px;
border: 1px solid gray;
background:blue;
}
#moveLeftButton img
{
height:75px;
width:100px;
-ms-transform:rotate(180deg); /* IE 9 */
-moz-transform:rotate(180deg); /* Firefox */
-webkit-transform:rotate(180deg); /* Safari and Chrome */
-o-transform:rotate(180deg); /* Opera */
}
#moveRightButton img
{
height:75px;
width:100px;
}
#moveUpButton
{
margin-left:100px;
}
#moveUpButton img
{
margin-top: -13px;
margin-left: 12px;
height:100px;
width:75px;
-ms-transform:rotate(270deg); /* IE 9 */
-moz-transform:rotate(270deg); /* Firefox */
-webkit-transform:rotate(270deg); /* Safari and Chrome */
-o-transform:rotate(270deg); /* Opera */
}
#moveDownButton
{
margin-left:100px;
}
#moveDownButton img
{
margin-left: 12px;
margin-top: -13px;
height:100px;
width:75px;
-ms-transform:rotate(90deg); /* IE 9 */
-moz-transform:rotate(90deg); /* Firefox */
-webkit-transform:rotate(90deg); /* Safari and Chrome */
-o-transform:rotate(90deg); /* Opera */
}
#moveBackButton
{
height:100px;
width:75px;
background:yellow !important;
}
#refreshDiv
{
height:40px;
width:133px;
margin-left:140px;
cursor: pointer;
background:#ba3537;
border-radius: 2px;
}
#refreshDiv span
{
display: contents;
font-family: \'微软雅黑\';
margin-left:159px;
font-size:20;
}
#refreshDiv span a
{
margin-bottom: 10px;
}
#explation
{
margin-top:30px;
}
#rights
{
margin-top:100px;
}
#rights span
{
font-size:10;
}
#explation span
{
font-size:14;
}
#mainTable
{
margin-top:20px;
background:#f5f5f5;
border: 2px solid #478dcd;
border-radius: 3px;
}
#mainTable div
{
display:flex;
width:400px;
heignt:100px;
}
#mainTable span
{
height:100px;
width:100px;
border: 1px solid gray;
font-size: 50;
text-align: center;
font-weight:bold;
}
.color0
{
background:#f5f5f5;
}
.color2
{
background:#f5c7ad;
}
.color4
{
background:#ec9362;
}
.color8
{
background:#e3631e;
}
.color16
{
background:#c2fcb1;
font-size: 45 !important;
}
.color32
{
background:#76f850;
font-size: 45 !important;
}
.color64
{
background:#2dad07;
font-size: 45 !important;
}
.color128
{
background:#a8a6f9;
font-size: 40 !important;
}
.color256
{
background:#4b47f1;
font-size: 40 !important;
}
.color512
{
background:#110da4;
font-size: 40 !important;
}
.color1024
{
background:#f799ef;
font-size: 35 !important;
}
.color2048
{
background:#a30e98;
font-size: 35 !important;
}
common.js
// 拼成了2048,冻结操作,不允许移动了 var flagSuccess = false; // 刚才点击了回退,不允许重复点击,要移动之后再点击 var clickedLastStep = false; // 记录上一步,用于回退 var lastStepArray = [ [0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0] ]; // 数组初始化--正常初始化 var arrayInit = [ [0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0] ]; //[//调试--将要success // [0,0,0,0], // [0,128,0,0], // [0,0,512,1024], // [0,0,0,1024] //]; //[//调试--将要fail // [1,2,3,4], // [5,128,6,7], // [8,9,512,1024], // [13,22,11,11] //]; // 页面加载初始化 function pageInit() { addHelper(); // initArray(); // 页面元素初始化(单元格) initElements(); // 初始数据 initTwoPositions(); // 根据初始数据给单元格填充值 updatePageByArray(); // 根据单元格的值给单元格设置样式 updateColor(); } // 重新开始 function gameRestart(){ initArray(); pageInit(); } function initArray(){ flagSuccess = false; arrayInit = createNewArray(); clickedLastStep = false; lastStepArray = createNewArray(); } // 给两个位置设置数字2 function initTwoPositions() { initOnePosition(arrayInit); initOnePosition(arrayInit); } // 给一个位置设置数字2 function initOnePosition(array){ // 取随机数方式1 // var num = getRamdom(16); // var line = Math.floor(num/4); // var col = num % 4; // var curNum = array[line][col]; // if (curNum == 0) // { // // 成功找到空闲位置 // array[line][col] = 2; // return true; // } // else{ // // 递归调用,必须找到一个可用位置才算完 // return initOnePosition(array); // } // 取随机数方式2 var coordinate = getOneEmptyCoordinate(array); array[coordinate[0]][coordinate[1]] = 2; } function isEmptyCell(arrayCopy) { for (var i=0;i<4;i++) { for (var j=0;j<4;j++) { if (arrayCopy[i][j] == 0) { return true; } } } return false; } // 生成随机数,转化成0-15的整数; function getRamdom(count) { // 0-1 var r0 = Math.random(); // 0-16 var r1 = r0 * count; // 只取整数位数的数 return Math.floor(r1); } // 改进:只在当前可用位置中随机找,不用找不可用的位置 function getOneEmptyCoordinate(array) { // 1. 得到当前数组 var countEmptyCells = 0; var mapIndex2Coordinate = {}; var coordinates = null; for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ if (array[i][j] == 0){ countEmptyCells++; coordinates = new Array(); coordinates.push(i); coordinates.push(j); mapIndex2Coordinate[countEmptyCells] = coordinates; } } } // 取可用位置的随机位置 var random = getRamdom(countEmptyCells); return mapIndex2Coordinate[random]; }
eventListener,js
/** * 引用工具类 */ function addHelper(){ var newscript = document.createElement(\'script\'); newscript.setAttribute(\'type\',\'text/javascript\'); newscript.setAttribute(\'src\',\'../js/arrayHelper.js\'); document.body.appendChild(newscript); } //捕捉按键事件 document.onkeyup = function(event) { event = event || window.event; if (event.keyCode == 37){//left move(\'left\'); }else if (event.keyCode == 39){//right move(\'right\'); }else if (event.keyCode == 38){//up move(\'up\'); }else if (event.keyCode == 40){//down move(\'down\'); }else if (event.keyCode == 32){//space eventSpaceKey(); } } function eventSpaceKey(){ // 回退上一步 if (clickedLastStep){ console.log(\'can not move back again\'); return; } moveBack(); flagSuccess = false; clickedLastStep = true; } // 回退上一步 function moveBack(){ // 判断上一步全是0(刚刚初始化) var justStarted = true; for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ if (lastStepArray[i][j] != 0){ justStarted = false; } } } if(justStarted){ return; } // 1. 用备份的数组给当前数组设置值 updateFrontArray(arrayInit,lastStepArray); // 3. 更新页面 updatePageByArray(); updateColor(); } // 通用方法 // 所有移动都转换成一个方向上的移动:例如,都想象成向左移动,只需要倒转数组即可,完成移动再倒转回来! function move(direction){ if (flagSuccess){ if (confirm("You\'ve got your 2048! Start Another One?\n已经通关!开始新游戏?")){ gameRestart(); } return; } // 移动之前,记录上一步的内容,移动失败之后可以恢复 var lastStepUnchange = createNewArray(); updateFrontArray(lastStepUnchange,lastStepArray); // 将上一步状态设置为当前的 updateFrontArray(lastStepArray,arrayInit); // 将当前的去更新,更新失败则回滚上一步的状态 // 1. 数组倒转复制 var arrayCopy = new Array(); if (direction == \'left\'){ arrayCopy = copyArrayLeft(); }else if (direction == \'right\'){ arrayCopy = copyArrayRight(); }else if (direction == \'up\'){ arrayCopy = copyArrayUp(); }else if (direction == \'down\'){ arrayCopy = copyArrayDown(); } // 2. 都向一个方向移动 var moveResult = moveLeft(arrayCopy); if (\'fail\' == moveResult){ updateFrontArray(lastStepArray,lastStepUnchange); // 移动失败,没有任何改变 if (confirm(\'Game Over! Try again?\n游戏结束,再来一次?\')){ gameRestart(); return; }else{ // 最后一步了,允许回退 clickedLastStep = false; return; } return; } if (\'unmoved\' == moveResult){ return; } // 3. 从倒转的数组更新原数组 if (direction == \'left\'){ restoreArrayLeft(arrayCopy); }else if (direction == \'right\'){ restoreArrayRight(arrayCopy); }else if (direction == \'up\'){ restoreArrayUp(arrayCopy); }else if (direction == \'down\'){ restoreArrayDown(arrayCopy); } // 4. 根据数字更新页面元素 updatePageByArray(); updateColor(); if (\'success\' == moveResult){ // 因为操作DOM不是实时的,所以要等一段事件操作完成之后再弹出确认框 setTimeout(function(){ // 游戏通关,是否重新开始 if (confirm(\'Congragulations! Start Another Game?\n恭喜通关!是否再来一把?\')){ gameRestart(); }else{ flagSuccess = true; } },200); return; } // 移动完成 clickedLastStep = false; } // 向一个方向移动,更新数组(左),其他方向也是一样的 function moveLeft(arrayCopy){ var gameSuccess = false; // 是否有合并或者移动,如果没有合并也没有移动,就是没有操作那就不要生成新的数字 var anyChange = false; // 每一行,从【左】往【右】对比是否有一样的数字(排除0)--并不需要挨着!中间隔了空气也可以合并 for (var i=0;i<4;i++){ var firstIndex = 0; var secondIndex = 1; while (secondIndex<4){ if (arrayCopy[i][firstIndex] == 0){ // 第一个是0,不可能有合并,往后移动 firstIndex++; secondIndex++; continue; } if (arrayCopy[i][secondIndex] == 0){ // 第二个是0,第二个继续往后找,第一个不变 secondIndex++; // 1. 后面找不到数字,一直往后找,结束循环 continue; } // 有一次一样的数字:计算得到和,放到第一个位置,这一行完了 else if (arrayCopy[i][firstIndex] == arrayCopy[i][secondIndex]){ arrayCopy[i][firstIndex] = arrayCopy[i][firstIndex] * 2; arrayCopy[i][secondIndex] = 0; anyChange = true; if (arrayCopy[i][firstIndex] >= 2048){ // 得到了2048,游戏结束 gameSuccess = true; } // 2. 后面找到数字,且可以合并,就合并,结束循环 break; } else{ // 3. 后面找到数字,但是不能合并,更新第一个数字为当前数字,第二个数字为下一个数字 firstIndex = secondIndex; secondIndex += 1; continue; } } } // 将每一行数字向【左】挪动 for (var i=0;i<4;i++){ var newLine = [];//临时存储从【左】到【右】的非0数字 var index = 0; for (var j=0;j<4;j++){ if (arrayCopy[i][j] != 0){ newLine[index] = arrayCopy[i][j]; index++; } } // 用临时存储的数字给数组更新 for (var m=0;m<index;m++){ if (arrayCopy[i][m] != newLine[m]){ anyChange = true; } arrayCopy[i][m] = newLine[m]; } // 剩余的位置给0 for (var n=index;n<4;n++){ if (arrayCopy[i][n] != 0){ anyChange = true; } arrayCopy[i][n] = 0; } } if (!anyChange){ console.log("no change after this move!"); if (!isEmptyCell(arrayCopy)){ // 本步不能移动,且没有剩余格子,且任意相邻格子没有相同的,就结束游戏 if (!canMerge(arrayCopy)){ console.log("Game Over! Try again."); return \'fail\'; } } if (gameSuccess){ return \'success\'; } // 没有移动 return \'unmoved\'; } // 给空闲位置设置数字2 if (isEmptyCell(arrayCopy)) { initOnePosition(arrayCopy); } if (gameSuccess){ return \'success\'; } return \'moved\'; } // 是否有任意相邻的格子可以合并 function canMerge(arrayCopy){ for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ if (j+1 < 4&& arrayCopy[i][j] == arrayCopy[i][j+1]){ return true; } if (i+1 < 4 && arrayCopy[i][j] == arrayCopy[i+1][j]){ return true; } } } return false; }
arrayHelper.js
function createNewArray(){ var newArray = [ [0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0] ]; return newArray; } // 后面的复制给前面 function updateFrontArray(arr1,arr2) { for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ arr1[i][j] = arr2[i][j]; } } } function copyArray(arr){ var newArray = createNewArray(); updateFrontArray(newArray,arr); return newArray; } //左,原方向 function copyArrayLeft(){ var arrayCopy = copyArray(arrayInit); return arrayCopy; } function restoreArrayLeft(arrayCopy){ updateFrontArray(arrayInit,arrayCopy); } //右,上下不变,左右颠倒 function copyArrayRight(){ var arrayCopy = new Array(); for (var i=0;i<4;i++){ var copyOneLine = new Array(); for (var j=0;j<4;j++){ copyOneLine[3-j] = arrayInit[i][j]; } arrayCopy[i] = copyOneLine; } return arrayCopy; } function restoreArrayRight(arrayCopy){ for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ arrayInit[i][j] = arrayCopy[i][3-j]; } } } //上 //从上往下变成从左往右 //从右往左变成从上往下 //(i,j) 对应:(3-j,i) function copyArrayUp(){ var arrayCopy = [ [0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0] ]; for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ arrayCopy[3-j][i] = arrayInit[i][j]; } } return arrayCopy; } function restoreArrayUp(arrayCopy){ for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ arrayInit[i][j] = arrayCopy[3-j][i]; } } } //下 //从上往下变成从下往上 //从左往右变成从左往右 //(i,j) 对应:(j,3-i) function copyArrayDown(){ var arrayCopy = [ [0,0,0,0], [0,0,0,0], [0,0,0,0], [0,0,0,0] ]; for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ arrayCopy[j][3-i] = arrayInit[i][j]; } } return arrayCopy; } function restoreArrayDown(arrayCopy){ for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ arrayInit[i][j] = arrayCopy[j][3-i]; } } }
domOperation.js
// 用数组给元素赋值 function updatePageByArray() { var lines = document.getElementById("mainTable").children; var lineIndex = 0; while (lineIndex < lines.length) { var spanIndex = 0; while (spanIndex < lines[lineIndex].children.length) { var oneSpan = lines[lineIndex].children[spanIndex]; oneSpan.innerHTML = arrayInit[lineIndex][spanIndex]; spanIndex++; } lineIndex++; } } // 初始化单元格和颜色 function initElements() { var mainTable = document.getElementById("mainTable"); var str = \'\'; // 创建行 for (var i=0;i<4;i++) { str += "<div id=\'" +"line"+i+"\'>"; for (var j=0;j<4;j++) { var num = arrayInit[i][j]; str += "<span id=\'" +"span"+i+j+"\'>" + num+ "</span>"; } str += "</div>"; mainTable.innerHTML = str; } } // 根据ID更新颜色 function updateColor(){ for (var i=0;i<4;i++){ for (var j=0;j<4;j++){ var span = document.getElementById("span"+i+j); var value = span.innerHTML; if (value == \'0\'){ span.innerHTML = \'\'; } span.className = (" color" + value); } } }