<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv = "X-UA-Compatible" content="IE=edge" />
<meta name = "viewport" content = "width=device-width, height=device-height, initial-scale=1.0, minimum-scale = 1.0, maximum-scale=1.0, user-scalable = no" />
<title>2048</title>
<link rel="stylesheet" href = "2048.css" />
<script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript" src="main2048.js"></script>
<script type="text/javascript" src="support2048.js"></script>
<script type="text/javascript" src="move2048.js"></script>
</head>
<body>
<header>
<h1>2048</h1>
<a href="javascript:newGame();" class="btm" id="newGameButtom">new game</a><br />
<p>score: <span id="score">0</span></p>
</header>
<div id="container">
<div class="cell" id="cell-00"></div>
<div class="cell" id="cell-01"></div>
<div class="cell" id="cell-02"></div>
<div class="cell" id="cell-03"></div>
<div class="cell" id="cell-10"></div>
<div class="cell" id="cell-11"></div>
<div class="cell" id="cell-12"></div>
<div class="cell" id="cell-13"></div>
<div class="cell" id="cell-20"></div>
<div class="cell" id="cell-21"></div>
<div class="cell" id="cell-22"></div>
<div class="cell" id="cell-23"></div>
<div class="cell" id="cell-30"></div>
<div class="cell" id="cell-31"></div>
<div class="cell" id="cell-32"></div>
<div class="cell" id="cell-33"></div>
<div class="alert" id="gameOver">
<p>Game is Over</p>
<a href="javascript:newGame();" class="btm" id="tryAgain">try again</a><br />
</div>
<div class="alert" id="gameWin" >
<p>GOOD!NOW YOU HAVE GET 2048!</p>
<p><a href="javascript:newGame();" class="btm" id="restart">new game</a></p>
<p><a href="javascript:continuePlay();" class="btm" id="continue">GoGoGO</a></p>
</div>
</body>
</html>
/* CSS Document */
header{
display:block;
margin:0 auto;
width:100%;
text-align:center;
}
header h1{
font-family:Verdana;
font-size:20pt;
color:orange;
}
.btm{
margin:20px auto;
width:5%;
padding:5px 5px;
text-decoration:none;
border-radius:10px;
font-family:Verdana;
background-color:orange;
color:#ffffff;
}
.btm:hover{
background-color:#FFCC99;
}
header p{
font-family:Verdana;
font-size:20px;
color:orange;
margin-top:20px;
margin-bottom:10px;
}
header p #score{
border-bottom:1px dashed orange;
width:60px;
}
#container{
width:500px;
height:500px;
padding:0px;
margin:20px auto;
border-radius:10px;
border:1px solid orange;
position:relative;
}
.cell{
/*
width:100px;
height:100px;
border-radius:6px;
*/
background-color:#FFCC99;
border:0px solid #FFCC99;
position:absolute;
}
.cellNumber{
/*width:100px;
height:100px;
border-radius:6px;
*/
position:absolute;
font-family:Verdana;
text-align:center;
font-size:20px;
line-height:100px;
}
#gameOver{
position:relative;
width:50%;
text-align:center;
margin:0 auto;
font-size:30px;
opacity:0.7;
font-family:Verdana;
color:orange;
background-color:#fff;
padding:20px;
border-radius:30%;
border:orange dashed 1px;
z-index:100;
}
#gameWin{
position:relative;
width:80%;
text-align:center;
margin:0 auto;
font-size:20px;
opacity:0.7;
font-family:Verdana;
color:orange;
background-color:#fff;
padding:20px;
border-radius:30%;
border:orange dashed 1px;
z-index:100;
}
// JavaScript Document
// 面向过程设计
var board = new Array();
var flag = new Array();
var score = 0;
//支持触碰
var startx = 0;
var starty = 0;
var endx = 0;
var endy = 0;
$(document).ready(function(){
prepareForMobile();
newGame();
});
function prepareForMobile(){
//移动端初始化
if (documentWidth >500){
containerWidth = 500;
cellLength = 100;
cellSpace = 20;
}
$('#container').css({'width':containerWidth - 2*cellSpace,
'height':containerWidth - 2*cellSpace,
'padding':cellSpace,
'border-radius':0.02 * containerWidth
});
$('.cell').css({'width':cellLength,
'height':cellLength,
'border-radius' : 0.1 * cellLength
});
}
function newGame(){
//初始化棋盘
$(".alert").css('display','none');
init();
//随机产生数字
initNum();
initNum();
}
function init(){
//初始化
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++){
//初始化网格
var gridCell = $("#cell-" + i + j);
gridCell.css({'top':getPos(i),'left':getPos(j)});
//gridCell.css('left',getPos(j));
}
board = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
updateBoardView();
score = 0;
updateScore(score);
}
function updateBoardView(){
$(".cellNumber").remove();
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++){
$("#container").append('<div class="cellNumber" id="cellNumber-' + i + j +'"></div>');
var temp = $('#cellNumber-' + i + j);
var num = board[i][j]
if (num==0){
temp.css({'width':'0px',
'height':'0px',
'top':getPos(i) + cellLength/2,
'left':getPos(j) + cellLength/2
});
}else{
temp.css({'width':cellLength,
'height':cellLength,
'top':getPos(i),
'left':getPos(j),
'border-radius':0.1*cellLength,
'background-color':getColor(num)[0],
'color':getColor(num)[1],
'z-index':50
});
temp.text(board[i][j]);
}
}
$(".cellNumber").css({
'line-height':cellLength+'px',
'font-size':0.4*cellLength+'px'
});
}
function initNum(){
if (noSpace(board))
return false;
//产生随机位置
var randi = parseInt(Math.floor(Math.random()*4));
var randj = parseInt(Math.floor(Math.random()*4));
var loop=0;
while(board[randi][randj]!=0 && loop<50){
randi = parseInt(Math.floor(Math.random()*4));
randj = parseInt(Math.floor(Math.random()*4));
loop = loop + 1;
}
//产生随机数
var randNum = Math.random()<0.5?2:4;
//随机位置产生随机数
if (board[randi][randj]==0){
board[randi][randj] = randNum;
}else{
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++)
if (board[i][j]==0)
board[i][j] = randNum;
}
showNum(randi,randj,randNum);
}
$(document).keydown(function(event){
switch(event.keyCode){
case 37: //left
event.preventDefault();
if(moveLeft()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",400);
}
break;
case 38: //up
event.preventDefault();
if(moveUp()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",400);
}
break;
case 39: //right
event.preventDefault();
if(moveRight()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",400);
}
break;
case 40://down
event.preventDefault();
if(moveDown()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",400);
}
break;
default:
break;
}
});
/*
监听触碰事件
*/
document.addEventListener('touchstart',function(event){
startx = event.touches[0].pageX;
starty = event.touches[0].pageY;
});
document.addEventListener('touchmove',function(event){
event.preventDefault();
});
document.addEventListener('touchend',function(event){
endx = event.changedTouches[0].pageX;
endy = event.changedTouches[0].pageY;
//判断左右移动还是上下移动
var deltax = endx - startx;
var deltay = endy - starty;
if (Math.abs(deltax)<0.3 * documentWidth && Math.abs(deltay)<0.3 * documentWidth){
return ; //不移动
}
if (Math.abs(deltax) >= Math.abs(deltay)){
if(deltax > 0){
//右移动
if(moveRight()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",300);
}
}else{
//左移动
if(moveLeft()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",300);
}
}
}else{
if(deltay > 0){
//下移动
if(moveDown()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",300);
}
}else{
//上移动
if(moveUp()){
setTimeout("initNum()",250);
setTimeout("isGameOver()",300);
}
}
}
});
function updateScore(score){
$('#score').text(score);
}
function moveLeft(){
if (!canMoveLeft(board))
return false;
//move left
flag = [[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 = 1; j < 4; j++){
if (board[i][j]!=0){
for (var k = j - 1; k >= 0 ; k--){
if (k == 0){
if(board[i][k] == 0){
moveAnimation(i,j,i,k);
board[i][k] = board[i][j];
board[i][j] = 0;
}else if (board[i][k] == board[i][j] && flag[i][k]!=1){
moveAnimation(i,j,i,k);
board[i][k] = board[i][k]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[i][k] = 1;
}else if (k!=j-1){
board[i][k+1] = board[i][j];
board[i][j] = 0;
}
}else{
if (board[i][k]!=0){
if (board[i][k] == board[i][j] && flag[i][k]!=1){
moveAnimation(i,j,i,k);
board[i][k] = board[i][k]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[i][k] = 1;
}else if (k!=j-1){
moveAnimation(i,j,i,k);
board[i][k+1] = board[i][j];
board[i][j] = 0;
}
break;
}
}
}
}
}
setTimeout("updateBoardView()",200);
checkNum(2048);
return true;
}
function moveUp(){
if (!canMoveUp(board))
return false;
//move Up
flag = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
for (var j = 0; j < 4; j++)
for (var i = 1; i < 4; i++){
if (board[i][j]!=0){
for (var k = i - 1; k >= 0 ; k--){
if (k == 0){
if(board[k][j] == 0){
moveAnimation(i,j,k,j);
board[k][j] = board[i][j];
board[i][j] = 0;
}else if (board[k][j] == board[i][j] && flag[k][j]!=1){
moveAnimation(i,j,k,j);
board[k][j] = board[k][j]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[i][k] = 1;
}else if (k!=i-1){
moveAnimation(i,j,k,j);
board[k+1][j] = board[i][j];
board[i][j] = 0;
}
}else{
if (board[k][j]!=0){
if (board[k][j] == board[i][j] && flag[k][j]!=1){
moveAnimation(i,j,k,j);
board[k][j] = board[k][j]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[k][j] = 1;
}else if (k!=i-1){
moveAnimation(i,j,k,j);
board[k+1][j] = board[i][j];
board[i][j] = 0;
}
break;
}
}
}
}
}
setTimeout("updateBoardView()",200);
checkNum(2048);
return true;
}
////////////////
function moveRight(){
if (!canMoveRight(board))
return false;
//move right
flag = [[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 = 2; j >= 0; j--){
if (board[i][j]!=0){
for (var k = j + 1; k <=3; k++){
if (k == 3){
if(board[i][k] == 0){
moveAnimation(i,j,i,k);
board[i][k] = board[i][j];
board[i][j] = 0;
}else if (board[i][k] == board[i][j] && flag[i][k]!=1){
moveAnimation(i,j,i,k);
board[i][k] = board[i][k]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[i][k] = 1;
}else if (k!=j+1){
moveAnimation(i,j,i,k);
board[i][k-1] = board[i][j];
board[i][j] = 0;
}
}else{
if (board[i][k]!=0){
if (board[i][k] == board[i][j] && flag[i][k]!=1){
moveAnimation(i,j,i,k);
board[i][k] = board[i][k]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[i][k] = 1;
}else if (k!=j+1){
moveAnimation(i,j,i,k);
board[i][k-1] = board[i][j];
board[i][j] = 0;
}
break;
}
}
}
}
}
setTimeout("updateBoardView()",200);
checkNum(2048);
return true;
}
function moveDown(){
if (!canMoveDown(board))
return false;
//move down
flag = [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]];
for (var j = 0; j < 4; j++)
for (var i = 2; i >= 0; i--){
if (board[i][j]!=0){
for (var k = i + 1; k <=3; k++){
if (k == 3){
if(board[k][j] == 0){
moveAnimation(i,j,k,j);
board[k][j] = board[i][j];
board[i][j] = 0;
}else if (board[k][j] == board[i][j] && flag[k][j]!=1){
moveAnimation(i,j,k,j);
board[k][j] = board[k][j]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[k][j] = 1;
}else if (k!=i+1){
moveAnimation(i,j,k,j);
board[k-1][j] = board[i][j];
board[i][j] = 0;
}
}else{
if (board[k][j]!=0){
if (board[k][j] == board[i][j] && flag[k][j]!=1){
moveAnimation(i,j,k,j);
board[k][j] = board[k][j]*2;
score = score + board[i][j]*2;
updateScore(score);
board[i][j] = 0;
flag[k][j] = 1;
}else if (k!=i+1){
moveAnimation(i,j,k,j);
board[k-1][j] = board[i][j];
board[i][j] = 0;
}
break;
}
}
}
}
}
setTimeout("updateBoardView()",200);
checkNum(2048);
return true;
}
function canMoveLeft( board ){
for( var i = 0 ; i < 4 ; i ++ )
for( var j = 1; j < 4 ; j ++ )
if( board[i][j] != 0 )
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][j] != 0 )
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] != 0 )
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 < 4 ; j ++ )
if( board[i][j] != 0 )
if( board[i+1][j] == 0 || board[i+1][j] == board[i][j] )
return true;
return false;
}
// JavaScript Document
//定义长宽,以便在移动端中自适应
documentWidth = window.screen.availWidth;
containerWidth = 0.92 * documentWidth;
cellLength = 0.18 * documentWidth;
cellSpace = 0.04 * documentWidth;
function getPos(i){
//初始化行和列,输入i为top,输入j为left
//return i * 120 + 20;
return i * (cellSpace + cellLength) + cellSpace;
}
function getColor(num){
//设置cell的颜色
var color = new Array;
var bg = "";
var textcolor = "";
if ((Math.log(num)/Math.log(2))%2==1){
bg = "orange";
textcolor="#ffffff";
}else{
bg = "#eee4da";
textcolor="orange";
}
/* 每个格子不同颜色
switch(num){
case 2: bg = "orange";
textcolor="#ffffff";
break;
case 4: bg = "#eee4da";
textcolor="orange";
break;
case 8: bg = "orange";
textcolor="#ffffff";
break;
case 16: bg = "#eee4da";
textcolor="orange";
break;
case 32: bg = "orange";
textcolor="#ffffff";
break;
case 64: bg = "#eee4da";
textcolor="orange";
break;
case 128: bg = "orange";
textcolor="#ffffff";
break;
case 256: bg = "#eee4da";
textcolor="orange";
break;
case 512: bg = "orange";
textcolor="#ffffff";
break;
case 1024: bg = "#eee4da";
textcolor="orange";
break;
case 2048: bg = "orange";
textcolor="#ffffff";
break;
case 4096: bg = "#eee4da";
textcolor="orange";
break;
case 8192: bg = "orange";
textcolor="#ffffff";
break;
}
*/
color[0] = bg;
color[1] = textcolor;
return color;
}
function checkNum(num){
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++)
if (board[i][j]==num){
$("#gameWin").show(500);
}
}
function noSpace(board){
for (var i = 0; i < 4; i++)
for (var j = 0; j < 4; j++)
if (board[i][j]==0)
return false;
return true;
}
function showNum(i,j,num){
//数字产生动画
var cell = $('#cellNumber-'+i+j);
cell.css({'background-color':getColor(num)[0],
'color':getColor(num)[1]
});
cell.text(num);
cell.animate({'width':cellLength,
'height':cellLength,
'border-radius':0.1*cellLength,
'top':getPos(i),
'left':getPos(j)
},80);
}
function moveAnimation(fromx,fromy,tox,toy){
var numCell = $('#cellNumber-' + fromx + fromy);
numCell.animate({
top:getPos( tox ),
left:getPos( toy )
},200);
}
function noMove(board){
if (canMoveUp( board ) || canMoveDown( board )
|| canMoveLeft( board ) || canMoveRight( board ))
return false;
return true;
}
function isGameOver(){
if (noSpace(board) && noMove(board)){
//if (score>15){ //测试用
//$("#gameOver").css('display','block');
$("#gameOver").show(500);
}
}
function continuePlay(){
$("#gameWin").remove();
}