<!DOCTYPE html> <html> <head> <title>2048</title> <meta charset="utf-8" /> <script typet="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script> <style> canvas { display: block; margin: 0 auto; border-radius: 10px; background-color: #bbada0; } </style> </head> <body> <center id="score" style="font:bold 25px Arial,Microsoft Yahei"></center><br/> <canvas id="canvas" width="500" height="500"></canvas> </body> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext('2d'); //初始化地图 var map = [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0] ]; //不同数字的颜色信息 var num_color = { 0: "#ccc0b3", 2: "#eee4da", 4: "#ede0c8", 8: "#f2b179", 16: "#f59563", 32: "#f67c5f", 64: "#ec6544", 128: "#e44d29", 256: "#edcf72", 512: "#c8a145", 1024: "#a8832b", 2048: "#86aa9c" }; //不同数字的大小信息 var num_size = { 0: "60", 2: "60", 4: "60", 8: "60", 16: "60", 32: "60", 64: "60", 128: "50", 256: "50", 512: "50", 1024: "40", 2048: "40" }; //不同数字的偏移量(为了将数字画在方块中心) var offsetx = { 0: 53, 2: 53, 4: 53, 8: 53, 16: 34, 32: 35, 64: 35, 128: 28, 256: 28, 512: 28, 1024: 24, 2048: 25 }; //上下左右键的code对应的方向信息 var keycom = { '38': [0, -1], '40': [0, 1], '37': [-1, 0], '39': [1, 0] } //space表示当前剩余的空格块数,score表示当前的分数 var space = 16, score = 0; function formap(func) { for(var i = 0; i < 4; i++) for(var j = 0; j < 4; j++) { func(i, j); } } function produce() { var cot = ~~(Math.random() * space); var k = 0; formap(function(i, j) { if(map[i][j] == 0) { if(cot == k) { map[i][j] = 2; draw(); } k += 1; } }); space -= 1; } function draw() { formap(function(i, j) { var num = map[i][j]; ctx.fillStyle = num_color[num]; ctx.fillRect(j * 120 + 20, i * 120 + 20, 100, 100); if(num != 0) { ctx.font = "bold " + num_size[num] + "px Arial,Microsoft Yahei"; ctx.fillStyle = (num <= 4) ? "#776e65" : "white"; ctx.fillText(String(map[i][j]), j * 120 + offsetx[num], i * 120 + 70 + num_size[num] / 3); } }); document.getElementById("score").innerText = "Score: " + String(score); } function move(dir) { //用来调整不同方向的遍历方式 function modify(x, y) { tx = x, ty = y; if(dir[0] == 0) tx = [ty, ty = tx][0]; if(dir[1] > 0) tx = 3 - tx; if(dir[0] > 0) ty = 3 - ty; return [tx, ty]; } //根据移动的方向,将地图中对应行/列中的数字一个个压入栈中,如果第一次遇到栈顶数字和待入栈数字相等,则栈顶数字乘2,最后用栈中数字更新地图中的对应行/列 for(var i = 0; i < 4; i++) { var tmp = Array(); var isadd = false; for(var j = 0; j < 4; j++) { var ti = modify(i, j)[0], tj = modify(i, j)[1]; if(map[ti][tj] != 0) { if(!isadd && map[ti][tj] == tmp[tmp.length - 1]) score += (tmp[tmp.length - 1] *= 2), isadd = true, space += 1; else tmp.push(map[ti][tj]); } } for(var j = 0; j < 4; j++) { var ti = modify(i, j)[0], tj = modify(i, j)[1]; map[ti][tj] = isNaN(tmp[j]) ? 0 : tmp[j]; } } produce(); if(space == 0) alert("game over"); draw(); } produce(); produce(); document.onkeydown = function(e) { dir = keycom[(e ? e : event).keyCode]; move(dir); }; var sx, sy, dx, dy, ex, ey; canvas.ontouchstart = function(event) { var touch = event.touches[0]; sx = touch.clientX, sy = touch.clientY; } canvas.ontouchmove = function(event) { var touch = event.touches[0]; ex = touch.clientX, ey = touch.clientY; dx = ex - sx, dy = ey - sy; //禁止默认的滑动事件 event.preventDefault(); } canvas.ontouchend = function(event) { //根据横纵坐标位移判断滑动方向 if(dy < -50 && Math.abs(dy / dx) > 2) move([0, -1]); if(dy > 50 && Math.abs(dy / dx) > 2) move([0, 1]); if(dx < -50 && Math.abs(dx / dy) > 2) move([-1, 0]); if(dx > 50 && Math.abs(dx / dy) > 2) move([1, 0]); } </script> </html>