2019.8.8 2048小游戏

本次为2048的小游戏制作,运用了之前的HTML+CSS以及现在的Jascript部分知识

目的是巩固之前所学内容,掌握现在的新知识,以及对面向对象能有进一步的理解

下面为html,css和JS三大页面:

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>2048</title>
<link rel="stylesheet" type="text/css" href="game.css">
</head>
<body>
<p class="game">2048小游戏</p>
<div class="block">
<p>Score:<span id="ScoreNum"></span></p>
<a href="">开始</a>
</div>
<div id="box">
<div class='cell' id="c00"></div>
<div class='cell' id="c01"></div>
<div class='cell' id="c02"></div>
<div class='cell' id="c03"></div>

<div class='cell' id="c10"></div>
<div class='cell' id="c11"></div>
<div class='cell' id="c12"></div>
<div class='cell' id="c13"></div>

<div class='cell' id="c20"></div>
<div class='cell' id="c21"></div>
<div class='cell' id="c22"></div>
<div class='cell' id="c23"></div>

<div class='cell' id="c30"></div>
<div class='cell' id="c31"></div>
<div class='cell' id="c32"></div>
<div class='cell' id="c33"></div>
</div>
<div class="gameover" id="over">
<div>
<h1>GAME OVER</h1>
<a href=''>TRY AGAIN</a>
</div>
</div>
<script src='game.js'></script>
</body>
</html>

css:

