javascript實現前端小遊戲2048

Jiang呀發表於2020-10-04

javascript實現前端小遊戲2048

前言

最近因為一些原因,研究了一下2048這個小遊戲的程式碼,順便給大家講一下實現過程。

遊戲截圖:

在這裡插入圖片描述

在這裡插入圖片描述

主要功能

1、根據格子的合併,部分數字對應的格子顏色不盡相同;

2、初始化隨機位置出現隨機的2個數字為2或4;

3、每次合併一個格子只合並一次,如2 2 4 0,第一次合併後是4 4 0 0,而不是8 0 0 0;

4,判斷所有格子是否能夠向上下左右移動,沒有空間或者對應方向的第一個格子數字和本身格子的數字不一樣即移動不了;

5、如果上下左右都無法移動以及生成不了新的格子即可判輸;

6、分數為兩個格子合併後的數值累加

實現過程

首先使用div佈置一個4*4的佈局

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>網頁版2048</title>
<link rel="stylesheet" type="text/css" href="css/index.css">
<script type="text/javascript"
    src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript"  src="js/support2048.js"></script>
<script type="text/javascript" src="js/showanimation2048.js"></script>
<script type="text/javascript" src="js/main2048.js"></script>
</head>
<body>
    <header>
        <h1>2048</h1>
        <a href="javascript:newgame();" id="newgamebutton">New Game</a>
        <p>
            score:<span id="score">0</span>
        </p>
    </header>
    <div id="grid-container">
        <div class="grid-cell" id="grid-cell-0-0"></div>
        <div class="grid-cell" id="grid-cell-0-1"></div>
        <div class="grid-cell" id="grid-cell-0-2"></div>
        <div class="grid-cell" id="grid-cell-0-3"></div>
        
        <div class="grid-cell" id="grid-cell-1-0"></div>
        <div class="grid-cell" id="grid-cell-1-1"></div>
        <div class="grid-cell" id="grid-cell-1-2"></div>
        <div class="grid-cell" id="grid-cell-1-3"></div>
        
        <div class="grid-cell" id="grid-cell-2-0"></div>
        <div class="grid-cell" id="grid-cell-2-1"></div>
        <div class="grid-cell" id="grid-cell-2-2"></div>
        <div class="grid-cell" id="grid-cell-2-3"></div>
        
        <div class="grid-cell" id="grid-cell-3-0"></div>
        <div class="grid-cell" id="grid-cell-3-1"></div>
        <div class="grid-cell" id="grid-cell-3-2"></div>
        <div class="grid-cell" id="grid-cell-3-3"></div>
    </div>
    <div id="gameover">
    	GAME OVER
    </div>
</body>
</html>

需要的css樣式:

@CHARSET "UTF-8";
*{
	padding: 0;
	margin: 0;
}
 
header{
    display:block;
    margin:0 auto;
    width:500px;
    text-align:center;
}
 
header h1{
    font-family:Arial, Helvetica, sans-serif;
    font-size:60px;
    font-weight:bold;
    margin-top: 20px;
    margin-bottom: 20px;    
}
 
header #newgamebutton{
    width:100px;
    padding:10px;
    background:#8f7a66;
    font-family:Arial, Helvetica, sans-serif;
    color:white;
    border-radius:10px;
    text-decoration:none;
    
}
 
header #newgamebutton:hover{
    background:#9f8b77;
}
 
header p{
    font-family:Arial, Helvetica, sans-serif;
    font-size:25px;
    margin:20px auto;
}
 
#grid-container{
    width:460px;
    height:460px;
    padding:20px;
    margin:40px auto;
    background:#bbada0;
    border-radius:10px;
    position:relative;
}
 
.grid-cell{
    width:100px;
    height:100px;
    border-radius:6px;
    background:#ccc0b3;
    position:absolute;
}
 
.number-cell{
    width:100px;
    height:100px;
    border-radius:6px;
    line-height:100px;
    font:Arial, Helvetica, sans-serif;
    font-size:50px;
    font-weight:bold;
    text-align: center;
    position:absolute;
}
#gameover{
    background-color:black;
    color: white;
    font-family:Arial, Helvetica, sans-serif;
    font-size:60px;
    position: absolute;
    top:45%;
    left:42%;
    width:250px;
    text-align:center;
    display: none;
}

現在的效果:

在這裡插入圖片描述
可以看到基本佈局已經好了

然後我們需要引入js,引入的順序也有講究,我們按照下面這個步驟引入外部檔案(index.css在上面),因為有一些函式呼叫是需要另一個檔案裡的,所有需要先引入被呼叫的:

<link rel="stylesheet" type="text/css" href="css/index.css">
<script type="text/javascript"
    src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>
