2048小游戏

Posted jiapei

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2048小游戏相关的知识,希望对你有一定的参考价值。

对于2048这个游戏,我曾一度沉迷于其中,然而最好的战绩却也是止步于512,这让我羞愧不已。

规则如下:

二维数组

1、手指向一个方向滑动,所有格子会向那个方向运动。

2、相同数字的两个格子,相撞时数字会相加。

3、每次滑动时,空白处会随机刷新出一个数字的格子。

4、当界面不可运动时(当界面全部被数字填满时),游戏结束;当界面中最大数字是2048时,游戏胜利。


如今,我利用了一些空些时间,整理了一下思路,准备创作了这个小游戏,要求只有一个,便是麻雀虽小但要五脏俱全。


整体的界面:分为4*4方格,然后定义每个方格中的属性:用于显示数字和一个自定义的Object对象。

然后创建三类数组,一类是整体数组,存放所有的方格。
还有一类就是方向数组,存放每个方向的方格,方便手势的响应。
最后一类,就是用来临时取值赋值的临时数组。


目前来讲我想到的操作有

1 移除临时数组中所有元素
2 循环取出方向数组中的元素
3 执行对应的手势方向平移操作
4 判断是否可以相加
5 修改相加之后的值
6 调用随机函数 随机产生数字(只在没有数字的方格产生)

 现在我们开始构建2048游戏的HTML框架

<div class="all">
<div class="top">
<span>2048</span>
<p>Score</p>
<div id="Score"></div>
<a href="2048.html">大爷,咱重头再来</a>
<div class="max">
<p>Best</p>
<div id="Best"></div>
</div>
</div>
<div id="onclick">
<div class="div_01 nj" id="c00"></div>
<div class="div_01 nj" id="c01"></div>
<div class="div_01 nj" id="c02"></div>
<div class="div_01 nj" id="c03"></div>

<div class="div_01 nj" id="c10"></div>
<div class="div_01 nj" id="c11"></div>
<div class="div_01 nj" id="c12"></div>
<div class="div_01 nj" id="c13"></div>

<div class="div_01 nj" id="c20"></div>
<div class="div_01 nj" id="c21"></div>
<div class="div_01 nj" id="c22"></div>
<div class="div_01 nj" id="c23"></div>

<div class="div_01 nj" id="c30"></div>
<div class="div_01 nj" id="c31"></div>
<div class="div_01 nj" id="c32"></div>
<div class="div_01 nj" id="c33"></div>
</div>
<div id="cover"></div>
<div id="cover1">
<button onclick="location=‘www.baidu.com‘">Leave</button>
</div>
<div id=‘cover2‘>Game over!</div>
<div id="cover3">
<button onclick="jie.start()">Try again</button>
</div>
</div>
<script src=‘2048.js‘></script>

框架搭建完成,接着便是css样式的美观

.all

width: 600px;
height: 750px;
margin: auto;

.top
width: 600px;
min-width: 600px;
height: 150px;
margin: auto;
position: relative;

#Score
font-size: 40px;
color: red;
width: 175px;
height: 75px;
line-height: 75px;
text-align: center;
position: absolute;
top: 63px;
left: 425px;

.top span
font-size: 80px;
color: #0edad3;

.top p
font-size: 40px;
position: absolute;
top: -25px;
left: 470px;
color: red;

.top a
text-decoration: none;
font-size: 24px;
font-weight: bold;
font-family: ‘楷体‘;
display: inline-block;
width: 200px;
height: 50px;
line-height: 50px;
text-align: center;
border-radius: 7px;
position: absolute;
left: 0px;
top: 100px;
color: black;

.top a:hover
cursor: pointer;
color: red;

.max
width: 150px;
height: 140px;
position: absolute;
top: 10px;
left: 680px;

.max p
font-size: 40px;
position: absolute;
top: -35px;
left: -360px;
color: blue;

#Best
font-size: 40px;
color: blue;
width: 175px;
height: 75px;
line-height: 75px;
text-align: center;
position: absolute;
top: 61px;
left: -415px;

#onclick
width: 600px;
min-width: 600px;
height: 600px;
background-image: url(img/01.jpg);
background-repeat: no-repeat;
background-size: cover;
margin: auto;
border-radius: 5px;
/*z-index: 10;*/

#cover
width: 600px;
min-width: 600px;
height: 600px;
border-radius: 5px;
position: absolute;
background-color: gray;
top: 158px;
opacity: 0.4;
display: none;

#cover2
width: 600px;
height: 140px;
font-size: 75px;
line-height: 140px;
font-weight: bold;
text-align: center;
opacity: 1;
position: absolute;
top:380px;
display: none;

#cover3
display: none;

