纯JS写的2048游戏,分享之
这几天玩儿着2048这个游戏,突然心血来潮想练习下敲代码的思路。于是乎就模仿做了一个,到眼下位置还没有实现动态移动,不是非常好看,只是玩儿着自己模仿的小游戏还是蛮爽的,哈哈
里边好多步骤写得不够简单介绍明了。欢迎指正
假设没有玩儿过这个游戏,最好先试玩儿下,这样看起下边的代码来easy些
用的是event。临时不支持firefox下玩儿。。。
试玩儿>>里边好多步骤写得不够简单介绍明了。欢迎指正
两个小时构思,主要构思用什么形式存表格,以及当中用到的几个比較关键的方法,比方:是否须要移动,是否须要合并,移动方法。合并方法等,然后開始编程的时候会遇到非常多问题,慢慢解决之
<html> <head> <title>2048</title> <meta http-equiv='content-type' content='text/html;charset=gb2312' /> <style type="text/css"> body,div,ul,li,p{padding:0;margin:0;border-radius:10px;} body{ font-family:"Microsoft YaHei",微软雅黑,Arial,Simsun,sans-serif; background:#FFFCEC; } .game_box{ margin:20px auto; width:400px; } .info{ height:60px; color:#333; font-size:32px; } .main_box{ border:2px solid #8E8E8E; background-color:#8E8E8E; height:396px; color:#333; font-size:36px; font-weight:700; text-align:center; line-height:100px; } .main_box li{ float:left; background:#d0d0d0; border:4px solid #8E8E8E; height:91px; width:91px; } .rule{ color:#333; font-size:16px; } </style> </head> <body onload="init();" onkeyup="run();"> <div class="game_box"> <div class="info"> <p style="float:right;">得分:<span id="score">0</span></p> 最大值:<span id="max_value">0</span> </div> <ul class="main_box"> <li id="11"></li> <li id="12"></li> <li id="13"></li> <li id="14"></li> <li id="21"></li> <li id="22"></li> <li id="23"></li> <li id="24"></li> <li id="31"></li> <li id="32"></li> <li id="33"></li> <li id="34"></li> <li id="41"></li> <li id="42"></li> <li id="43"></li> <li id="44"></li> </ul> <div style="clear:both;"></div> <p class="rule">玩法:</p> <p class="rule">1.用键盘上下左右键控制数字走向</p> <p class="rule">2.当点击了一个方向时,格子中的数字会所有往那个方向移动。直到不能再移动,假设有同样的数字则会合并</p> <p class="rule">3.当格子中不再有可移动和可合并的数字时,游戏结束</p> </div> </body> <script type="text/javascript"> var table = { 11:0,12:0,13:0,14:0, 21:0,22:0,23:0,24:0, 31:0,32:0,33:0,34:0, 41:0,42:0,43:0,44:0 };//整个表格 var cur_queue = null;//因为移动时是一行或一列移动的,此变量代表须要处理的当前行和列 var direction = 0;//当前操作移动的方向 var max_value = 0;//最大值 var score = 0;//最高分数 function is_num_exist() {//推断当前处理行(列)是否有数字。有则进行处理。无则不用处理 return table[cur_queue[1]]||table[cur_queue[2]]||table[cur_queue[3]]||table[cur_queue[4]]; } function need_move() {//当前行(列)是否须要移动(不包含合并) if(Boolean(table[cur_queue[4]])>=Boolean(table[cur_queue[3]])&&Boolean(table[cur_queue[3]])>=Boolean(table[cur_queue[2]])&&Boolean(table[cur_queue[2]])>=Boolean(table[cur_queue[1]])) { return false; }else { return true; } } function need_merge() {//当前行(列)是否须要合并 if((table[cur_queue[4]]==table[cur_queue[3]])&&table[cur_queue[4]]&&table[cur_queue[3]]||(table[cur_queue[3]]==table[cur_queue[2]])&&table[cur_queue[3]]&&table[cur_queue[2]]||(table[cur_queue[2]]==table[cur_queue[1]])&&table[cur_queue[2]]&&table[cur_queue[1]]) { return true; }else { return false; } } function move() {//对当前行(列)的数字进行移动 for(var i=4;i>=2;i--) { if(Boolean(table[cur_queue[i]]<Boolean(table[cur_queue[i-1]]))) { table[cur_queue[i]] = table[cur_queue[i-1]]; table[cur_queue[i-1]] = 0; break; } } } function merge() {//对当前行(列)的数字进行合并 for(var i=4;i>=2;i--) { if(table[cur_queue[i]]==table[cur_queue[i-1]]) { score=score+table[cur_queue[i]]; table[cur_queue[i]] = table[cur_queue[i]]+table[cur_queue[i-1]]; table[cur_queue[i-1]] = 0; document.getElementById("score").innerHTML=score;//更新最高分 break; } } } function run() {//点击上下左右键时開始运行 var done = false; if(event.keyCode>=37&&event.keyCode<=40) {//仅仅有 set_direction();//设置移动方向參数 for(var i=1;i<=4;i++) {//因为一个方向上移动时有4行(列)所以须要逐行处理 set_cur_queue(i);//设置当前行(列) if(is_num_exist()) { if(need_move()||need_merge()) { done = true;//此变量用来限制每次仅仅合并一次 } while(need_move()) {//假设能够移动则一直移动 move(); } if(need_merge()) {//假设须要合并 if(table[cur_queue[1]]==table[cur_queue[2]]&&table[cur_queue[3]]==table[cur_queue[4]]) {//特例,当一行(列)上四个数字所有同样时候,进行两次合并 merge(); while(need_move()) { move(); } merge(); }else { merge(); while(need_move()) { move(); } } } } } //var empty_box = find_empty_box();//获取当前空格子集合 //if(empty_box.length==0&&!need_merge()) {//假设没有没有空位且不能合并 // alert('Game over'); // return; //} if(done) {//假设此次有移动或合并,即有效操作,则生成新的数字 create_and_set_num(); } update_max_value();//更新最大值 draw();//又一次绘制表格用于显示 } } function update_max_value() { max_value = Math.max(table[11],table[12],table[13],table[14],table[21],table[22],table[23],table[24],table[31],table[32],table[33],table[34],table[41],table[42],table[43],table[44]); document.getElementById("max_value").innerHTML=max_value; } function set_cur_queue(queue_num) { if(direction == 37) { cur_queue = {1:queue_num*10+4,2:queue_num*10+3,3:queue_num*10+2,4:queue_num*10+1}; }else if(direction == 38) { cur_queue = {1:40+queue_num,2:30+queue_num,3:20+queue_num,4:10+queue_num}; }else if(direction == 39) { cur_queue = {1:queue_num*10+1,2:queue_num*10+2,3:queue_num*10+3,4:queue_num*10+4}; }else if(direction == 40) { cur_queue = {1:10+queue_num,2:20+queue_num,3:30+queue_num,4:40+queue_num}; }else { cur_queue = {1:queue_num*10+1,2:queue_num*10+2,3:queue_num*10+3,4:queue_num*10+4}; } } function draw() {//总体刷新16个格子 for(var i=10;i<=40;i+=10) { for(var j=1;j<=4;j++) { if(table[i+j]!=0) { document.getElementById(i+j).innerHTML=table[i+j]; }else { document.getElementById(i+j).innerHTML=''; } } } } function set_direction() {//设置此次移动的方向 direction = event.keyCode; } function set_new_num(empty_box) {//生成新的数字 var num = 0; var ranNum = Math.random()*100; if(ranNum>80) { num = 4; }else { num = 2; } var box_num = Math.floor(Math.random()*(empty_box.length)); table[empty_box[box_num]] = num; } function find_empty_box() {//获得所有的空格子。即值为0的格子集合 var empty_box = []; for(var num in table) { if(table[num]==0) { empty_box.push(num); } } return empty_box; } function init() { create_and_set_num(); for(var i=1;i<=4;i++) { set_cur_queue(i); draw(); } update_max_value(); } function create_and_set_num() { var empty_box; empty_box = find_empty_box(); set_new_num(empty_box); } </script> </html>