网页版《2048游戏》
教程
人力资源管理pdf成真迷上我教程下载西门子数控教程protel99se入门教程fi6130z安装使用教程
网页版《2048游戏》教程
1. 课程介绍
1.1. 关于《2048》
《2048》是比较流行的一款数字游戏。原版2048首先在github上发布,原作者是Gabriele Cirulli。它是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏。
随后2048便出现各种版本,走各大平台。由Ketchapp公司移植到IOS的版本最为火热,现在约有1000万下载,其名字跟原版一模一样。衍生版中最出名的是《2048六边形》版本,先后在全球81个国家中的board game中排进了前200。安卓版非常火爆的有《挑战2048》,其2.0.0版以后还加入了双人对战。其次比较特别的有2048中国朝代版。更有2048自定义版,可以自己定义文字和图片。《2048》是IOS中流行的一款。
1.2. 游戏演示
1.3. 使用技术
, HTML
, CSS
, Javascript
, jQuery
1.4. 游戏架构
, index.html:游戏页面,引入样式文件及逻辑文件顺序如下:
, 2048.css:游戏样式
, jquery.js:jQuery文件
, support.js:游戏基础逻辑文件
, animation.js:游戏动画逻辑文件
, main.js:游戏主逻辑文件
, game.js:游戏交互逻辑文件
2. 构建页面
2.1. 游戏标
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
《2048》游戏的标题包含游戏名称、开始新游戏的按钮和游戏分数等三项内容。
创建游戏页面index.html:
2048
创建样式文件2048.css:
, 设置游戏标题样式
header {
display: block;
margin: 0 auto;
width: 100%;
text-align: center;
}
, 设置游戏名称样式
header h1 {
font-family: Arial;
font-size: 40px;
font-weight: bold;
}
, 设置游戏按钮样式
header #newgamebutton {
display: block;
margin: 20px 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-size: 25px;
margin: 20px auto;
}
2.2. 游戏主体
《2048》游戏的主体包含16个方块。
编辑游戏页面index.html:
编辑样式文件2048.css:
, 设置16个方块的主体方块样式
#grid-container {
width: 460px;
height: 460px;
padding: 20px;
margin: 50px auto;
background-color: #bbada0;
border-radius: 10px;
position: relative;
}
, 设置16个方块的样式
.grid-cell {
width: 100px;
height: 100px;
border-radius: 6px;
background-color: #ccc0b3;
position: absolute;
}
3. 游戏初始化
3.1. 初始化棋盘格
我们在main.js文件中,创建newgame()方法用于开始新的游戏。而开始新游戏需要完成两件事情,
一是初始化棋盘格,一是在随机两个格子生成两个数字。 $(function () {
newgame();
});
function newgame() {
//初始化棋盘格
init();
//在随机两个格子生成数字
generateOneNumber();
generateOneNumber();
}
我们通过编写init()方法来完成棋盘格的初始化工作。棋盘格是一个4乘4的16块的方格,所以
我们需要创建一个二位数组来
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
示。
var board = new Array();
function init() {
//i表示4乘4的格子中的行
for (var i = 0; i < 4; i++) {
board[i] = new Array();
//j表示4乘4的格子中的列
for (var j = 0; j < 4; j++) {
//将每个格子的值初始化为0
board[i][j] = 0;
//通过双重遍历获取每个格子元素
var gridCell = $("#grid-cell-" + i + "-" + j);
//通过getPosTop()方法设置每个格子距顶端的距离
gridCell.css("top", getPosTop(i, j));
//通过getPosLeft()方法设置每个格子距左端的距离
gridCell.css("left", getPosLeft(i, j));
}
}
}
完成以上步骤,我们就将棋盘格的初始化工作完成了。
3.2. 初始化数字格
仅仅初始化棋盘格是不够的,我们还需要一个4乘4的格子用来显示数字。而用来显示数字的格子应该在棋盘格的基础上的,所以初始化数字格的updateBoardView()应该在初始化棋盘格的init()方法最后来执行。
function updateBoardView() {
//首先清空之前的数字格布局内容
$(".number-cell").remove();
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
//向棋盘格上增加数字格
$("#grid-container").append("
");
var numberCell = $("#number-cell-" + i + "-" + j);
//如果棋盘格的值为0的话,设置数字格为高宽都为0
if (board[i][j] == 0) {
numberCell.css("width", "0px");
numberCell.css("height", "0px");
numberCell.css("top", getPosTop(i, j) + 100);
numberCell.css("left", getPosLeft(i, j) + 100);
}
//如果棋盘格的值不为0的话,设置数字格为高宽为75并设置背景色和前景色及数字值
else {
numberCell.css("width", "100px");
numberCell.css("height", "100px");
numberCell.css("top", getPosTop(i, j));
numberCell.css("left", getPosLeft(i, j));
numberCell.css("background-color",
getNumberBackgroundColor(board[i][j]));
numberCell.css("color", getNumberColor(board[i][j]));
numberCell.text(board[i][j]);
}
}
}
//设置数字值的字体样式
$(".number-cell").css("line-height", "100px");
$(".number-cell").css("font-size", "60px");
} 我们还需要在2048.css样式文件中,为number-cell数字格设置一些样式。 .number-cell {
border-radius: 6px;
font-family: Arial;
font-weight: bold;
font-size: 60px;
line-height: 100px;
text-align: center;
position: absolute;
} 数字格被初始化完毕之后,我们在页面效果上是看不到的。所以,我们要使用火狐浏览器的Firebug工具来查看是否初始化成功。
3.3. 随机生成数字
数字格初始化完成之后,我们需要做的就是在两个随机的数字格中生成两个随机的数字即可。这
个需求我利用generateOneNumber()方法来完成,完成这个方法需要进行四步完成: 第一步判断当前的格子是否是空的,如果不为空则返回false,否则返回true。 function generateOneNumber() {
if (nospace(board)) {
return false;
}
return true;
} 第二步随机一个格子。
function generateOneNumber() {
//随机一个x坐标的位置
var randx = parseInt(Math.floor(Math.random() * 4));
//随机一个y坐标的位置
var randy = parseInt(Math.floor(Math.random() * 4));
//定义一个死循环,完成生成随机空格子
while (true) {
//如果当前格子的值为0,满足条件
if (board[randx][randy] == 0) {
break;
}
//否则重新随机一个位置
var randx = parseInt(Math.floor(Math.random() * 4));
var randy = parseInt(Math.floor(Math.random() * 4));
}
} 第三步随机一个数字。
function generateOneNumber() {
//随机一个数字
var randNumber = Math.random() < 0.5 ? 2 : 4; } 第四步在随机格子中显示随机数字。
function generateOneNumber() {
//在随机位置显示随机数字
board[randx][randy] = randNumber;
//实现随机数字显示的动画
ShowNumberWithAnimation(randx, randy, randNumber); }
3.4. 初始化基础逻辑
在初始化棋盘格和数字格时,我们使用了getPosTop()方法和getPosLeft()方法来完成距顶端和
距左端的距离设置。
function getPosTop(i, j) {
return 20 + i * 120;
}
function getPosLeft(i, j) {
return 20 + j * 120;
}
在初始化数字格时,我们使用了getNumberBackgroundColor()方法来设置数字的背景色,使用
getNumberColor()方法来设置数字的前景色。
function getNumberBackgroundColor(number) {
switch (number) {
case 2:return "#eee4da";break;
case 4:return "#ede0c8";break;
case 8:return "#f2b179";break;
case 16:return "#f59563";break;
case 32:return "#f67c5f";break;
case 64:return "#f65e3b";break;
case 128:return "#edcf72";break;
case 256:return "#edcc61";break;
case 512:return "#9c0";break;
case 1024:return "#33b5e5";break;
case 2048:return "#09c";break;
case 4096:return "#a6c";break;
case 8192:return "#93c";break;
}
}
function getNumberColor(number) {
if (number <= 4) {
return "#776e65"
}
return "white";
}
在生成随机数字时,我们使用nospace()方法来判断当前格子是否为空。
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;
}
3.5. 初始化动画逻辑
在生成随机数字时,我们使用ShowNumberWithAnimation()方法来完成随机数字显示的动画逻辑。
function ShowNumberWithAnimation(i, j, randNumber) {
获取当前的数字格 //
var numberCell = $("#number-cell-" + i + "-" + j);
//设置当前的数字格的背景色和前景色及数字值
numberCell.css("background-color",
getNumberBackgroundColor(randNumber));
numberCell.css("color", getNumberColor(randNumber));
numberCell.text(randNumber);
//设置当前的数字格的显示动画
numberCell.animate({
width: "100px",
height: "100px",
top: getPosTop(i, j),
left: getPosLeft(i, j)
}, 50);
}
4. 游戏逻辑
4.1. 捕获键盘事件
《2048》游戏的操作主要是依靠键盘的上、下、左、右来完成,首先我们需要在game.js文件中
捕获键盘响应的事件。
$(document).keydown(function (event) {
switch (event.keyCode) {
case 37://left
break;
case 38://up
break;
case 39://right
break;
case 40://down
break;
default :
break;
}
});
键盘事件捕获到后,我们需要完成具体的游戏逻辑。首先,我们以向左移动为例,
分析
定性数据统计分析pdf销售业绩分析模板建筑结构震害分析销售进度分析表京东商城竞争战略分析
一下向左
的事情逻辑内容。
首先,我们需要判断是否可以向左移动,这里我们使用if判断语句完成。 $(document).keydown(function (event) {
switch (event.keyCode) {
case 37://left
if (moveLeft()) {}
break;
case 38://up
break;
case 39://right
break;
case 40://down
break;
default :
break;
}
});
如果可以的话,我们需要做两件事情:一件是生成两个新的随机数字,这个逻辑我们使用之前编
写的generateOneNumber()方法完成;一件是判断当移动之后游戏是否结束,这个逻辑我们编写
isgameover()方法完成。
$(document).keydown(function (event) {
switch (event.keyCode) {
case 37://left
if (moveLeft()) {
generateOneNumber();
isgameover();
}
break;
case 38://up
break;
case 39://right
break;
case 40://down
break;
default :
break;
}
});
4.2. 完成移动逻辑
下面我们以向左移动为例,来讲解具体的移动逻辑内容,完成moveLeft()方法逻辑。首先,我们
需要判断是否可以向左移动,我们使用canMoveLeft()方法来完成。
function moveLeft() {
if (!canMoveLeft(board)) {
return false;
}
return true;
}
如果可以向左移动的话,第一步,遍历数字格,判断除第一列外有哪些数字格的值是不为0的。
function moveLeft() {
if (!canMoveLeft(board)) {
return false;
}
//moveLeft
for (var i = 0; i < 4; i++) {
for (var j = 1; j < 4; j++) {
if (board[i][j] != 0) {
}
}
}
return true;
}
第二步,遍历当前值不为0的数字格左边数字格。
function moveLeft() {
if (!canMoveLeft(board)) {
return false;
}
//moveLeft
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++) {
}
}
}
}
return true;
} 第三步,向左移动逻辑还要分成两种情况,一种是当前值不为0的数字格左边的数字格必须值为
0并且中间的数字格必须值也为0,一种是当前值不为0的数字格与左边的数字格值相等并且中间的
数字格必须值也为0。
//判断当前值不为0的数字格左边的数字格必须值为0并且中间的数字格必须值也为0 if (board[i][k] == 0 && noBlokHorizontalCol(i, k, j, board)) {
continue;
}
//判断当前值不为0的数字格与左边的数字格值相等并且中间的数字格必须值也为0 else if (board[i][k] == board[i][j] && noBlokHorizontalCol(i, k, j,
board)) {
continue;
} 如果是当前值不为0的数字格左边的数字格必须值为0并且中间的数字格必须值也为0,具体逻
辑如下:
//move
showMoveAnimation(i, j, i, k);
board[i][k] = board[i][j];
board[i][j] = 0; 如果是当前值不为0的数字格与左边的数字格值相等并且中间的数字格必须值也为0,具体逻辑
如下:
//move
showMoveAnimation(i, j, i, k);
//add
board[i][k] += board[i][j];
board[i][j] = 0;
//add score
score += board[i][k];
updateScore(score);
当完成向左移动逻辑之后,我们需要重新初始化数字格布局。
updateBoardView(); 4.3. 游戏基础逻辑
在完成移动逻辑代码时,我们使用了canMoveLeft()方法来判断是否可以向左移动。我们将此方法定义在suppot.js文件中。
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;
} 在完成移动逻辑代码时,我们使用了noBlokHorizontalCol()方法来判断当前数字格左边的数字格是否值为0。
function noBlokHorizontalCol(row, col1, col2, board) {
for (var i = col1 + 1; i < col2; i++) {
if (board[row][i] != 0) {
return false;
}
}
return true;
} 4.4. 游戏动画逻辑
在完成移动逻辑代码时,我们使用了showMoveAnimation()方法来实现数字格移动的动画逻辑,
此方法我们定义在animation.js文件中。
function showMoveAnimation(fromx, fromy, tox, toy) {
var numberCell = $("#number-cell-" + fromx + "-" + fromy);
numberCell.animate({
top: getPosTop(tox, toy),
left: getPosLeft(tox, toy)
}, 200);
}
5. 游戏优化
5.1. GameOver部分
下面我们来分析游戏是如何结束的。一种情况是棋盘格中没有空的格子了,一种情况是棋盘格中
没有可以移动的格子了。
首先,完成isgameover()方法的逻辑。
function isgameover() {
if (nospace(board) && nomove(board)) {
gameover();
}
}
其次,完成棋盘格中没有空的格子。
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 (canMoveDown(board) ||
canMoveLeft(board) ||
canMoveRight(board) ||
canMoveUp(board)) {
return false;
}
return true;
}
最后,完成游戏结束的逻辑。
function gameover() {
alert("gameover!");
} 5.2. 加入Score
下面,我们增加游戏分数。首先,我们需要在main.js文件定义board变量后,定义score变量来表示游戏分数。
在移动数字格时,如果两个数字格的值相等的话,我们就需要更新游戏分数(游戏分数为两个数字格的数字值相加)。我们以向左移动为例,下面的代码就是增加对应的游戏分数:
//add score
score += board[i][k];
updateScore(score);
在完成移动逻辑代码时,我们使用了updateScore()方法来实现游戏分数值的更新动画逻辑,此方法我们同样定义在animation.js文件中。
function updateScore(score) {
$("#score").text(score);
} 5.3. 让游戏和原版一致
到此,我们的《2048》游戏中,还有一个bug。就是当一行的4个格子的值为2、2、4、8的时候,如果向左移动,原版游戏的结果为4、4、8,而我们现在的游戏为16。导致这个问题的原因是2和2合并后为4,4又和第三个格子中的4进行合并为8,8再和第四个格子里的8进行合并。而原版游戏中,只能合并一次。所以,我们还需要加以控制。
首先,我们在main.js文件中,同样定义一个二维数组hasConflicted。
var hasConflicted = new Array();
其次,我们在init()方法中,将hasConflicted数组定义为二维数组,并初始化为false。 function init() {
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] = false;
}
}
} 其三,我们需要在初始化数字格updateBoardView()方法中,将每一个数字格的hasConflicted
的值设置为false。
function updateBoardView() {
$(".number-cell").remove();
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
$("#grid-container").append("
");
var numberCell = $("#number-cell-" + i + "-" + j);
if (board[i][j] == 0) {
} else {
}
hasConflicted[i][j] = false;
}
}
} 其四,当我们真正移动数字格,如果两个数字格的值相等时,我们需要增加当前格子是否合并后
的判断。
else if (board[i][k] == board[i][j] && noBlokHorizontalCol(i, k, j,
board)&&!hasConflicted[i][k]) 如果当前两个数字格合并之后,需要将hasConflicted值设置为true,表示当前这个数字格不能
再合并。
else if (board[i][k] == board[i][j] && noBlokHorizontalCol(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];
updateScore(score);
hasConflicted[i][k] = true;
continue;
} 5.4. 优化GameOver
之前的GameOver,我们只是弹出提示框。效果上并不很好。现在,我们来优化一下GameOver部分,让游戏结束变得更漂亮一些。
首先,我们来修改一下gameover()方法。
function gameover() {
$("#grid-container").append("
");
var gameover = $("#gameover");
gameover.css("width", "500px");
gameover.css("height", "500px");
gameover.css("background-color", "rgba(0, 0, 0, 0.5)"); } 然后,我们来设置一下游戏结束提示的样式。
.gameover{
display: block;
margin: 0 auto;
width: 500px;
text-align: center;
vertical-align: middle;
position: absolute;
}
.gameover p {
font-family: Arial;
font-size: 50px;
color: white;
margin: 20px auto;
margin-top: 150px;
}
.gameover span {
font-family: Arial;
font-size: 50px;
color: white;
margin: 20px auto;
}
#restartgamebutton {
display: block;
margin: 20px auto;
width: 180px;
padding: 10px 10px;
background-color: #8f7a66;
font-family: Arial;
font-size: 30px;
color: white;
border-radius: 10px;
text-decoration: none; }
#restartgamebutton:hover {
background-color: #9f8b77; }
其次,我们来完成restartgame()方法的逻辑。
function restartgame(){
$("#gameover").remove();
updateScore(0);
newgame();
}