#cover3>button
width: 150px;
height: 50px;
font-size: 20px;
cursor: pointer;
background-color: #8f7a66;
color: white;
border:0px;
position: absolute;
top: 550px;
left: 530px;

#cover1
display: none;

#cover1>button
width: 150px;
height: 50px;
font-size: 20px;
cursor: pointer;
background-color: #8f7a66;
color: white;
border:0px;
position: absolute;
top: 550px;
left: 700px;

.div_01
width: 120px;
height: 120px;
margin: 15px;
text-align: center;
line-height: 120px;
/*background-color: #cdc1b4;*/
float: left;
border-radius: 5px;
font-size: 45px;

.n2background-color:#eee3da
.n4background-color:#ede0c8
.n8background-color:#f2b179
.n16background-color:#f59563
.n32background-color:#f67c5f
.n64background-color:#f65e3b
.n128background-color:#edcf72
.n256background-color:#edcc61
.n512background-color:#9c0
.n1024background-color:#33b5e5
.n2048background-color:#09c
.n4096background-color:#a6c
.n8192background-color:#93c
.n2,.n4color:#776e65
.n1024,.n2048,.n4096,.n8192font-size:40px

 

最后便是js的执行,用来判断游戏是否结束亦或是继续,以及游戏是否成功(有数字达到2048)

var jie =
data:null,RN:4,CN:4,
score: 0,count:0,Best:0,
start()
this.score = 0;
this.data = [];
// 遍历data二维数组,将内容默认为0
for(var r = 0;r < this.RN; r++)
this.data[r] = [];
for(var c = 0; c < this.CN; c++)
this.data[r][c] = 0;


// 调用各种方法
this.randomNum();
this.randomNum();
this.uptateView();
this.decideEnd();
// 按键触发,根据按键来确定执行的函数
document.onkeydown = function(e)
switch (e.keyCode)
case 37:
jie.moveLeft();
break;
case 38:
jie.moveTop();
break;
case 39:
jie.moveRight();
break;
case 40:
jie.moveButton();
break;


// 将遮挡物隐藏
document.getElementById(`cover`).style = ‘display:none;‘
document.getElementById(`cover1`).style = ‘display:none;‘
document.getElementById(`cover2`).style = ‘display:none;‘
document.getElementById(`cover3`).style = ‘display:none;‘
,
decideEnd()//判断2048小游戏是否结束
this.count = 0;
for(var r = 0;r < this.RN; r++)//遍历data数组,累计数组内元素不为零的个数
for(var c = 0; c < this.CN; c++)
if(this.data[r][c] != 0)
this.count += 1;



if(this.count == 16)//data数组里的元素全不为零是
this.data[-1] = 0;
this.data[4] = 0;
var is = true;
for (var i = 0;i < 4;i++) //判断data数组中的任何一个元素与其四周的是否相等
for (var j = 0;j < 4;j++)
if (this.data[i][j] == this.data[i][j-1] || this.data[i][j] == this.data[i][j+1] || this.data[i][j] == this.data[i+1][j] || this.data[i][j] == this.data[i-1][j])
is = false;
break;



if(is)//确定data内元素无法再次移动,将遮挡物显示出来
document.getElementById(`cover`).style = ‘display:inline-block;‘
document.getElementById(`cover1`).style = ‘display:inline-block;‘
document.getElementById(`cover2`).style = ‘display:inline-block;‘
document.getElementById(`cover3`).style = ‘display:inline-block;‘


,
randomNum()
while(true)
// 随机产生两个数,确定随机得到的二维数组的位置
var r = Math.floor(Math.random()*(this.RN));
var c = Math.floor(Math.random()*(this.CN));
// 确认随机得到的数组位置里的值是否为默认值0
if(this.data[r][c] === 0)
// 判断随机数j的区间,来给定随机数是2还是4
var j = Math.random();
if(j < 0.9)
this.data[r][c] = 2;
document.getElementById(`c$r$c`).innerHTML = this.data[r][c];
break;
else
this.data[r][c] = 4;
document.getElementById(`c$r$c`).innerHTML = this.data[r][c];
break;

else
// 仅仅退出本次循环
continue;


,
uptateView()
// 遍历二维数组data
for(var r = 0; r < this.RN; r++)
for(var c = 0; c < this.CN; c++)
// 通过ID选择器找到二维数组在页面中对应的div
var div = document.getElementById(`c$r$c`);
// 将目前二维数组位置的值赋给j
var j = this.data[r][c];
// 判断j是否为默认值0
if(j == 0)
// j为默认值时,清空div内的内容,且将背景颜色转为默认的背景颜色
div.innerHTML = ‘‘;
div.className = ‘div_01‘;
else
// 否则,将j的值在页面中对应的div输出,背景颜色转为与j值相对应的颜色
div.innerHTML = j;
div.className = ‘div_01 n‘+j;



