模仿了下html5游戏_2048
可以PC上用键盘玩
手机上用手势玩
应该是内存管理存在问题,虽然在UC上速度可以,但在默认浏览器下时间一长就卡,代码仅供参考
效果图:
代码:
index.htm:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <meta name="description" content="An HTML5 canvas game."> 6 <meta name="keywords" content="html5, canvas, web, game"> 7 <meta name="author" content="Wang Xin Sheng"> 8 <meta name="apple-mobile-web-app-capable" content="yes"> 9 <meta name="apple-mobile-web-app-status-bar-style" content="black"> 10 <meta name="viewport" id="viewport" content="width = device-width, initial-scale = 1, minimum-scale = 1, maximum-scale = 1, user-scalable=no"> 11 <meta http-equiv="X-UA-Compatible" content="chrome=1"> 12 <meta http-equiv="Pragma" content="no-cache"> 13 <meta http-equiv="Cache-Control" content="no-cache"> 14 <meta equiv="Expires" content="0"> 15 <meta http-equiv="content-script-type" content="text/javascript"> 16 <title>[WXS]2048</title> 17 <!--<script src="requestNextAnimationFrame.js"></script>--> 18 <style type="text/css"> 19 html {color:#000;background:#222;margin:0px;} 20 body {-webkit-user-select:none;margin:0px;} 21 #BirdWorld{cursor:pointer;background:#fff;/*border:6px #333333 solid;*/} 22 #btn_start{color:white;font-size:38px;font-weight:bold;z-index:999;display:none;background:rgba(150,150,150,0.8);text-align:center;cursor:pointer;} 23 </style> 24 </head> 25 <body> 26 <section> 27 <div style='position:absolute;left:0px;top:0px;' id='btn_start'></div> 28 <canvas id="GameWorld" width="900" height="400" style="position: absolute; left: 0px; top: 0px;"> 29 <p>You need a <a href="http://www.google.com/chrome">modern browser</a> to view this.</p> 30 </canvas> 31 </section> 32 </body> 33 <script src="CGM009.js"></script> 34 </html>
CGM009.js
1 ; 2 var gameWorld = new function(){ 3 function doResize(){ 4 caW = window.innerWidth; 5 caH = window.innerHeight; 6 btn_start.style.width=caW+"px"; 7 btn_start.style.height=caH+"px"; 8 btn_start.style.display="inline"; 9 btn_start.innerHTML = "<div style='margin:auto; position:absolute;100%;text-align:center; top:"+caH * 0.4 +"px'>由WangXinsheng创建<br />点击屏幕开始游戏</div>"; 10 caObj.width = caW; 11 caObj.height = caH; 12 scoreTotal = 0; 13 scoreShow = "滑动屏幕开始游戏"; 14 if(caH>caW){ 15 cellW = Math.ceil(caW * 0.25); 16 cellH = cellW; 17 cellBL = Math.ceil((caW - cellW * 4) * 0.5); 18 cellBT = Math.ceil((caH - cellW * 4) * 0.5); 19 wordT = cellBT * 0.5; 20 wordL = caW * 0.5; 21 }else{ 22 cellW = Math.ceil(caH * 0.25); 23 cellH = cellW; 24 cellBL = Math.ceil((caW - cellW * 4) * 0.5); 25 cellBT = Math.ceil((caH - cellW * 4) * 0.5); 26 wordT = caH * 0.5; 27 wordL = cellBL * 0.5; 28 } 29 } 30 function doTouchStart(e){ 31 e.preventDefault(); 32 //console.log("ts",e); 33 pageXs = e.changedTouches[0].pageX; 34 pageYs = e.changedTouches[0].pageY; 35 e.stopPropagation(); 36 } 37 function doTouchEnd(e){ 38 e.preventDefault(); 39 //console.log("te",e); 40 pageXe = e.changedTouches[0].pageX; 41 pageYe = e.changedTouches[0].pageY; 42 var offsetX = pageXe - pageXs; 43 var offsetY = pageYe - pageYs; 44 var parm = ""; 45 //console.log(pageXe,pageYe,pageXs,pageYs,offsetX,offsetY); 46 if(Math.abs(offsetX)==Math.abs(offsetY)){ 47 //45度,不予理睬 48 }else if(Math.abs(offsetX)>Math.abs(offsetY)){ 49 if(offsetX>0){ 50 parm="right"; 51 }else{ 52 parm="left"; 53 } 54 }else{ 55 if(offsetY<0){ 56 parm="up"; 57 }else{ 58 parm="down"; 59 } 60 } 61 //console.log(parm); 62 if(parm!="") 63 doMove(parm); 64 e.stopPropagation(); 65 } 66 function stopEvent(e){e.preventDefault();e.stopPropagation();} 67 function BindEvent(){ 68 btn_start.addEventListener("click", 69 function(){ 70 btn_start.style.display="none"; 71 if(scoreShow == "你输了!") 72 reStart(); 73 }, false); 74 if(v){ 75 caObj.addEventListener("touchstart", doTouchStart, false); 76 caObj.addEventListener("touchend", doTouchEnd, false); 77 78 caObj.addEventListener("touchmove", stopEvent, false); 79 caObj.addEventListener("touchcancel", stopEvent, false); 80 caObj.addEventListener("gesturestart", stopEvent, false); 81 caObj.addEventListener("gesturechange", stopEvent, false); 82 caObj.addEventListener("gestureend", stopEvent, false); 83 }else{ 84 document.addEventListener("keyup", doKeyPress, false); 85 } 86 } 87 function doKeyPress(e){ 88 if(window.event) // IE 89 { 90 keynum = e.keyCode 91 } 92 else if(e.which) // Netscape/Firefox/Opera 93 { 94 keynum = e.which 95 } 96 switch(keynum){ 97 case 38: 98 doMove("up"); 99 break; 100 case 40: 101 doMove("down"); 102 break; 103 case 37: 104 doMove("left"); 105 break; 106 case 39: 107 doMove("right"); 108 break; 109 } 110 } 111 function doMove(direction){ 112 //up down left right 113 var scoreToAdd = 0; 114 115 for(var i=0;i<cells.length;i++){ 116 for(var j=0;j<cells[i].length;j++){ 117 cells[i][j].newFlg =false; 118 } 119 } 120 121 switch(direction){ 122 case "up": 123 // 先列,后行 124 for(var j=0;j<cells[1].length ;j++ ) 125 { 126 var step = 1; 127 var conFlg = false; 128 for (var i=1;i<cells.length ;i++ ) 129 { 130 if(cells[i][j].n==0) 131 { 132 step++; 133 conFlg=true; 134 continue; 135 } 136 if(!conFlg){ 137 step = 1; 138 }//else{console.log(i,j,"Step:"+step);} 139 if(cells[i][j].n==cells[i-step][j].n && !cells[i-step][j].hbFlg) 140 { 141 //合并 142 scoreToAdd += cells[i-step][j].n; 143 cells[i-step][j].n *= 2; 144 cells[i-step][j].index += 1; 145 cells[i][j].n = 0; 146 cells[i][j].index = 0; 147 for(var kk=i-step;kk>=0;kk--) 148 cells[kk][j].hbFlg = true; 149 }else{ 150 if(conFlg)step--; 151 if(cells[i-step][j].n==0){ 152 //移动 153 cells[i-step][j].n = cells[i][j].n; 154 cells[i-step][j].index = cells[i][j].index; 155 cells[i][j].n = 0; 156 cells[i][j].index = 0; 157 if(!conFlg){ 158 i--; 159 } 160 } 161 } 162 if(conFlg){ 163 i=1-1; 164 } 165 conFlg=false; 166 step = 1; 167 } 168 } 169 break; 170 case "down": 171 // 先列,后行 172 for(var j=0;j<cells[1].length ;j++ ) 173 { 174 var step = 1; 175 var conFlg = false; 176 for (var i=cells.length-2;i>=0 ;i-- ) 177 { 178 if(cells[i][j].n==0) 179 { 180 step++; 181 conFlg=true; 182 continue; 183 } 184 if(!conFlg){ 185 step = 1; 186 }//else{console.log(step);} 187 if(cells[i][j].n==cells[i+step][j].n && !cells[i+step][j].hbFlg) 188 { 189 //合并 190 scoreToAdd += cells[i+step][j].n; 191 cells[i+step][j].n *= 2; 192 cells[i+step][j].index += 1; 193 cells[i][j].n = 0; 194 cells[i][j].index = 0; 195 for(var kk=i+step;kk<cells.length;kk++) 196 cells[kk][j].hbFlg = true; 197 }else{ 198 if(conFlg)step--; 199 if(cells[i+step][j].n==0){ 200 //移动 201 cells[i+step][j].n = cells[i][j].n; 202 cells[i+step][j].index = cells[i][j].index; 203 cells[i][j].n = 0; 204 cells[i][j].index = 0; 205 if(!conFlg){ 206 i++; 207 } 208 } 209 } 210 if(conFlg){ 211 i=cells.length-2+1; 212 } 213 conFlg=false; 214 step = 1; 215 } 216 } 217 break; 218 case "left": 219 // 先行,后列 220 for(var i=0;i<cells.length ;i++ ) 221 { 222 var step = 1; 223 var conFlg = false; 224 for (var j=1;j<cells[i].length ;j++ ) 225 { 226 if(cells[i][j].n==0) 227 { 228 step++; 229 conFlg=true; 230 continue; 231 } 232 if(!conFlg){ 233 step = 1; 234 }//else{console.log(step);} 235 if(cells[i][j].n==cells[i][j-step].n && !cells[i][j-step].hbFlg) 236 { 237 //合并 238 scoreToAdd += cells[i][j-step].n; 239 cells[i][j-step].n *= 2; 240 cells[i][j-step].index += 1; 241 cells[i][j].n = 0; 242 cells[i][j].index = 0; 243 for(var kk=j-step;kk>=0;kk--) 244 cells[i][kk].hbFlg = true; 245 }else{ 246 if(conFlg)step--; 247 if(cells[i][j-step].n==0){ 248 //移动 249 cells[i][j-step].n = cells[i][j].n; 250 cells[i][j-step].index = cells[i][j].index; 251 cells[i][j].n = 0; 252 cells[i][j].index = 0; 253 if(!conFlg){ 254 j--; 255 } 256 } 257 } 258 if(conFlg){ 259 j=1-1; 260 } 261 conFlg=false; 262 step = 1; 263 } 264 } 265 break; 266 case "right": 267 // 先行,后列 268 for(var i=0;i<cells.length ;i++ ) 269 { 270 var step = 1; 271 var conFlg = false; 272 for (var j=cells[i].length-2;j>=0 ;j-- ) 273 { 274 if(cells[i][j].n==0) 275 { 276 step++; 277 conFlg=true; 278 continue; 279 } 280 if(!conFlg){ 281 step = 1; 282 }//else{console.log(step);} 283 if(cells[i][j].n==cells[i][j+step].n && !cells[i][j+step].hbFlg) 284 { 285 //合并 286 scoreToAdd += cells[i][j+step].n; 287 cells[i][j+step].n *= 2; 288 cells[i][j+step].index += 1; 289 cells[i][j].n = 0; 290 cells[i][j].index = 0; 291 for(var kk=j+step;kk<cells[i].length;kk++) 292 cells[i][kk].hbFlg = true; 293 }else{ 294 if(conFlg)step--; 295 if(cells[i][j+step].n==0){ 296 //移动 297 cells[i][j+step].n = cells[i][j].n; 298 cells[i][j+step].index = cells[i][j].index; 299 cells[i][j].n = 0; 300 cells[i][j].index = 0; 301 if(!conFlg){ 302 j++; 303 } 304 } 305 } 306 if(conFlg){ 307 j=cells[i].length-2+1; 308 } 309 conFlg=false; 310 step = 1; 311 } 312 } 313 break; 314 } 315 for(var i=0;i<cells.length;i++){ 316 for(var j=0;j<cells[i].length;j++){ 317 cells[i][j].hbFlg =false; 318 } 319 } 320 scoreTotal += scoreToAdd; 321 scoreShow = "得分:"+scoreTotal; 322 genNum(false); 323 if(doJudge()=="t"){ 324 scoreShow = "恭喜你赢了!"; 325 }else if(doJudge()=="f"){ 326 scoreShow = "你输了!"; 327 btn_start.style.display="inline"; 328 } 329 doDrawCanvas(); 330 } 331 function addScroe(scoreToAdd){ 332 } 333 function getZeroLst(){ 334 cellZeroLst = []; 335 for(var i=0;i<cells.length;i++){ 336 for(var j=0;j<cells[i].length;j++){ 337 if(cells[i][j].n==0) 338 cellZeroLst.push(cells[i][j]); 339 //cellZeroLst.push(i*cells.length+j); 340 } 341 } 342 /*for(var h=0;h<cellZeroLst.length;h++){ 343 //var i= Math.round(cellZeroLst[h]/cells.length); 344 //var j= cellZeroLst[h]%cells.length; 345 //cells[i][j].n=2048; 346 //cells[i][j].index=11; 347 cellZeroLst[h].index=11; 348 cellZeroLst[h].n = 2048; 349 }*/ 350 //doDrawCells(); 351 } 352 function doDrawCanvas(){ 353 caCt.fillStyle = "white"; 354 caCt.fillRect(0,0,caW,caH); 355 doDrawWords(); 356 doDrawBorders(); 357 doDrawCells(); 358 //getZeroLst(); 359 } 360 function doDrawCells(){ 361 for(var i=0;i<cells.length;i++){ 362 for(var j=0;j<cells[i].length;j++){ 363 caCt.fillStyle = bgCLst[cells[i][j].index]; 364 if(cells[i][j].newFlg){ 365 caCt.fillStyle = "yellow"; 366 } 367 caCt.fillRect(cellBL + cellW * j +0.5,cellBT + cellH * i +0.5,cellW-1,cellH-1); 368 caCt.fillStyle = fontCLst[cells[i][j].index]; 369 if(cells[i][j].newFlg){ 370 caCt.fillStyle = "red"; 371 } 372 caCt.font=cells[i][j].fontSize + "px Arial"; 373 caCt.textAlign="center"; 374 caCt.textBaseline="middle"; 375 caCt.fillText(cells[i][j].n,cellBL + cellW * j + cellW*0.5,cellBT + cellH * i + cellH*0.5); 376 } 377 } 378 } 379 function doDrawBorders(){ 380 var cellBTop = caH - cellW * 4; 381 caCt.strokeStyle = borderC; 382 //caCt.strokeRect(cellBL-0.5,cellBT-0.5,cellW * 4,cellH * 4); 383 for(var i =0;i<=4;i++){ 384 //console.log(cellBT + cellH * i-0.5); 385 caCt.moveTo(cellBL-0.5,cellBT + cellH * i-(i==0?0.5:0.5)); 386 caCt.lineTo(cellBL + cellW * 4 -0.5,cellBT + cellH * i-(i==0?0.5:0.5)); 387 caCt.stroke(); 388 caCt.moveTo(cellBL + cellW * i-(i==0?0.5:0.5),cellBT-0.5); 389 caCt.lineTo(cellBL + cellW * i-(i==0?0.5:0.5),cellBT + cellH * 4 -0.5); 390 caCt.stroke(); 391 } 392 } 393 function doDrawWords(){ 394 caCt.fillStyle = "black"; 395 if(scoreShow == "恭喜你赢了!"){ 396 caCt.fillStyle = "red"; 397 } 398 else if(scoreShow == "你输了!"){ 399 caCt.fillStyle = "green"; 400 } 401 caCt.font= ((caH>caW)?(wordT * 0.7):13) +"px Arial"; 402 caCt.textAlign="center"; 403 caCt.textBaseline="middle"; 404 caCt.fillText(scoreShow,wordL,wordT); 405 } 406 function reStart(){ 407 cells=[]; 408 /********init size of canvas and other vars**********/ 409 doResize(); 410 /*******init cell data************/ 411 initDate(); 412 /******init not zero data*********/ 413 genNum(false); 414 genNum(false); 415 /********bound the event such as keyenvet and suggestionEvent***********/ 416 BindEvent(); 417 /********draw canvas**************/ 418 doDrawCanvas(); 419 btn_start.style.display="none"; 420 } 421 function initDate(){ 422 for(var i = 0;i<4;i++){ 423 var tmpCell = []; 424 for(var j = 0;j<4;j++){ 425 /*if(i==0 && j==0){ 426 tmpCell.push(new cell(cellW * 0.4,0,0)); 427 }else{ 428 tmpCell.push(new cell(cellW * 0.4,Math.pow(2,(4*i+j)),(4*i+j))); 429 }*/ 430 tmpCell.push(new cell(cellW * 0.4,0,0)); 431 } 432 cells.push(tmpCell); 433 } 434 //console.log(cells); 435 } 436 function doJudge(){ 437 getZeroLst(); 438 if(cellZeroLst.length==0){ 439 var goOn = false; 440 for(var i=0;i<cells.length;i++){ 441 if(goOn){break;} 442 for(var j=0;j<cells[i].length;j++){ 443 if((j>0 && cells[i][j].n==cells[i][j-1].n) || (j< cells[i].length-1 && cells[i][j].n==cells[i][j+1].n)){ 444 goOn = true; 445 break; 446 } 447 if((i>0 && cells[i][j].n==cells[i-1][j].n) || (i< cells[j].length-1 && cells[i][j].n==cells[i+1][j].n)){ 448 goOn = true; 449 break; 450 } 451 } 452 } 453 if(!goOn) 454 return "f"; 455 }else{ 456 for(var i=0;i<cells.length;i++){ 457 for(var j=0;j<cells[i].length;j++){ 458 if(cells[i][j].n == 2048){ 459 return "t"; 460 } 461 } 462 } 463 } 464 return "g"; 465 } 466 function genNum(only2){ 467 getZeroLst(); 468 if(cellZeroLst.length>0){ 469 var i = Math.round(Math.random()*(cellZeroLst.length-1)); 470 var number = 2; 471 var index = 1; 472 if(!only2){ 473 if(Math.random()>0.8){ 474 number = 4; 475 index = 2; 476 } 477 } 478 cellZeroLst[i].n=number; 479 cellZeroLst[i].index=index; 480 cellZeroLst[i].newFlg=true; 481 } 482 } 483 var v = navigator.userAgent.toLowerCase().indexOf("android") != -1 || navigator.userAgent.toLowerCase().indexOf("iphone") != -1 || navigator.userAgent.toLowerCase().indexOf("ipad") != -1, 484 caW = window.innerWidth, 485 caH = window.innerHeight, 486 btn_start = document.getElementById("btn_start"), 487 caObj = document.getElementById("GameWorld"), 488 caCt = caObj.getContext("2d"), 489 cells = [], 490 cellW = 0, 491 cellH = 0, 492 cellBT = 0, 493 cellBL = 0, 494 wordT = 0, 495 wordL = 0, 496 pageXs = 0, 497 pageYs = 0, 498 pageXe = 0, 499 pageYe = 0, 500 cellZeroLst = [], 501 scoreTotal = 0, 502 scoreShow = "滑动屏幕开始游戏", 503 borderC = "blue", 504 numLst = [0,2,4,8,16,32,64,128,256,512,1024,2048], 505 bgCLst = ["white","gray","lightblue","lightgreen","#d3a4ff","#ffa6ff","#6A6AFF","#FFA042","#AD5A5A","orange","#6C3365","red"], 506 fontCLst = ["white","white","white","white","white","white","white","white","black","black","white","white"]; 507 this.init = function(){ 508 /********init size of canvas and other vars**********/ 509 doResize(); 510 /*******init cell data************/ 511 initDate(); 512 /******init not zero data*********/ 513 genNum(false); 514 genNum(false); 515 /********bound the event such as keyenvet and suggestionEvent***********/ 516 BindEvent(); 517 /********draw canvas**************/ 518 doDrawCanvas(); 519 } 520 521 } 522 523 function cell(fontSize,n,index){ 524 this.c = "lightBlue"; 525 this.n = n!=null?n:0; // 指数 526 this.fontSize = fontSize; 527 this.isCaled = false; 528 this.index = index; 529 this.hbFlg = false; 530 this.newFlg = false; 531 } 532 533 onload = function(){ 534 gameWorld.init(); 535 }
CSDN下载