<script type="text/javascript"  src="js/support2048.js"></script>
<script type="text/javascript" src="js/showanimation2048.js"></script>
<script type="text/javascript" src="js/main2048.js"></script>

main2048.js,裡面存放了初始化棋盤格的方法,以及上下左右響應,判斷是否遊戲結束 格子上下左右移動的方法

var board = new Array();
var added = new Array();
var score = 0;
var top = 240;
$(document).ready(function(e){
    newgame();
});
 
function newgame(){
    //初始化棋盤格
    init();
    //在隨機生成兩個隨機的數字
    generateOneNumber();
    generateOneNumber();
}
 
function init(){
	score=0;
	document.getElementById("score").innerHTML=score;
	$("#gameover").css('display','none');
    for(var i = 0;i<4;i++){
        for(var j = 0;j<4;j++){
            var gridCell = $("#grid-cell-"+i+"-"+j);
            gridCell.css("top",getPosTop(i,j));
            gridCell.css("left",getPosLeft(i,j));
        }
    }
    
    for(var i = 0; i<4;i++){//初始化格子陣列
        board[i] = new Array();
        for(var j = 0;j<4;j++){
            board[i][j] = 0;
        }
    }
    
    for(var i = 0; i<4;i++){//初始化判定合併的陣列
        added[i] = new Array();
        for(var j = 0;j<4;j++){
            added[i][j] = 0;
        }
    }
    
    updateBoardView();//通知前端對board二位陣列進行設定。
}
 
function updateBoardView(){//更新陣列的前端樣式
    $(".number-cell").remove();
    for(var i = 0;i<4;i++){
        for ( var j = 0; j < 4; j++) {
            $("#grid-container").append('<div class="number-cell" id="number-cell-'+i+'-'+j+'"></div>');
            var theNumberCell = $('#number-cell-'+i+'-'+j);
            if(board[i][j] == 0){
                theNumberCell.css('width','0px');
                theNumberCell.css('height','0px');
                theNumberCell.css('top',getPosTop(i,j));
                theNumberCell.css('left',getPosLeft(i,j));
            }else{
                theNumberCell.css('width','100px');
                theNumberCell.css('hegiht','100px');
                theNumberCell.css('top',getPosTop(i,j));
                theNumberCell.css('left',getPosLeft(i,j));
                //NumberCell覆蓋
                theNumberCell.css('background-color',getNumberBackgroundColor(board[i][j]));//返回背景色
                theNumberCell.css('color',getNumberColor(board[i][j]));//返回前景色
                theNumberCell.text(board[i][j]);
            }
        }
    }
}
 
function generateOneNumber(){//生成隨機的格子
    if (nospace(board)) //如果沒有空間就返回false
        return false;
    
    //隨機一個位置
    var randx = parseInt(Math.floor(Math.random()*4));
    var randy = parseInt(Math.floor(Math.random()*4));
    while(true){
        if (board[randx][randy] == 0) 
            break;
        randx = parseInt(Math.floor(Math.random()*4));
        randy = parseInt(Math.floor(Math.random()*4));
    }
    //隨機一個數字
    var randNumber = Math.random()<0.5 ? 2 : 4;
    //在隨機位置顯示隨機數字
    board[randx][randy] = randNumber;
    showNumberWithAnimation(randx,randy,randNumber);
    return true;
}
 
//事件響應迴圈
$(document).keydown(function(event){
    switch (event.keyCode) {
    case 37://left
        if(moveLeft()){
            //setTimeout("generateOneNumber()",210);
            getScore();
            generateOneNumber();//每次新增一個數字就可能出現遊戲結束
            setTimeout("isgameover()",400);//300毫秒
        }
        break;
    case 38://up
        if(moveUp()){
        	getScore();
            generateOneNumber();//每次新增一個數字就可能出現遊戲結束
            setTimeout("isgameover()",400);
        }
        break;
    case 39://right
        if(moveRight()){
        	getScore();
            generateOneNumber();//每次新增一個數字就可能出現遊戲結束
            setTimeout("isgameover()",400);
        }
        break;
    case 40://down
        if(moveDown()){
        	getScore();
            generateOneNumber();//每次新增一個數字就可能出現遊戲結束
            setTimeout("isgameover()",400);
        }
        break;
 
    }
});
 
function isgameover(){
    if(nospace(board)&&nomove(board))//如果沒有多餘的空間或者上下左右都移動不了就遊戲結束
        gameover();
}
 
function gameover(){//將遊戲結束的div浮現出來
    $("#gameover").css('display','block');
}
 
function isaddedArray(){//將判斷能否合併的陣列值置為0
	for(var i = 0;i<4;i++){
        for(var j = 0;j<4;j++){
        	added[i][j] = 0;
        }
   }
}
 
