在imooc上见到有用H5做2048的教程,就跟着做了一下。在其中有学到一些不足。
有遇到
Cannot read property '0' of undefined
的问题。后面发现是因为js定义的函数在调用时并没有传参数进去。但是运行结果好像是正确的,在将参数补上后,console不再报错。
还有一次是因为在JQuery的animate函数中把其中一个参数的名称打错了。然而,console不报错,就是不运行结果。最后一点一点查,才查出来结果。是有2个字母的顺序写反了。这个一个值得记住的教训。下面附上源码。
index.html
<html lang="en">
<head>
<meta charset="UTF-8">
<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 study from imooctitle>
<link rel="stylesheet" href="css/style.css" type="text/css">
<script type="text/javascript" src="jQuery/jquery-2.2.0.min.js">script>
<script type="text/javascript" src="mian2048.js">script>
<script type="text/javascript" src="showanimation2048.js">script>
<script type="text/javascript" src="support.js">script>
head>
<body>
<header>
<h1>2048h1>
<a href="javascript:newgame();" id="newgamebutton">New Gamea>
<p>score: <span id="score">0span>p>
header>
<div id="grid-container">
<div class="grid-cell" id="grid-cell-0-0">div>
<div class="grid-cell" id="grid-cell-0-1">div>
<div class="grid-cell" id="grid-cell-0-2">div>
<div class="grid-cell" id="grid-cell-0-3">div>
<div class="grid-cell" id="grid-cell-1-0">div>
<div class="grid-cell" id="grid-cell-1-1">div>
<div class="grid-cell" id="grid-cell-1-2">div>
<div class="grid-cell" id="grid-cell-1-3">div>
<div class="grid-cell" id="grid-cell-2-0">div>
<div class="grid-cell" id="grid-cell-2-1">div>
<div class="grid-cell" id="grid-cell-2-2">div>
<div class="grid-cell" id="grid-cell-2-3">div>
<div class="grid-cell" id="grid-cell-3-0">div>
<div class="grid-cell" id="grid-cell-3-1">div>
<div class="grid-cell" id="grid-cell-3-2">div>
<div class="grid-cell" id="grid-cell-3-3">div>
div>
body>
html>
main2048.js
var board = new Array();
var score = 0;
var hasConflicted = new Array();
$(document).ready(function() {
perpare4Mobole();
newgame();
})
function perpare4Mobole() {
if (documentWidth > 500) {
gridContainer = 500;
cellSpace = 20;
cellSideLength = 100;
}
$('#grid-container').css('width', gridContainer - 2 * cellSpace);
$('#grid-container').css('height', gridContainer - 2 * cellSpace);
$('#grid-container').css('padding', cellSpace);
$('#grid-container').css('border-radius', 0.02 * gridContainer);
$('.grid-cell').css('width', cellSideLength);
$('.grid-cell').css('height', cellSideLength);
$('.grid-cell').css('border-radius', 0.02 * gridContainer);
}
function newgame() {
//初始化棋盘格
init();
//随机两个格子生成数字
generateOneRadom();
generateOneRadom();
}
function init() {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var gridCell = $("#grid-cell-" + i + "-" + j);
gridCell.css({
top: getPosTop(i, j),
left: getPosLeft(i, j)
});
}
}
for (var i = 0; i < 4; i++) {
board[i] = new Array();
hasConflicted[i] = new Array();
for (var j = 0; j < 4; j++) {
board[i][j] = 0;
hasConflicted[i][j] = 0;
}
}
updateBoardView();
}
function updateBoardView() {
$(".number-cell").remove();
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
$("#grid-container").append(''-' + j + '">');
var theNumberCell = $("#number-cell-" + i + "-" + j);
if (board[i][j] == 0) {
theNumberCell.css('width', '0px');
theNumberCell.css('height', '0px');
theNumberCell.css('top', getPosTop(i, j) + cellSideLength / 2);
theNumberCell.css('left', getPosLeft(i, j) + cellSideLength / 2);
} else {
theNumberCell.css('width', cellSideLength);
theNumberCell.css('height', cellSideLength);
theNumberCell.css('top', getPosTop(i, j));
theNumberCell.css('left', getPosLeft(i, j));
theNumberCell.css('background-color', getNumberBackgroundColor(board[i][j]));
theNumberCell.css('color', getNumberColor(board[i][j]));
theNumberCell.text(board[i][j]);
}
hasConflicted[i][j] = 0;
}
}
$('.number-cell').css('line-height', cellSideLength + 'px');
$('.number-cell').css('font-size', 0.6 * cellSideLength + 'px');
}
function generateOneRadom() {
if (nospace(board)) {
return false;
}
//随机一个位置
var randx = parseInt(Math.floor(Math.random() * 4));
var randy = parseInt(Math.floor(Math.random() * 4));
var time = 0;
while (time < 50) {
if (board[randx][randy] == 0) {
break;
}
randx = parseInt(Math.floor(Math.random() * 4));
randy = parseInt(Math.floor(Math.random() * 4));
time++;
}
if (time == 50) {
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
if (board[i][j] == 0) {
randx = i;
randy = j;
}
}
}
}
//随即一个数字
var randnumber = Math.random() > 0.5 ? 2 : 4;
//在随机位置显示随机数字
board[randx][randy] = randnumber;
showNumberWithAnimation(randx, randy, randnumber);
return true;
}
$(document).keydown(function(event) {
switch (event.keyCode) {
case 37: //left
event.preventDefault();
if (moveLeft()) {
setTimeout("generateOneRadom()", 210);
}
isgameover();
break;
case 38: //up
event.preventDefault();
if (moveUp()) {
document.preventDefault();
setTimeout("generateOneRadom()", 210);
}
isgameover();
break;
case 39: //right
event.preventDefault();
if (moveRight()) {
setTimeout("generateOneRadom()", 210);
}
isgameover();
break;
case 40: //down
event.preventDefault();
if (moveDown()) {
setTimeout("generateOneRadom()", 210);
console.log('is check gmaeover');
}
isgameover();
break;
}
});
document.addEventListener('touchstart', function(event) {
startx = event.touches[0].pageX;
starty = event.touches[0].pageY;
});
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.15 * documentWidth && Math.abs(deltaY) < 0.15 * documentWidth) {
return;
}
//x
if (Math.abs(deltaX) >= Math.abs(deltaY)) {
if (deltaX > 0) {
//move Right
if (moveRight()) {
setTimeout("generateOneRadom()", 210);
setTimeout("isgameover()", 210);
}
} else {
//move Left
if (moveLeft()) {
setTimeout("generateOneRadom()", 210);
setTimeout("isgameover()", 210);
}
}
} else {
if (deltaY > 0) {
//move Down
if (moveDown()) {
setTimeout("generateOneRadom()", 210);
setTimeout("isgameover()", 210);
}
} else {
//move Up
if (moveUp()) {
setTimeout("generateOneRadom()", 210);
setTimeout("isgameover()", 210);
}
}
}
});
function isgameover() {
if (nospace(board) && nomove(board)) {
gameover();
}
}
function gameover() {
alert('gameover');
}
function moveLeft() {
if (!canmoveLeft(board)) {
return false;
}
//moveLeft
console.log('2test');
for (var i = 0; i < 4; i++) {
for (var j = 1; j < 4; j++) {
if (board[i][j] !== 0) {
for (var k = 0; k < j; k++) {
if (board[i][k] === 0 && noBlockHorizontal(i, k, j, board)) {
//move
showMoveAnimation(i, j, i, k);
board[i][k] = board[i][j];
board[i][j] = 0;
break;
} else if (board[i][k] == board[i][j] && noBlockHorizontal(i, k, j, board) && !hasConflicted[i][k]) {
//move
showMoveAnimation(i, j, i, k);
//add
board[i][k] += board[i][j];
board[i][j] = 0;
//add score
score += board[i][k];
hasConflicted[i][k] = 1;
updateScore(score);
break;
}
}
}
}
}
setTimeout('updateBoardView()', 200);
return true;
}
var ti = 0;
function moveRight() {
if (!canmoveRight(board)) {
console.log("can't moveRight.");
return false;
}
//moveRight
console.log("moveRight");
for (var i = 0; i < 4; i++) {
for (var j = 2; j >= 0; j--) {
if (board[i][j] != 0) {
for (var k = 3; k > j; k--) {
if (board[i][k] == 0 && noBlockHorizontal(i, j, k, board)) {
//move
showMoveAnimation(i, j, i, k);
board[i][k] = board[i][j];
board[i][j] = 0;
break;
} else if (board[i][k] == board[i][j] && noBlockHorizontal(i, j, k, board) && !hasConflicted[i][k]) {
//move
showMoveAnimation(i, j, i, k);
//add
board[i][k] *= 2;
board[i][j] = 0;
//add score
score += board[i][k];
hasConflicted[i][k] = 1;
updateScore(score);
break;
}
}
}
}
}
setTimeout('updateBoardView()', 200);
return true;
}
function moveUp() {
if (!canmoveUp(board))
return false;
//moveUp
for (var j = 0; j < 4; j++)
for (var i = 1; i < 4; i++) {
if (board[i][j] != 0) {
for (var k = 0; k < i; k++) {
if (board[k][j] == 0 && noBlockVertical(j, k, i, board)) {
//move
showMoveAnimation(i, j, k, j);
board[k][j] = board[i][j];
board[i][j] = 0;
continue;
} else if (board[k][j] == board[i][j] && noBlockVertical(j, k, i, board) && !hasConflicted[k][j]) {
//move
showMoveAnimation(i, j, k, j);
//add
board[k][j] += board[i][j];
board[i][j] = 0;
//add score
score += board[k][j];
updateScore(score);
hasConflicted[k][j] = true;
continue;
}
}
}
}
setTimeout("updateBoardView()", 200);
return true;
}
function moveDown() {
if (!canmoveDown(board))
return false;
//moveDown
for (var j = 0; j < 4; j++)
for (var i = 2; i >= 0; i--) {
if (board[i][j] != 0) {
for (var k = 3; k > i; k--) {
if (board[k][j] == 0 && noBlockVertical(j, i, k, board)) {
//move
showMoveAnimation(i, j, k, j);
board[k][j] = board[i][j];
board[i][j] = 0;
continue;
} else if (board[k][j] == board[i][j] && noBlockVertical(j, i, k, board) && !hasConflicted[k][j]) {
//move
showMoveAnimation(i, j, k, j);
//add
board[k][j] += board[i][j];
board[i][j] = 0;
//add score
score += board[k][j];
updateScore(score);
hasConflicted[k][j] = true;
continue;
}
}
}
}
setTimeout("updateBoardView()", 200);
return true;
}
function updateScore(score) {
var obj = $("#score");
obj.text(score);
obj.css('color', 'blue');
obj.css('font-size', '30px');
}
showanimate2048.js
function showNumberWithAnimation(i,j,randNumer){
var numberCell = $("#number-cell-"+i+'-'+j);
numberCell.css('background-color', getNumberBackgroundColor(randNumer));
numberCell.css('color',getNumberColor(randNumer));
numberCell.text(randNumer);
numberCell.animate({
width:cellSideLength,
height:cellSideLength,
top:getPosTop(i,j),
left:getPosLeft(i,j)
},50);
}
function showMoveAnimation(fromx,fromy,tox,toy){
var numberCell=$('#number-cell-'+fromx+'-'+fromy);
numberCell.animate({
top:getPosTop(tox,toy),
left:getPosLeft(tox,toy)
},200);
}
support.js
documentWidth = window.screen.availWidth;
gridContainer = 0.92 * documentWidth;
cellSideLength = 0.18 * documentWidth;
cellSpace = 0.04*documentWidth;
function getPosTop(i, j) {
return cellSpace + i * (cellSpace+cellSideLength);
}
function getPosLeft(i, j) {
return cellSpace + j * (cellSpace+cellSideLength);
}
function getNumberBackgroundColor(number) {
switch (number) {
case 2:
return "#eee4da";
case 4:
return "#ede0c8";
case 8:
return "#f2b179";
case 16:
return "#f59563";
case 32:
return "#f67c5f";
case 64:
return "#f65e3b";
case 128:
return "#edcf72";
case 256:
return "#edcc61";
case 512:
return "$9c0";
case 1024:
return "#33b5e5";
case 2048:
return "#09c";
case 4096:
return "#a6c";
case 8192:
return "#93c";
}
return "black";
}
function getNumberColor(number) {
if (number <= 4) {
return "#776e65";
}
return "white";
}
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 nomove(board){
if (canmoveLeft(board) ||canmoveRight(board) || canmoveUp(board)||canmoveDown(board)) {
return false;
}
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 canmoveRight(board) {
for (var i = 0; i < 4; i++) {
for (var j = 2; j > -1; 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 j = 0; j < 4; j++) {
for (var i = 1; i < 4; i++) {
if (board[i][j] != 0) {
if (board[i - 1][j] == 0 || board[i - 1][j] == board[i][j]) {
return true;
}
}
}
}
return false;
}
function canmoveDown(board) {
for (var i = 2; i > -1; 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 noBlockHorizontal(row, col1, col2, board) {
for (var i = col1 + 1; i < col2; i++)
if (board[row][i] != 0)
return false;
return true;
}
function noBlockVertical( col , row1 , row2 , board ){
for( var i = row1 + 1 ; i < row2 ; i ++ )
if( board[i][col] != 0 )
return false;
return true;
}
style.css
header{
display: block;
margin: 0 auto;
width: 100%;
text-align: center;
}
header h1 {
font-family: Arial;
font-size: 40px;
font-weight: bold;
margin:0 0;
}
header #newgamebutton{
display: block;
margin: 0px auto;
width: 100px;
padding: 10px 10px;
background-color: #8f7a66;
font-family: Arial;
color: white;
border-radius: 10px;
text-decoration: none;
}
header #newgamebutton:hover{
background-color: #9f8b77;
}
header p{
font-family: Arial;
font-style: 25px;
margin: 10px auto;
}
#grid-container{
width: 460px;
height: 460px;
padding: 20px;
margin: 0px auto;
background-color: #bbada0;
border-radius: 10px;
position: relative;
}
.grid-cell{
width: 100px;
height: 100px;
border-radius: 6px;
background-color: #ccc0b3;
position: absolute;
}
.number-cell{
border-radius: 6px;
font-family: Arial;
font-weight: bold;
font-size: 60px;
line-height: 100px;
text-align: center;
position: absolute;
}