#box{
450px;
height: 450px;
margin: 20px auto;
background-color: #bcac90;
border-radius: 10px;
clear: left;
}
.cell{
100px;
height: 100px;
margin: 10px 0 0 10px;
float: left;
background-color: #d3c9bf;
border-radius: 6px;
font-size: 60px;
color: #000;
text-align: center;
line-height: 100px;
}
.game{
280px;
margin: 20px auto;
font-size: 50px;
}
.block{
450px;
height: 100px;
margin: 0 auto;
}
.block p{
380px;
height: 50px;
font-size: 40px;
float: left;
}
.block a{
display: block;
70px;
height: 30px;
text-decoration: none;
color: #fff;
background-color: #7b770b;
float: left;
text-align: center;
line-height: 30px;
margin-top: 55px;
border-radius: 5px;
}
.gameover{
display: none;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: rgba(20,20,20,.5);
}
.gameover>div{
300px;
height: 250px;
position: absolute;
left: 50%;
top: 50%;
margin-top: -125px;
margin-left: -150px;
background-color: #fff;
border-radius: 10px;
border: 5px solid #edcf72;
text-align: center;
font-size: 25px;
font-family: Arial;
font-weight: bold;
}
.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}
.n2,.n4{color:#776e65}
.n1024,.n2048,.n4096,.n8192{font-size:30px}
.n128,.n256,.n512{font-size:50px}

js:

var game = {
//设置游戏的二维数组data,4行4列
Score:0,
data:null,
RN:4,
CN:4,
start(){
//清零
Score = 0;
//1、初始化二维数组
//先建一个空数组
this.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.updataView();
//触发游戏
document.onkeydown = function(e){
switch (e.keyCode){
case 37://左移
game.moveLeft();
// console.log(e.keyCode);
break;
case 38://上移
game.moveUp();
// console.log(e.keyCode);
break;
case 39://右移
game.moveRight();
// console.log(e.keyCode);
break;
case 40://下移
game.moveDown();
// console.log(e.keyCode);
break;
}
}

},
//2、随即在二维数组中添加两个数值,2或4
randomNum(){
//在一个随机位置生成2或者4
//反复执行,直到生成成功
//循环两次,每次生成一个值
for(var i = 1;i < 2;i++){
//生成的值只有2或者4
var num = Math.random()<0.5?2:4;
//下标在0~3之间
var r_random = Math.ceil(Math.random()*this.RN-1);
var c_random = Math.ceil(Math.random()*this.CN-1);
//让data[r][c]中的值为2或4
//当里面值为0时,赋值,不为0时,再循环一次
if(this.data[r_random][c_random] == 0){
this.data[r_random][c_random] = num;
}else
i = i - 1;
}
},
//3、将data中的数据展示到页面div中
updataView(){
//遍历二维数组data
//r从0开始,到RN结束
for(var r = 0;r < this.RN;r++){
//c从0开始,到CN结束
for(var c = 0;c < this.CN;c++){
//找到id为'c'+r+c的div元素
var div = document.getElementById('c'+r+c);
//获取到data r行c列的数据,存储到变量n中
//判断this.data[r][c];是否为0
//如果是0
//清除div里面的内容
if(this.data[r][c] == 0){
//找到对应的div,和二维数组下标相同
div.innerHTML = '';
//恢复div的class为 cell
div.className = 'cell';
//否则
//将div的值设置为this.data[r][c];
//将div的class设置为 'cell n'+this.data[r][c];
}else{
div.innerHTML = this.data[r][c];
div.className = 'cell n'+this.data[r][c];
}
}
}
document.getElementById('ScoreNum').innerHTML = this.Score;
this.Over();
},
moveLeft(){//左移所有行
var before = (this.data).toString();
//给数组拍照 var before = arr.toString()
for(var r = 0;r < this.RN;r++){
//r从0开始,到<RN结束
//左移r行
this.moveLeftInRow(r);
}
//r循环结束
var after = (this.data).toString();
//结束后,再给数组拍照 赋值给after
//如果before != after
//调用updateView更新页面数据
if(before != after){
this.randomNum();
this.updataView();
}
},
moveLeftInRow(r){//左移
//c从0开始,到<CN-1
for(var c = 0;c < this.CN-1;c++){
//查找r行c列下一个不为0的位置nextc
//i从c+1开始,到<CN结束
for(var i = c + 1;i < this.CN;i++){
if(this.data[r][i] != 0){
//当前i位置的值是否为0
//值不为0的位置 i赋值nextc
var nextc = i;
break;
}else{
//否则
//将nextc赋值为-1
//i循环结束
nextc = -1;
}
}
//如果nextc的值为-1 证明后面都是0 直接退出
if(nextc == -1){
break;
//否则
//找r行c列位置的值 判断是否为0
}else if(this.data[r][c] == 0){
//如果是0 将nextc位置的值赋值给c位置
//将nextc位置赋值为0
//将c留在原地
this.data[r][c] = this.data[r][nextc];
this.data[r][nextc] = 0;
c--;
}
else if(this.data[r][c] == this.data[r][nextc]){
//否则 else if (c位置的值等于nextc位置的值)
//将c位置的值*2
//将nextc位置的值赋值为0
this.data[r][c] = this.data[r][c]*2;
this.data[r][nextc] = 0;
this.Score += this.data[r][c]
}
//c循环结束
}
},
moveRight(){//右移所有行
var before = (this.data).toString();
//给数组拍照 var before = arr.toString()
for(var r = 0;r < this.RN;r++){
//r从0开始,到<RN结束
//右移r行
this.moveRightInRow(r);
}
//r循环结束
var after = (this.data).toString();
//结束后,再给数组拍照 赋值给after
//如果before != after
//调用updateView更新页面数据
if(before != after){
this.randomNum();
this.updataView();
}
},
moveRightInRow(r){//右移
//c从0开始,到<CN-1
for(var c = this.CN-1;c > 0;c--){
//查找r行c列下一个不为0的位置nextc
//i从c+1开始,到<CN结束
for(var i = c - 1;i > -1;i--){
if(this.data[r][i] != 0){
//当前i位置的值是否为0
//值不为0的位置 i赋值nextc
var nextc = i;
break;
}else{
//否则
//将nextc赋值为-1
//i循环结束
var nextc = -1;
}
}
//如果nextc的值为-1 证明后面都是0 直接退出
if(nextc == -1){
break;
//否则
//找r行c列位置的值 判断是否为0
}else if(this.data[r][c] == 0){
//如果是0 将nextc位置的值赋值给c位置
//将nextc位置赋值为0
//将c留在原地
this.data[r][c] = this.data[r][nextc];
this.data[r][nextc] = 0;
c++;
}
else if(this.data[r][c] == this.data[r][nextc]){
//否则 else if (c位置的值等于nextc位置的值)
//将c位置的值*2
//将nextc位置的值赋值为0
this.data[r][c] = this.data[r][c]*2;
this.data[r][nextc] = 0;
this.Score += this.data[r][c]
}
//c循环结束
}
},
moveDown(){//下移所有行
var before = (this.data).toString();
//给数组拍照 var before = arr.toString()
for(var c = 0;c < this.CN;c++){
//r从0开始,到<RN结束
//右移r行
this.moveDownInRow(c);
}
//r循环结束
var after = (this.data).toString();
//结束后,再给数组拍照 赋值给after
//如果before != after
//调用updateView更新页面数据
if(before != after){
this.randomNum();
this.updataView();
}
},
moveDownInRow(c){//下移
//c从0开始,到<CN-1
for(var r = this.RN-1;r > 0;r--){
//查找r行c列下一个不为0的位置nextc
//i从c+1开始,到<CN结束
for(var i = r - 1;i >= 0;i--){
if(this.data[i][c] != 0){
//当前i位置的值是否为0
//值不为0的位置 i赋值nextc
var nextc = i;
break;
}else{
//否则
//将nextc赋值为-1
//i循环结束
var nextc = -1;
}
}
//如果nextc的值为-1 证明后面都是0 直接退出
if(nextc == -1){
break;
//否则
//找r行c列位置的值 判断是否为0
}else if(this.data[r][c] == 0){
//如果是0 将nextc位置的值赋值给c位置
//将nextc位置赋值为0
//将c留在原地
this.data[r][c] = this.data[nextc][c];
this.data[nextc][c] = 0;
r++;
}
else if(this.data[r][c] == this.data[nextc][c]){
//否则 else if (c位置的值等于nextc位置的值)
//将c位置的值*2
//将nextc位置的值赋值为0
this.data[r][c] = this.data[r][c]*2;
this.data[nextc][c] = 0;
this.Score += this.data[r][c]
}
//c循环结束
}
},
moveUp(){//上移所有行
var before = (this.data).toString();
//给数组拍照 var before = arr.toString()
for(var c = 0;c < this.CN;c++){
//r从0开始,到<RN结束
//右移r行
this.moveUpInRow(c);
}
//r循环结束
var after = (this.data).toString();
//结束后,再给数组拍照 赋值给after
//如果before != after
//调用updateView更新页面数据
if(before != after){
this.randomNum();
this.updataView();
}
},
moveUpInRow(c){//上移
//c从0开始,到<CN-1
for(var r = 0;r < this.RN-1;r++){
//查找r行c列下一个不为0的位置nextc
//i从c+1开始,到<CN结束
for(var i = r + 1;i < this.RN;i++){
if(this.data[i][c] != 0){
//当前i位置的值是否为0
//值不为0的位置 i赋值nextc
var nextc = i;
break;
}else{
//否则
//将nextc赋值为-1
//i循环结束
var nextc = -1;
}
}
//如果nextc的值为-1 证明后面都是0 直接退出
if(nextc == -1){
break;
//否则
//找r行c列位置的值 判断是否为0
}else if(this.data[r][c] == 0){
//如果是0 将nextc位置的值赋值给c位置
//将nextc位置赋值为0
//将c留在原地
this.data[r][c] = this.data[nextc][c];
this.data[nextc][c] = 0;
r--;
}
else if(this.data[r][c] == this.data[nextc][c]){
//否则 else if (c位置的值等于nextc位置的值)
//将c位置的值*2
//将nextc位置的值赋值为0
this.data[r][c] = this.data[r][c]*2;
this.data[nextc][c] = 0;
this.Score += this.data[r][c]
}
//c循环结束
}
},
GameOver(){//游戏结束
//便利data数组
for(var r = 0;r < this.RN;r++){
for(var c = 0;c < this.CN;c++){
//如果有0则false
if(this.data[r][c] == 0) return false
//如果有相等的则false
if(c < this.CN-1){
if(this.data[r][c] == this.data[r][c+1]){
return false;
}
}
//如果有相等的则false
if(r < this.RN-1){
if(this.data[r][c] == this.data[r+1][c]){
return false;
}
}
}
}
//否则 true
return true;
},
Over(){
//如果结束条件成立
if(this.GameOver()){
//开启遮蔽罩
document.getElementById('over').style.display = 'block';
}
},
}
game.start();

原文地址:https://www.cnblogs.com/awei313558147/p/11342102.html