function moveLeft(){//更多地細節資訊
    //判斷格子是否能夠向左移動
    if( !canMoveLeft(board))
        return false;
    
    isaddedArray();
    //真正的moveLeft函式//標準
    for(var i = 0;i<4;i++)
        for(var j = 1;j<4;j++){//第一列的數字不可能向左移動
            if(board[i][j] !=0){
                //(i,j)左側的元素
                for(var k = 0;k<j;k++){
                    //落腳位置的是否為空 && 中間沒有障礙物
                    if(board[i][k] == 0 && noBlockHorizontal(i , k, j, board)){
                        //move
                        showMoveAnimation(i, j,i,k);
                        board[i][k] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    //落腳位置的數字和本來的數字相等 && 中間沒有障礙物
                    else if(board[i][k] == board[i][j] && noBlockHorizontal(i , k, j, board)){
                        //move
                        showMoveAnimation(i, j,i,k);
                        //add
                        if(added[i][k]!=0){//目標落腳點是否完成過合併
                        		board[i][k+1] = board[i][j];
                        		board[i][j] = 0;
                        }
                        else{
                        	board[i][k] += board[i][j];
                        	board[i][j] = 0;
                        	added[i][k] = 1;
                        	score +=board[i][k];
                        }
                        continue;
                    }
                }
            }
        }
    setTimeout("updateBoardView()",200);
    return true;
}
 
function moveRight(){//更多地細節資訊
    //判斷格子是否能夠向右移動
    if( !canMoveRight(board))
        return false;
    
    isaddedArray();
    //真正的moveRight函式//標準
    for(var i = 0;i<4;i++)
        for(var j = 2;j>=0;j--){//最後一列的數字不可能向右移動
            if(board[i][j] !=0){
                //(i,j)右側的元素
                for(var k = 3;k>j;k--){
                    //落腳位置的是否為空 && 中間沒有障礙物
                    if(board[i][k] == 0 && noBlockHorizontal(i , j, k, board)){
                        //move
                        showMoveAnimation(i, j,i,k);
                        board[i][k] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    //落腳位置的數字和本來的數字相等 && 中間沒有障礙物
                    else if(board[i][k] == board[i][j] && noBlockHorizontal(i , j, k, board)){
                        //move
                        showMoveAnimation(i, j,i,k);
                        //add
                         if(added[i][k]!=0){
                        		board[i][k-1] = board[i][j];
                        		board[i][j] = 0;
                        }
                        else{
                        	board[i][k] += board[i][j];
                        	board[i][j] = 0;
                        	added[i][k] = 1;
                        	score +=board[i][k];
                        }
                        continue;
                    }
                }
            }
        }
    setTimeout("updateBoardView()",200);
    return true;
}
 
function moveUp(){//更多地細節資訊
    //判斷格子是否能夠向上移動
    if( !canMoveUp(board))
        return false;
    
    isaddedArray();
    //真正的moveUp函式//標準
    for(var j = 0;j<4;j++)
        for(var i = 1;i<4;i++){//第一行的數字不可能向上移動
            if(board[i][j] !=0){
                //(i,j)上面的元素
                for(var k = 0;k<i;k++){
                    //落腳位置的是否為空 && 中間沒有障礙物
                    if(board[k][j] == 0 && noBlockVertical(j , k, i, board)){
                        //move
                        showMoveAnimation(i, j,k,j);
                        board[k][j] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    //落腳位置的數字和本來的數字相等 && 中間沒有障礙物
                    else if(board[k][j] == board[i][j] && noBlockVertical(j , k, i, board)){
                        //move
                        showMoveAnimation(i, j,k,j);
                        //add
                        if(added[k][j]!=0){
                        	board[k+1][j] = board[i][j];
                        	board[i][j] = 0;
                        }
                        else{
                        	board[k][j] += board[i][j];
                        	board[i][j] = 0;
                        	added[k][j] = 1;
                        	score +=board[k][j];
                        }
                        continue;
                    }
                }
            }
        }
    setTimeout("updateBoardView()",200);
    return true;
}
 
function moveDown(){//更多地細節資訊
    //判斷格子是否能夠向下移動
    if( !canMoveDown(board))
        return false;
        
    isaddedArray();
    //真正的moveDown函式//標準
    for(var j = 0;j<4;j++)
        for(var i = 2;i>=0;i--){//最後一行的數字不可能向下移動
            if(board[i][j] !=0){
                //(i,j)上面的元素
                for(var k = 3;k>i;k--){
                    //落腳位置的是否為空 && 中間沒有障礙物
                    if(board[k][j] == 0 && noBlockVertical(j , i, k, board)){
                        //move
                        showMoveAnimation(i, j,k,j);
                        board[k][j] = board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    //落腳位置的數字和本來的數字相等 && 中間沒有障礙物
                    else if(board[k][j] == board[i][j] && noBlockVertical(j , i, k, board)){
                        //move
                        showMoveAnimation(i, j,k,j);
                        //add
                        if(added[k][j]!=0){
                        	board[k-1][j] = board[i][j];
                        	board[i][j] = 0;
                        }
                        else{
                        	board[k][j] += board[i][j];
                        	board[i][j] = 0;
                        	added[k][j] = 1;
                        	score +=board[k][j];
                        }
                        continue;
                    }
                }
            }
        }
    setTimeout("updateBoardView()",200);
    return true;
}

showanimation2048.js

function showNumberWithAnimation(i, j, randNumber) {//實現隨機數字的樣式變動
 
  var numberCell = $('#number-cell-' + i + '-' + j);
  numberCell.css("background-color", getNumberBackgroundColor(randNumber));
  numberCell.css("color", getNumberColor(randNumber));
  numberCell.text(randNumber);
  
  numberCell.animate({
      width : "100px",
      height : "100px",
      top : getPosTop(i, j),
      left : getPosLeft(i, j)
  }, 50);
}

function showMoveAnimation(fromx, fromy, tox, toy){//實現移動格子的樣式變動
  
  var numberCell = $('#number-cell-'+fromx +'-'+fromy);
  numberCell.animate({top:getPosTop(tox,toy),
  left:getPosLeft(tox,toy)},200);
}

support2048.js 介面格子的背景顏色以及字型顏色支援以及位置佈置函式,以及更新分數,判斷格子能不能移動

function getPosTop(i, j) {
  return 20 + i * 120;
}

function getPosLeft(i, j) {
  return 20 + j * 120;
}

function getNumberBackgroundColor(number) {
  switch (number) {
  case 2:
      return "#eee4da";
      break;
  case 4:
      return "#eee4da";
      break;
  case 8:
      return "#f26179";
      break;
  case 16:
      return "#f59563";
      break;
  case 32:
      return "#f67c5f";
      break;
  case 64:
      return "#f65e36";
      break;
  case 128:
      return "#edcf72";
      break;
  case 256:
      return "#edcc61";
      break;
  case 512:
      return "#9c0";
      break;
  case 1024:
      return "#3365a5";
      break;
  case 2048:
      return "#09c";
      break;
  case 4096:
      return "#a6bc";
      break;
  case 8192:
      return "#93c";
      break;
  }
  return "black";
}

function getNumberColor(number) {
  if (number <= 4){
      return "#776e65";
  }
  return "white";
}

function getScore(){
document.getElementById("score").innerHTML=score;
}

//在隨機生成數字的時候判斷16宮格中是否還有空間
function nospace(board) {
  for ( var i = 0; i < 4; i++) 
      for ( var j = 0; j < 4; j++) 
          if (board[i][j] == 0)
              return false;
  return true;
}

//實現功能判斷
function canMoveLeft( board ){ 
  for(var i = 0;i<4;i++)
      for(var j = 0;j<4;j++)
          if( board[i][j] !=0 && j != 0)
              if( board[i][j-1] == 0 || board[i][j-1] == board[i][j])
                  return true;
                  
  return false;
}

function canMoveRight( board ){
  for(var i = 0;i<4;i++)
      for(var j = 0;j<4;j++)
          if( board[i][j] !=0 && j != 3)
              if( board[i][j+1] == 0 || board[i][j+1] == board[i][j])
                  return true;
                  
  return false;
}

function canMoveUp( board ){
  for(var i = 0;i<4;i++)
      for(var j = 0;j<4;j++)
          if( board[i][j] !=0 && i != 0)
              if( board[i-1][j] == 0 || board[i-1][j] == board[i][j])
                  return true;   
  return false;
}

function canMoveDown( board ){
  for(var i = 0;i<4;i++)
      for(var j = 0;j<4;j++)
          if( board[i][j] !=0 && i != 3)
              if( board[i+1][j] == 0 || board[i+1][j] == board[i][j])
                  return true;
  return false;
}

//判斷水平方向是否有障礙物
function noBlockHorizontal(row, col1, col2, board){
  for(var i = col1 + 1; i<col2; i++)
      if(board[row][i]!=0)
          return false;
  return true;
}

//判斷豎直方向是否有障礙物
function noBlockVertical(col, row1, row2, board){
  for(var i = row1 + 1; i<row2; i++)
      if(board[i][col]!=0)
          return false;
  return true;
}
//最後收尾
function nomove(board){
  if(canMoveLeft(board)|| canMoveRight(board)||canMoveUp(board)||canMoveDown(board))
      return false;
  return true;
}

相關文章