前端小游戏2048(一步步详解附带源代码,源码上传到csdn,可以免费下载)
2048小游戏
2048是前端开发必经的一个小游戏,2048小游戏包含了HTML,CSS和JavaScript。
简介
《2048》,是一款益智小游戏,这款游戏是由年仅19岁的意大利程序员加布里勒希鲁尼(Gabriele Cirulli)开发出来的,官方版本只能在网页上或通过其移动网站运行。 2048游戏共有16个格子,初始时会有两个格子上安放了两个数字2,每次可以选择上下左右其中一个方向去滑动,每滑动一次,所有的数字方块都会往滑动的方向靠拢外,系统也会在空白的地方随即出现一个数字方块,相同数字的方块在靠拢、相撞时会相加。系统给予的数字方块不是2就是4,玩家要想办法在这小小的16格范围中凑出“2048”这个数字方块。
效果图
游戏结束弹出遮罩层显示
代码部分
首先是html部分
<p class="grade">分数:<span id="score01">999999999</span> </p>
<div class="all">
<div class="cell n2" id="c00">2</div>
<div class="cell n4" id="c01">4</div>
<div class="cell n8" id="c02">8</div>
<div class="cell n16" id="c03">16</div>
<div class="cell n32" id="c10">32</div>
<div class="cell n64" id="c11">64</div>
<div class="cell n128" id="c12">128</div>
<div class="cell n256" id="c13">256</div>
<div class="cell n512" id="c20">512</div>
<div class="cell n1024" id="c21">1024</div>
<div class="cell n2048" id="c22">2048</div>
<div class="cell n4096" id="c23">4096</div>
<div class="cell n8192" id="c30">8192</div>
<div class="cell" id="c31"></div>
<div class="cell" id="c32"></div>
<div class="cell" id="c33"></div>
</div>
<div class="gameover">
<p>
游戏结束!<br> 分数:<span id="score02">999999999</span> <br>
<a href="">再来一次</a>
</p>
</div>
html样式部分代码
* {
padding: 0;
margin: 0;
font-family: Arial;
text-decoration: none;
}
body {
background-color: #FAF8EF;
}
.grade {
width: 500px;
margin: 0 auto;
margin-top: 50px;
font-size: 40px;
text-align: center;
font-weight: bold;
color: #776E65;
}
.all {
width: 500px;
height: 500px;
margin: auto;
background-color: #BBADA0;
border-radius: 10px;
}
.cell {
width: 100px;
height: 100px;
margin-top: 20px;
margin-left: 20px;
background-color: #ccc0b3;
float: left;
border-radius: 5px;
font-size: 24px;
font-weight: bold;
color: #776E65;
line-height: 100px;
text-align: center;
}
.n2 {
background-color: #eee3da;
}
.n4 {
background-color: #ede0c8;
}
.n8 {
background-color: #f2b179;
}
.n16 {
background-color: #f59563;
}
.n32 {
background-color: #f67c5f;
}
.n64 {
background-color: #f65e3b;
}
.n128 {
background-color: #edcf72;
}
.n256 {
background-color: #edcc61;
}
.n512 {
background-color: #9c0;
}
.n1024 {
background-color: #33b5e5;
}
.n2048 {
background-color: #09c;
}
.n4096 {
background-color: #a6c;
}
.n8192 {
background-color: #93c;
}
.gameover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.3);
}
.gameover p {
width: 400px;
height: 300px;
background-color: white;
position: absolute;
top: 50%;
left: 50%;
margin-top: -150px;
margin-left: -200px;
border: solid 1px black;
border-radius: 10px;
font-size: 40px;
line-height: 100px;
text-align: center;
}
.gameover p a {
background-color: #8F7A66;
border-radius: 5px;
padding: 15px;
color: white;
}
下面是2048核心js代码了
var game = {
data: [], //存放数据
score: 0, //分数
status: 0, //当前状态,时刻的监听,时刻的需要改变 游戏运行中的状态,结束的状态
gameover: 0,
gamerunning: 1,
start: function() {}
randomNum: function() {}
dataView: function() {}
isgameover: function() {}
moveLeft: function() {}
moveLeftInRow: function(r) {} //单独处理每一行的逻辑
getNextInRow: function(r, c) {}
moveRight: function() {}
moveRightInRow: function(r) { }//单独处理每一行的逻辑
getNextInRowa: function(r, c) {}
moveTop: function() {}
moveTopInRow: function(c) {}
getNextInRowaa: function(r, c) {}
moveButtom: function() {}
moveButtomInRow: function(c) {}
getNextInRowaaa: function(r, c) {}
}
开始写各个函数
开始游戏的方法
start: function() {
this.score = 0;
this.data = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
this.status = this.gamerunning;
this.randomNum()
this.randomNum()
this.dataView()
}
随机数的方法,随机生成数字
randomNum: function() {
for (;;) {
var r = Math.floor(Math.random() * 4);
var c = Math.floor(Math.random() * 4);
if (this.data[r][c] == 0) {
var num = Math.random() > 0.2 ? 2 : 4;
this.data[r][c] = num;
break;
}
}
}
实时更新的视图
dataView: function() {
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
var div = document.getElementById('c' + r + c);
if (this.data[r][c] != 0) {
div.innerHTML = this.data[r][c];
div.className = 'cell n' + this.data[r][c]
} else {
div.innerHTML = ''
div.className = 'cell'
}
}
}
document.getElementById('score01').innerHTML = this.score; //设置游戏分数
// 监测游戏状态
if (this.status == this.gameover) {
document.getElementById('score02').innerHTML = this.score;
document.getElementsByClassName('gameover')[0].style.display = 'block'
} else {
document.getElementsByClassName('gameover')[0].style.display = 'none'
}
}
判断游戏是否结束的方法 游戏没结束返回false 结束返回true
isgameover: function() {
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
// 没有结束,三种情况::1.数组中还有0 2.左右相邻的有相同的 3.上下相邻有相同的
if (this.data[r][c] == 0) {
return false
}
if (c < 3) {
if (this.data[r][c] == this.data[r][c + 1]) {
return false
}
}
if (r < 3) {
if (this.data[r][c] == this.data[r + 1][c]) {
return false
}
}
}
}
return true; //表示游戏已经结束
}
左移动
moveLeft: function() {
var before = String(this.data) //移动之前
//处理移动的逻辑
for (var r = 0; r < 4; r++) {
this.moveLeftInRow(r);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveLeftInRow: function(r) { //单独处理每一行的逻辑
for (var c = 0; c < 3; c++) {
var nextc = this.getNextInRow(r, c);
if (nextc != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[r][nextc];
this.data[r][nextc] = 0;
c--;
} else if (this.data[r][c] == this.data[r][nextc]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[r][nextc] = 0
}
} else {
break;
}
}
},
getNextInRow: function(r, c) {
for (var i = c + 1; i < 4; i++) {
if (this.data[r][i] != 0) {
return i
}
}
return -1;
}
右移动,上移动,下移动和左移动的代码相似
// 右移动
moveRight: function() {
var before = String(this.data) //移动之前
for (var r = 3; r >= 0; r--) {
this.moveRightInRow(r);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveRightInRow: function(r) { //单独处理每一行的逻辑
for (var c = 3; c >= 0; c--) {
var nextc = this.getNextInRowa(r, c);
if (nextc != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[r][nextc];
this.data[r][nextc] = 0;
c++;
} else if (this.data[r][c] == this.data[r][nextc]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[r][nextc] = 0
}
} else {
break;
}
}
},
getNextInRowa: function(r, c) {
for (var i = c - 1; i >= 0; i--) {
if (this.data[r][i] != 0) {
return i
}
}
return -1;
},
// 上移动
moveTop: function() {
var before = String(this.data) //移动之前
for (var c = 0; c < 4; c++) {
this.moveTopInRow(c);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveTopInRow: function(c) { //单独处理每一列的逻辑
for (var r = 0; r < 3; r++) {
var nextr = this.getNextInRowaa(r, c);
if (nextr != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[nextr][c];
this.data[nextr][c] = 0;
r--;
} else if (this.data[r][c] == this.data[nextr][c]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[nextr][c] = 0
}
} else {
break;
}
}
},
getNextInRowaa: function(r, c) {
for (var i = r + 1; i < 4; i++) {
if (this.data[i][c] != 0) {
return i
}
}
return -1;
},
// 下移动
moveButtom: function() {
var before = String(this.data) //移动之前
for (var c = 3; c >= 0; c--) {
this.moveButtomInRow(c);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveButtomInRow: function(c) { //单独处理每一列的逻辑
for (var r = 3; r >= 0; r--) {
var nextr = this.getNextInRowaaa(r, c);
if (nextr != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[nextr][c];
this.data[nextr][c] = 0;
r++;
} else if (this.data[r][c] == this.data[nextr][c]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[nextr][c] = 0
}
} else {
break;
}
}
},
getNextInRowaaa: function(r, c) {
for (var i = r - 1; i >= 0; i--) {
if (this.data[i][c] != 0) {
return i
}
}
return -1;
},
}
调用开始函数
game.start()
绑定键盘上下左右事件(37,38,39,40分别对应键盘左上右下键)
document.onkeydown = function(e) {
if (e.keyCode == 37) {
game.moveLeft()
}
if (e.keyCode == 39) {
game.moveRight()
}
if (e.keyCode == 38) {
game.moveTop()
}
if (e.keyCode == 40) {
game.moveButtom()
}
}
最后,给再来一次绑定事件
zai = function() {
game.start()
}
以上就是2048小游戏的全部代码。希望大家也可以动手做出这个小游戏玩玩。
整体代码
html–index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./css/index.css">//引用代码的时候注意路径准确性
<link rel="shortcut icon" href="https://www.2048.org/favicon.ico">//添加一个2048小图标
<title>2048</title>
</head>
<body>
<p class="grade">分数:<span id="score01">000</span> </p>
<div class="all">
<div class="cell n2" id="c00">2</div>
<div class="cell n4" id="c01">4</div>
<div class="cell n8" id="c02">8</div>
<div class="cell n16" id="c03">16</div>
<div class="cell n32" id="c10">32</div>
<div class="cell n64" id="c11">64</div>
<div class="cell n128" id="c12">128</div>
<div class="cell n256" id="c13">256</div>
<div class="cell n512" id="c20">512</div>
<div class="cell n1024" id="c21">1024</div>
<div class="cell n2048" id="c22">2048</div>
<div class="cell n4096" id="c23">4096</div>
<div class="cell n8192" id="c30">8192</div>
<div class="cell" id="c31"></div>
<div class="cell" id="c32"></div>
<div class="cell" id="c33"></div>
</div>
<div class="gameover">
<p>
游戏结束!<br> 分数:<span id="score02">999999999</span> <br>
<a href="">再来一次</a>
</p>
</div>
<script src="./js/index.js"></script>//引用代码的时候注意路径准确性
</body>
</html>
css–index.css
* {
padding: 0;
margin: 0;
font-family: Arial;
text-decoration: none;
}
body {
background-color: #FAF8EF;
}
.grade {
width: 500px;
margin: 0 auto;
margin-top: 50px;
font-size: 40px;
text-align: center;
font-weight: bold;
color: #776E65;
}
.all {
width: 500px;
height: 500px;
margin: auto;
background-color: #BBADA0;
border-radius: 10px;
}
.cell {
width: 100px;
height: 100px;
margin-top: 20px;
margin-left: 20px;
background-color: #ccc0b3;
float: left;
border-radius: 5px;
font-size: 24px;
font-weight: bold;
color: #776E65;
line-height: 100px;
text-align: center;
}
.n2 {
background-color: #eee3da;
}
.n4 {
background-color: #ede0c8;
}
.n8 {
background-color: #f2b179;
}
.n16 {
background-color: #f59563;
}
.n32 {
background-color: #f67c5f;
}
.n64 {
background-color: #f65e3b;
}
.n128 {
background-color: #edcf72;
}
.n256 {
background-color: #edcc61;
}
.n512 {
background-color: #9c0;
}
.n1024 {
background-color: #33b5e5;
}
.n2048 {
background-color: #09c;
}
.n4096 {
background-color: #a6c;
}
.n8192 {
background-color: #93c;
}
.gameover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.3);
}
.gameover p {
width: 400px;
height: 300px;
background-color: white;
position: absolute;
top: 50%;
left: 50%;
margin-top: -150px;
margin-left: -200px;
border: solid 1px black;
border-radius: 10px;
font-size: 40px;
line-height: 100px;
text-align: center;
}
.gameover p a {
background-color: #8F7A66;
border-radius: 5px;
padding: 15px;
color: white;
}
js–index.js
var game = {
data: [], //存放数据
score: 0, //分数
status: 0, //当前状态,时刻的监听,时刻的需要改变 游戏运行中的状态,结束的状态
gameover: 0,
gamerunning: 1,
// 开始游戏的方法
start: function() {
this.score = 0;
this.data = [
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0]
]
this.status = this.gamerunning;
this.randomNum()
this.randomNum()
this.dataView()
},
// 随机数的方法
randomNum: function() {
for (;;) {
var r = Math.floor(Math.random() * 4);
var c = Math.floor(Math.random() * 4);
if (this.data[r][c] == 0) {
var num = Math.random() > 0.2 ? 2 : 4;
this.data[r][c] = num;
break;
}
}
},
// 更新的视图
dataView: function() {
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
var div = document.getElementById('c' + r + c);
if (this.data[r][c] != 0) {
div.innerHTML = this.data[r][c];
div.className = 'cell n' + this.data[r][c]
} else {
div.innerHTML = ''
div.className = 'cell'
}
}
}
document.getElementById('score01').innerHTML = this.score; //设置游戏分数
// 监测游戏状态
if (this.status == this.gameover) {
document.getElementById('score02').innerHTML = this.score;
document.getElementsByClassName('gameover')[0].style.display = 'block'
} else {
document.getElementsByClassName('gameover')[0].style.display = 'none'
}
},
// 判断游戏是否结束的方法 游戏没结束返回false 结束返回true
isgameover: function() {
for (var r = 0; r < 4; r++) {
for (var c = 0; c < 4; c++) {
// 没有结束,三种情况::1.数组中还有0 2.左右相邻的有相同的 3.上下相邻有相同的
if (this.data[r][c] == 0) {
return false
}
if (c < 3) {
if (this.data[r][c] == this.data[r][c + 1]) {
return false
}
}
if (r < 3) {
if (this.data[r][c] == this.data[r + 1][c]) {
return false
}
}
}
}
return true; //表示游戏已经结束
},
// 左移动
moveLeft: function() {
var before = String(this.data) //移动之前
//处理移动的逻辑
for (var r = 0; r < 4; r++) {
this.moveLeftInRow(r);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveLeftInRow: function(r) { //单独处理每一行的逻辑
// 0200 2000
// 0220 4000
// 2202 4200
// 2222 4022 4202 4220 4400
for (var c = 0; c < 3; c++) {
var nextc = this.getNextInRow(r, c);
if (nextc != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[r][nextc];
this.data[r][nextc] = 0;
c--;
} else if (this.data[r][c] == this.data[r][nextc]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[r][nextc] = 0
}
} else {
break;
}
}
},
getNextInRow: function(r, c) {
for (var i = c + 1; i < 4; i++) {
if (this.data[r][i] != 0) {
return i
}
}
return -1;
},
// 右移动
moveRight: function() {
var before = String(this.data) //移动之前
for (var r = 3; r >= 0; r--) {
this.moveRightInRow(r);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveRightInRow: function(r) { //单独处理每一行的逻辑
for (var c = 3; c >= 0; c--) {
var nextc = this.getNextInRowa(r, c);
if (nextc != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[r][nextc];
this.data[r][nextc] = 0;
c++;
} else if (this.data[r][c] == this.data[r][nextc]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[r][nextc] = 0
}
} else {
break;
}
}
},
getNextInRowa: function(r, c) {
for (var i = c - 1; i >= 0; i--) {
if (this.data[r][i] != 0) {
return i
}
}
return -1;
},
// 上移动
moveTop: function() {
var before = String(this.data) //移动之前
for (var c = 0; c < 4; c++) {
this.moveTopInRow(c);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveTopInRow: function(c) { //单独处理每一列的逻辑
for (var r = 0; r < 3; r++) {
var nextr = this.getNextInRowaa(r, c);
if (nextr != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[nextr][c];
this.data[nextr][c] = 0;
r--;
} else if (this.data[r][c] == this.data[nextr][c]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[nextr][c] = 0
}
} else {
break;
}
}
},
getNextInRowaa: function(r, c) {
for (var i = r + 1; i < 4; i++) {
if (this.data[i][c] != 0) {
return i
}
}
return -1;
},
// 下移动
moveButtom: function() {
var before = String(this.data) //移动之前
for (var c = 3; c >= 0; c--) {
this.moveButtomInRow(c);
}
var after = String(this.data) //移动之后
if (before != after) {
this.randomNum()
if (this.isgameover()) {
this.status = this.gameover;
}
this.dataView()
}
},
moveButtomInRow: function(c) { //单独处理每一列的逻辑
for (var r = 3; r >= 0; r--) {
var nextr = this.getNextInRowaaa(r, c);
if (nextr != -1) {
if (this.data[r][c] == 0) {
this.data[r][c] = this.data[nextr][c];
this.data[nextr][c] = 0;
r++;
} else if (this.data[r][c] == this.data[nextr][c]) {
this.data[r][c] *= 2;
this.score += this.data[r][c]
this.data[nextr][c] = 0
}
} else {
break;
}
}
},
getNextInRowaaa: function(r, c) {
for (var i = r - 1; i >= 0; i--) {
if (this.data[i][c] != 0) {
return i
}
}
return -1;
},
}
game.start()
document.onkeydown = function(e) {
if (e.keyCode == 37) {
game.moveLeft()
}
if (e.keyCode == 39) {
game.moveRight()
}
if (e.keyCode == 38) {
game.moveTop()
}
if (e.keyCode == 40) {
game.moveButtom()
}
}
zai = function() {
game.start()
}
本次2048小游戏的所有代码就放在这里了,2048的源码我也上传到csdn了,有需要的朋友可以免费下载,如果找不到,可以在评论区留言,我也可以直接发给大家!谢谢!如果代码有什么不足的希望大家及时交流,补充,谢谢大家!
本文地址:https://blog.csdn.net/yf19990720/article/details/107520685
上一篇: python读取xml文件方法解析
下一篇: 前端实用小利器 —— Snipaste