为什么标题叫使用js写一个2048呢?因为我不会页面美化(在这里给div加外边距和内边距已经是我做页面美化的极限了)!!!!本来打算导入SemanticUI来美化页面的,结果发现SemanticUI的弹出层需要jquery支持。那我用原生js写不是显得很呆?那就不对页面做美化了,能看就行,消息提示也使用尊贵的alert()来完成吧。
首先我们创建一个html文件,在body标签体内写我们需要的东西
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input type="button" id="initBtn" value="开始" onclick="initBoard()" /><!--开始和重新开始按钮-->
<div id="boardDiv"></div><!--展示图片-->
</body>
</html>
然后准备一些图片,用来展示
以我高超的美术功底,这些工作很快就能完成
在html文件同级目录下新建一个img文件夹,然后把这些图片丢进去
开始准备写js代码
准备一些常量(分数这个东西因为我忘了写计分功能,就没啥用了)
//棋盘
var BOARD = [[0,0,0,0,0]
,[0,0,0,0,0]
,[0,0,0,0,0]
,[0,0,0,0,0]
,[0,0,0,0,0]];
//行列数
var ROW = 5;
var COL = 5;
//开始标志
var startFlag = false;
//数据列表
var LIST = [2,4,8,16,32,64,128,256,512,1024,2048];
//分数
var sore = 0;
//存储按下鼠标的位置
var startX = 0;
var startY = 0;
//不移动阈值
var LIMIT = 10;
获取页面上一些等会要用的元素
var initBtn = document.getElementById('initBtn');
var boardDiv = document.getElementById('boardDiv');
var body = document.getElementById('body');
写几个函数(写循环的时候把i,j和行列的对应关系搞的有点混,幸亏是一个行数列数一样的矩阵)
初始化棋盘的函数
/**
* 初始化棋盘
*/
function initBoard(){
startFlag = true;
initBtn.value = "重新开始";
for(var i = 0; i < ROW; i++){
for(var j = 0; j < COL; j++){
BOARD[i][j] = 0;
}
}
var count = 0;
while(count < 4){
var i = Math.floor(Math.random() * COL);
var j = Math.floor(Math.random() * ROW);
if(BOARD[i][j] !== 0){
continue;
}
BOARD[i][j] = 2;
count++;
}
showBoard();
}
展示棋盘的函数
/**
* 展示棋盘
*/
function showBoard(){
boardDiv.innerHTML = "";
for(var i = 0; i < ROW; i++){
for(var j = 0; j < COL; j++){
boardDiv.innerHTML += "<img src='img/" + BOARD[i][j] + ".png'/>";
}
boardDiv.innerHTML += "<br\>";
}
}
向棋盘添加数据的函数(如果棋盘满了就不加,没满就随机找一个空位添加)
/**
* 添加数据到棋盘
*/
function addNum(){
var flag = true;
for(var i = 0; i < COL; i++){
for(var j = 0; j < ROW; j++){
if(0 == BOARD[i][j]){
flag = false;
break;
}
}
}
if(flag){
return;
}
var x;
var y;
do{
x = Math.floor(Math.random() * COL);
y = Math.floor(Math.random() * ROW);
}while(BOARD[x][y] != 0);
BOARD[x][y] = LIST[Math.floor(Math.random() * 4)];
}
向四个方向移动数据并合并的函数
/**
* 向左合并
*/
function mergeLeft(){
for(var i = 0 ; i < ROW; i++){
//记录需要附加移动的数
var count = (0 == BOARD[i][COL - 1]? 0 : 1);
for(var j = COL - 1; j > 0; j--){
if(0 == BOARD[i][j - 1] || BOARD[i][j - 1] == BOARD[i][j]){
//相等相加
BOARD[i][j - 1] += BOARD[i][j];
if(2048 == BOARD[i][j - 1]){
BOARD[i][j - 1] = 0
}
BOARD[i][j] = 0;
//复制附件移动的数
if(count > 0){
for(k = j + 1;k < j + 1 + count;k++){
if(k > COL - 1){
break;
}
BOARD[i][k - 1] = BOARD[i][k];
BOARD[i][k] = 0;
}
}
}else if(BOARD[i][j - 1] != BOARD[i][j]){
count++;
}
}
}
}
/**
* 向右合并
*/
function mergeRight(){
for(var i = 0 ; i < ROW; i++){
var count = (0 == BOARD[i][0]? 0 : 1);
for(var j = 0; j < COL - 1; j++){
if(0 == BOARD[i][j + 1] || BOARD[i][j + 1] == BOARD[i][j]){
BOARD[i][j + 1] += BOARD[i][j];
if(2048 == BOARD[i][j + 1]){
BOARD[i][j + 1] = 0
}
BOARD[i][j] = 0;
if(count > 0){
for(k = j - 1;k > j - 1 - count;k--){
if(k < 0){
break;
}
BOARD[i][k + 1] = BOARD[i][k];
BOARD[i][k] = 0;
}
}
}else if(BOARD[i][j + 1] != BOARD[i][j]){
count++;
}
}
}
}
/**
* 向下合并
*/
function mergeDown(){
for(var j = 0; j < COL; j++){
var count = (0 == BOARD[0][j]? 0 : 1);
for(var i = 0; i < ROW - 1; i++){
if(0 == BOARD[i + 1][j] || BOARD[i + 1][j] == BOARD[i][j]){
BOARD[i + 1][j] += BOARD[i][j];
if(2048 == BOARD[i + 1][j]){
BOARD[i + 1][j] = 0
}
BOARD[i][j] = 0;
if(count > 0){
for(k = i - 1;k > i - 1 - count;k--){
if(k < 0){
break;
}
BOARD[k + 1][j] = BOARD[k][j];
BOARD[k][j] = 0;
}
}
}else if(BOARD[i + 1][j] != BOARD[i][j]){
count++;
}
}
}
}
/**
* 向上合并
*/
function mergeUp(){
for(var j = 0; j < COL; j++){
var count = (0 == BOARD[ROW - 1][j]? 0 : 1);
for(var i = ROW - 1; i > 0; i--){
if(0 == BOARD[i - 1][j] || BOARD[i - 1][j] == BOARD[i][j]){
BOARD[i - 1][j] += BOARD[i][j];
if(2048 == BOARD[i - 1][j]){
BOARD[i - 1][j] = 0
}
BOARD[i][j] = 0;
if(count > 0){
for(k = i + 1;k < i + 1 + count;k++){
if(k > ROW - 1){
break;
}
BOARD[k - 1][j] = BOARD[k][j];
BOARD[k][j] = 0;
}
}
}else if(BOARD[i - 1][j] != BOARD[i][j]){
count++;
}
}
}
}
判断游戏结束的函数(游戏结束的判定标准是数据无法移动也无法合并)
/**
* 判断当前位置是否可以使游戏继续
* @param {Object} x x坐标
* @param {Object} y y坐标
*/
function coludContinue(x,y){
if(0 == BOARD[x][y]){
return true;
}
return BOARD[x - 1][y] == BOARD[x][y] ||
BOARD[x][y - 1] == BOARD[x][y] ||
BOARD[x][y + 1] == BOARD[x][y] ||
BOARD[x + 1][y] == BOARD[x][y];
}
/**
* 判断游戏是否失败
*/
function isFalse(){
for(var x = 0; x < COL; x++){
if(0 == BOARD[0][x] || 0 == BOARD[ROW - 1][x] || 0 == BOARD[x][0] || 0 == BOARD[x][COL - 1]){
return false;
}
}
for(var i = 1; i < ROW - 1; i++){
for(var j = 1; j < COL - 1; j++){
if(coludContinue(i,j)){
return false;
}
}
}
return true;
}
判断当前用户指定的移动方向以及游戏进行的函数
/**
* 鼠标按下时获取按下时的坐标
* @param {Object} event 鼠标按下事件,js自动传入
*/
document.onmousedown = function(event){
startX = event.pageX;
startY = event.pageY;
}
/**
* 鼠标松开时判断是否要进行移动
* @param {Object} event 鼠标松开事件,js自动传入
*/
document.onmouseup = function(event){
if(!startFlag){
return;
}
if(0 == startX && 0 == startY){
return
}
var endX = event.pageX;
var endY = event.pageY;
var x = endX - startX;
var y = endY - startY;
startX = 0;
startY = 0;
if(x > LIMIT || x < -LIMIT || y > LIMIT || y < -LIMIT){
var absX = Math.abs(x);
var absY = Math.abs(y);
if(absX > absY){
if(x > 0){
mergeRight();
}else{
mergeLeft();
}
}else{
if(y > 0){
mergeDown();
}else{
mergeUp();
}
}
if(isFalse()){
alert("您输了");
startFlag = false;
}
addNum();
showBoard();
}
}
完整的代码长这个样子
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
#boardDiv{
margin-top: 10px;
}
img{
margin-top: 2px;
margin-right: 2px;
}
</style>
</head>
<body id="body" onselectstart="return false">
<input type="button" id="initBtn" value="开始" onclick="initBoard()" /><!--开始和重新开始按钮-->
<div id="boardDiv"></div><!--展示图片-->
</body>
<script>
//棋盘
var BOARD = [[0,0,0,0,0]
,[0,0,0,0,0]
,[0,0,0,0,0]
,[0,0,0,0,0]
,[0,0,0,0,0]];
//行列数
var ROW = 5;
var COL = 5;
//开始标志
var startFlag = false;
//数据列表
var LIST = [2,4,8,16,32,64,128,256,512,1024,2048];
//分数
var sore = 0;
//存储按下鼠标的位置
var startX = 0;
var startY = 0;
//不移动阈值
var LIMIT = 10;
var initBtn = document.getElementById('initBtn');
var boardDiv = document.getElementById('boardDiv');
var body = document.getElementById('body');
var sorceMsg = document.getElementById('sorceMsg');
/**
* 初始化棋盘
*/
function initBoard(){
startFlag = true;
initBtn.value = "重新开始";
for(var i = 0; i < ROW; i++){
for(var j = 0; j < COL; j++){
BOARD[i][j] = 0;
}
}
var count = 0;
while(count < 4){
var i = Math.floor(Math.random() * COL);
var j = Math.floor(Math.random() * ROW);
if(BOARD[i][j] !== 0){
continue;
}
BOARD[i][j] = 2;
count++;
}
showBoard();
}
/**
* 添加数据到棋盘
*/
function addNum(){
var flag = true;
for(var i = 0; i < COL; i++){
for(var j = 0; j < ROW; j++){
if(0 == BOARD[i][j]){
flag = false;
break;
}
}
}
if(flag){
return;
}
var x;
var y;
do{
x = Math.floor(Math.random() * COL);
y = Math.floor(Math.random() * ROW);
}while(BOARD[x][y] != 0);
BOARD[x][y] = LIST[Math.floor(Math.random() * 4)];
}
/**
* 展示棋盘
*/
function showBoard(){
boardDiv.innerHTML = "";
for(var i = 0; i < ROW; i++){
for(var j = 0; j < COL; j++){
boardDiv.innerHTML += "<img src='img/" + BOARD[i][j] + ".png'/>";
}
boardDiv.innerHTML += "<br\>";
}
}
/**
* 向左合并
*/
function mergeLeft(){
for(var i = 0 ; i < ROW; i++){
//记录需要附加移动的数
var count = (0 == BOARD[i][COL - 1]? 0 : 1);
for(var j = COL - 1; j > 0; j--){
if(0 == BOARD[i][j - 1] || BOARD[i][j - 1] == BOARD[i][j]){
//相等相加
BOARD[i][j - 1] += BOARD[i][j];
if(2048 == BOARD[i][j - 1]){
BOARD[i][j - 1] = 0
}
BOARD[i][j] = 0;
//复制附件移动的数
if(count > 0){
for(k = j + 1;k < j + 1 + count;k++){
if(k > COL - 1){
break;
}
BOARD[i][k - 1] = BOARD[i][k];
BOARD[i][k] = 0;
}
}
}else if(BOARD[i][j - 1] != BOARD[i][j]){
count++;
}
}
}
}
/**
* 向右合并
*/
function mergeRight(){
for(var i = 0 ; i < ROW; i++){
var count = (0 == BOARD[i][0]? 0 : 1);
for(var j = 0; j < COL - 1; j++){
if(0 == BOARD[i][j + 1] || BOARD[i][j + 1] == BOARD[i][j]){
BOARD[i][j + 1] += BOARD[i][j];
if(2048 == BOARD[i][j + 1]){
BOARD[i][j + 1] = 0
}
BOARD[i][j] = 0;
if(count > 0){
for(k = j - 1;k > j - 1 - count;k--){
if(k < 0){
break;
}
BOARD[i][k + 1] = BOARD[i][k];
BOARD[i][k] = 0;
}
}
}else if(BOARD[i][j + 1] != BOARD[i][j]){
count++;
}
}
}
}
/**
* 向下合并
*/
function mergeDown(){
for(var j = 0; j < COL; j++){
var count = (0 == BOARD[0][j]? 0 : 1);
for(var i = 0; i < ROW - 1; i++){
if(0 == BOARD[i + 1][j] || BOARD[i + 1][j] == BOARD[i][j]){
BOARD[i + 1][j] += BOARD[i][j];
if(2048 == BOARD[i + 1][j]){
BOARD[i + 1][j] = 0
}
BOARD[i][j] = 0;
if(count > 0){
for(k = i - 1;k > i - 1 - count;k--){
if(k < 0){
break;
}
BOARD[k + 1][j] = BOARD[k][j];
BOARD[k][j] = 0;
}
}
}else if(BOARD[i + 1][j] != BOARD[i][j]){
count++;
}
}
}
}
/**
* 向上合并
*/
function mergeUp(){
for(var j = 0; j < COL; j++){
var count = (0 == BOARD[ROW - 1][j]? 0 : 1);
for(var i = ROW - 1; i > 0; i--){
if(0 == BOARD[i - 1][j] || BOARD[i - 1][j] == BOARD[i][j]){
BOARD[i - 1][j] += BOARD[i][j];
if(2048 == BOARD[i - 1][j]){
BOARD[i - 1][j] = 0
}
BOARD[i][j] = 0;
if(count > 0){
for(k = i + 1;k < i + 1 + count;k++){
if(k > ROW - 1){
break;
}
BOARD[k - 1][j] = BOARD[k][j];
BOARD[k][j] = 0;
}
}
}else if(BOARD[i - 1][j] != BOARD[i][j]){
count++;
}
}
}
}
/**
* 判断当前位置是否可以使游戏继续
* @param {Object} x x坐标
* @param {Object} y y坐标
*/
function coludContinue(x,y){
if(0 == BOARD[x][y]){
return true;
}
return BOARD[x - 1][y] == BOARD[x][y] ||
BOARD[x][y - 1] == BOARD[x][y] ||
BOARD[x][y + 1] == BOARD[x][y] ||
BOARD[x + 1][y] == BOARD[x][y];
}
/**
* 判断游戏是否失败
*/
function isFalse(){
for(var x = 0; x < COL; x++){
if(0 == BOARD[0][x] || 0 == BOARD[ROW - 1][x] || 0 == BOARD[x][0] || 0 == BOARD[x][COL - 1]){
return false;
}
}
for(var i = 1; i < ROW - 1; i++){
for(var j = 1; j < COL - 1; j++){
if(coludContinue(i,j)){
return false;
}
}
}
return true;
}
/**
* 鼠标按下时获取按下时的坐标
* @param {Object} event 鼠标按下事件,js自动传入
*/
document.onmousedown = function(event){
startX = event.pageX;
startY = event.pageY;
}
/**
* 鼠标松开时判断是否要进行移动
* @param {Object} event 鼠标松开事件,js自动传入
*/
document.onmouseup = function(event){
if(!startFlag){
return;
}
if(0 == startX && 0 == startY){
return
}
var endX = event.pageX;
var endY = event.pageY;
var x = endX - startX;
var y = endY - startY;
startX = 0;
startY = 0;
if(x > LIMIT || x < -LIMIT || y > LIMIT || y < -LIMIT){
var absX = Math.abs(x);
var absY = Math.abs(y);
if(absX > absY){
if(x > 0){
mergeRight();
}else{
mergeLeft();
}
}else{
if(y > 0){
mergeDown();
}else{
mergeUp();
}
}
if(isFalse()){
alert("您输了");
startFlag = false;
}
addNum();
showBoard();
}
}
</script>
</html>
跑一下试试
跑起来了也没有报错,欸嘿
开始瞧瞧
失败提示
我需要的功能都完成了