//将当前分数与最高分在页面中显示
document.getElementById(‘Score‘).innerHTML = this.score;
document.getElementById(‘Best‘).innerHTML = this.Best;
,
moveLeft()//记录移动前后的data数组,如果一样则不能移动
var before = this.data.toString();
for(var r = 0; r < this.RN; r++)
this.moveLeftNow(r);

var after = this.data.toString();
if(before != after)
// 调用一个随机数并进行页面的数据更新,且确定游戏是否结束
this.randomNum();
this.uptateView();
this.decideEnd();

,
moveLeftNow(r)
var nextc = 0;
var i;//遍历data数组,确定相邻的值是否相等
for(var c = 0; c < this.CN-1; c++)
for( i = c+1; i < this.CN; i++)
if(this.data[r][i] != 0)//退出i的循环
nextc = this.data[r][i];
break;
else//一行的值都为0时,将nextc赋值为-1
nextc = -1;


if(nextc == -1)
break;//结束c的循环,进入r的下一行循环
else if(this.data[r][c] == 0)//将后面的不为0的值赋予前面为0的位置
this.data[r][c] = this.data[r][i];
this.data[r][i] = 0;//将已经赋值的位置值设置为0
c--;
else if(this.data[r][c] == this.data[r][i])//若两个相等的数之间除了0没有其他数
this.data[r][c] = this.data[r][c]*2;
this.data[r][i] = 0;//将前面的数值*2,后面的清零
this.score += this.data[r][c];

if(this.Best <= this.score)//如果最高分小于当前分数
this.Best = this.score;//将当前分数赋值给最高分


,
moveTop()
var before = this.data.toString();
for(var c = 0; c < this.CN; c++)
this.moveTopNow(c);

var after = this.data.toString();
if(before != after)
this.randomNum();
this.uptateView();
this.decideEnd();

,
moveTopNow(c)
var nextc = 0;
var i;
for(var r = 0; r < this.CN-1; r++)
for( i = r+1; i < this.CN; i++)
if(this.data[i][c] != 0)
nextc = this.data[i][c];
break;
else
nextc = -1;


if(nextc == -1)
break;
else if(this.data[r][c] == 0)
this.data[r][c] = this.data[i][c];
this.data[i][c] = 0;
r--;
else if(this.data[r][c] == this.data[i][c])
this.data[r][c] = this.data[r][c]*2;
this.score += this.data[r][c];
this.data[i][c] = 0;

if(this.Best <= this.score)
this.Best = this.score;


,
moveRight()
var before = this.data.toString();
for(var r = 0; r < this.RN; r++)
this.moveRightNow(r);

var after = this.data.toString();
if(before != after)
this.randomNum();
this.uptateView();
this.decideEnd();

,
moveRightNow(r)
var nextc = 0;
var i;
for(var c = this.CN-1; c >= 1; c--)
for( i = c-1; i >= 0; i--)
if(this.data[r][i] != 0)
nextc = this.data[r][i];
break;
else
nextc = -1;


if(nextc == -1)
break;
else if(this.data[r][c] == 0)
this.data[r][c] = this.data[r][i];
this.data[r][i] = 0;
c++;
else if(this.data[r][c] == this.data[r][i])
this.data[r][c] = this.data[r][c]*2;
this.score += this.data[r][c];
this.data[r][i] = 0;

if(this.Best <= this.score)
this.Best = this.score;


,
moveButton()
var before = this.data.toString();
for(var c = 0; c < this.CN; c++)
this.moveButtonNow(c);

var after = this.data.toString();
if(before != after)
this.randomNum();
this.uptateView();
this.decideEnd();

,
moveButtonNow(c)
var nextc = 0;
var i;
for(var r = this.CN-1; r >= 1 ; r--)
for( i = r-1; i >= 0; i--)
if(this.data[i][c] != 0)
nextc = this.data[i][c];
break;
else
nextc = -1;


if(nextc == -1)
break;
else if(this.data[r][c] == 0)
this.data[r][c] = this.data[i][c];
this.data[i][c] = 0;
r++;
else if(this.data[r][c] == this.data[i][c])
this.data[r][c] = this.data[r][c]*2;
this.score += this.data[r][c];
this.data[i][c] = 0;

if(this.Best <= this.score)
this.Best = this.score;


,

jie.start();

2048小游戏便这样完成了

 

以上是关于2048小游戏的主要内容,如果未能解决你的问题,请参考以下文章

Qt 制作2048小游戏

2048小游戏竟然还有3D版?使用MATLAB制作一款3D版2048小游戏

2048小游戏竟然还有3D版?使用MATLAB制作一款3D版2048小游戏

如何在CentOS上安装一个2048小游戏

2048小游戏用例图

2048小游戏