为了更好的学习掌握JavaScript,我在工作空闲时间,用JavaScript写了一些小游戏。这篇文章主要是回顾整理2048的代码,在代码开发阶段,遇到了好几个坑,当时没有做记录,时间长了,那几个bug以及处理思路也就忘掉了。因此就有了写博客的想法,记录下自己的学习历程。
进入正题,2048是前几年很火的一个小游戏。游戏思路如下:
1.开局生成4*4的游戏方格,也就是一个二维数组,在其中任意一个方格产生随机数2或者4,数组中值为0在方格中显示就是空白。
2.监听键入事件,确定移动方向。例如向右移动,遍历可移动的表格(即前三列),遍历顺序为在每一行中从第三列开始到第一列结束,即(0,2)-(0,1)-(0,0),找出需要移动(有值)的格子,例如图中坐标为(0,1)的方格。遍历(0,1)右方方格,顺序依然为从最后一列往前找,即(0,3)-(0,2)。
3.对(0,3),我们需要检查(0,1)和(0,3)之间是否有障碍值,即不为0的值。如果(0,1)和(0,3)之间没有障碍值,检查(0,3)的值。如果array[0][3] == 0,则(0,1)直接移动到(0,3),即array[0][3] = array[0][1],array[0][1] = 0;如果array[0][3] == array[0][1],则(0,3)吸收(0,1)的值,即array[0][3] += array[0][1],array[0][1] = 0;如果array[0][3]的值不符合上述两种情况,不做任何改变。如果(0,1)和(0,3)之间有障碍值,则继续对(0,2)执行上述流程。
4.对所有可移动方格执行步骤3,完成数值移动。渲染方格,检查是否存在array[x][y] == 2048,如果有,玩家胜利,游戏结束。如果无,随机选择空白表格生成随机数2或者4,继续步骤2。
游戏实现比较简单,需要思考的也就是步骤三。第一次写,不知道讲清楚没有,另外代码中有很多可以改进的地方,无伤大雅,我也就懒得再改了。
欢迎大家留言讨论,大佬如果有啥指导意见也请留言,谢谢。
最后附上源码,也可以访问我的GitHub直接下载。
js如下:
/**
* Created by PC on 2017/12/5.
*/
$(function () {
$('#start').click(function () {
var game = new Game();
game.start();
})
})
var Game = function () {
this.x = 4;
this.y = 4;
this.m = [];
this.empty = [];
_this = this;
this.data = [];
this.gameGo =true;
this.start = function () {
$('#container').html('');
//createBox
this.createBox();
this.createRandom();
window.addEventListener('keydown',function (e) {
switch (e.which){
case 37:
_this.moveLeft();
break;
case 38:
_this.moveUp();
break;
case 39:
_this.moveRight();
break;
case 40:
_this.moveDown();
break;
}
})
};
this.createBox = function () {
for(var i = 0;i < this.x;i++){
this.m[i] = [];
for(var j = 0;j < this.y;j++){
this.m[i][j] = 0;
var box = "<div class='box' x='" + i + "' y='" + j + "'></div>";
$('#container').append(box);
}
$('#container').append("<br>");
}
};
this.createRandom = function () {
//random
if(_this.gameGo){
var random = Math.random() < 0.5 ? 2 : 4;
//find empty box
for(var i = 0;i < this.x;i++){
for(var j = 0;j < this.y;j++){
if(this.m[i][j] == 0){
this.empty.push([i,j]);
}
}
}
if(this.empty.length > 0){
var r = Math.floor(Math.random() *this.empty.length),
rx = this.empty[r][0],
ry = this.empty[r][1];
_this.m[rx][ry] = random;
}
this.empty = [];
this.showNumber();
}
};
this.moveLeft = function () {
// alert('left');
for(var i = 0;i < this.x;i++){
for(var j =1;j < this.y;j++){
if(_this.m[i][j] != 0){
for(var k = 0;k < j;k++){
if(_this.m[i][k] == 0 && _this.rowCheck(i,j,k)){
_this.m[i][k] = _this.m[i][j];
_this.m[i][j] = 0;
continue;
}else if(_this.m[i][k] == this.m[i][j] && _this.rowCheck(i,j,k)){
_this.m[i][k] += _this.m[i][j];
_this.m[i][j] = 0;
}
}
}
}
}
this.showNumber();
this.createRandom();
};
this.moveUp = function () {
// alert('up');
for(var i = 1;i < this.x;i++){
for(var j =0;j < this.y;j++){
if(_this.m[i][j] != 0){
for(var k = 0;k < i;k++){
if(_this.m[k][j] == 0 && _this.columnCheck(i,j,k)){
_this.m[k][j]= _this.m[i][j];
_this.m[i][j] = 0;
continue;
}else if(_this.m[k][j] == this.m[i][j] && _this.columnCheck(i,j,k)){
_this.m[k][j] += _this.m[i][j];
_this.m[i][j] = 0;
}
}
}
}
}
this.showNumber();
this.createRandom();
};
this.moveRight = function () {
// alert('right');
for(var i = 0;i < this.x;i++){
for(var j =this.y-2;j >= 0;j--){
if(_this.m[i][j] != 0){
for(var k = this.y-1;k > j;k--){
if(_this.m[i][k] == 0 && _this.rowCheck(i,j,k)){
_this.m[i][k] = _this.m[i][j];
_this.m[i][j] = 0;
continue;
}else if(_this.m[i][k] == this.m[i][j] && _this.rowCheck(i,j,k)){
_this.m[i][k] += _this.m[i][j];
_this.m[i][j] = 0;
}
}
}
}
}
this.showNumber();
this.createRandom();
};
this.moveDown =function () {
// alert('down');
for(var i = this.x-2;i >= 0;i--){
for(var j =0;j < this.y;j++){
if(_this.m[i][j] != 0){
for(var k = this.x-1;k > i;k--){
if(_this.m[k][j] == 0 && _this.columnCheck(i,j,k)){
_this.m[k][j] = _this.m[i][j];
_this.m[i][j] = 0;
continue;
}else if(_this.m[k][j] == this.m[i][j] && _this.columnCheck(i,j,k)){
_this.m[k][j] += _this.m[i][j];
_this.m[i][j] = 0;
}
}
}
}
}
this.showNumber();
this.createRandom();
};
this.rowCheck = function (i,j,k) {
//to left
if(k < j){
k += 1;
for(;k < j;k++){
if(_this.m[i][k] != 0){
return false;
}
}
return true;
}else if(k > j){
//to right
k -= 1;
for(;k > j;k--){
if(_this.m[i][k] != 0){
return false;
}
}
return true;
}
};
this.columnCheck = function (i,j,k) {
//to up
if(k < i){
k += 1;
for(;k < i;k++){
if(_this.m[k][j] != 0){
return false;
}
}
return true;
}else if(k > i){
k -=1;
for(;k>i;k--){
if(_this.m[k][j] != 0){
return false;
}
}
return true;
}
};
this.showNumber = function () {
for(var i =0;i<this.x;i++){
for(var j =0;j<this.y;j++){
if(this.m[i][j] != 0){
$('.box[x='+ i +'][y='+ j +']').text(this.m[i][j]);
}else {
$('.box[x='+ i +'][y='+ j +']').text('');
}
}
}
this.dataCheck();
};
this.dataCheck = function () {
for(var i =0;i<this.x;i++){
for(var j =0;j<this.y;j++){
this.data.push(this.m[i][j]);
}
}
//2048
if(_this.gameWin()){
alert('YOU WIN!!');
_this.gameGo = false;
}
this.data = [];
}
this.gameWin = function () {
return this.data.some(function (v) { return v == 2048 })
}
}
html如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Game-2048</title>
<style>
.box { display: inline-block; width: 40px; height: 40px; line-height: 40px; border: 1px solid #fff; background: #eee; cursor: pointer; text-align: center; vertical-align: middle; }
</style>
</head>
<body style="text-align:center">
<div style="margin: 10px;">
<div id="game" style="">
<button style="margin: 10px;background: #ffffff;width: 50px;height: 50px" id="start">2048 Start!</button>
</div>
<div id="container"></div>
</div>
<script src="jquery.min.js"></script>
<script src="2048.js"></script>
</body>
</html>