首頁 > 軟體

基於JS實現的消消樂遊戲的範例程式碼

2022-04-16 13:00:35

前言

一直對小遊戲挺感興趣的,也嘗試著做過一些小遊戲,實現遊戲是一個不錯的提高程式碼基礎水平的方式,因此這次挑戰了一個較為困難的小遊戲:消消樂。

如果僅僅是從消除方面來製作一個靜態的消消樂(只有消除和補充方塊的過程,但是沒有任何互動和動畫)其實並不算太難,只要我們能夠想通方塊消除(主要是三消)的原理和方塊下落後的新位置,我們就可以解決這個問題。但如果我們要同時實現各個狀態的動畫呢?這就是一個比較複雜的問題了。

本文將從邏輯到實現步驟慢慢詳細的介紹該遊戲的製作過程。對了,這個遊戲是完全用原生js實現的,考慮到要將遊戲成品發給一些不懂程式的朋友,因此沒做程式碼拆分,所有的程式碼均在一個單一的html檔案上。

該遊戲已放在codepen上面,點選檢視遊戲線上演示。有興趣的小夥伴可以檢視,如果能點一個小愛心更好呢。

遊戲目前僅做了最簡單的三消功能,如果有時間可以把其他互動也寫出來。

遊戲的準備工作

首先我們思考遊戲的機制: 遊戲有一個“棋盤”,是一個n*m的矩形。矩形中有若干個顏色(或者型別)的方塊,相同型別的方塊,在一個橫行或者豎行,有3個或者3個以上時,便會消除。

在部分方塊消除後,這些方塊上方的方塊便會下墜並補充這些消除方塊的缺口,同時,上方又會生成新的方塊來補充下墜方塊的位置,在執行完上述步驟後,便完成了一個遊戲過程的迴圈。

總結一下

一共有3個步驟,將生成一個遊戲迴圈:消除,下墜,補充。在補充後,如果方塊們無法自然消除,迴圈便會結束。這時候就需要玩家來交還兩個相鄰方塊,來人為製造可以消除的情況,以重新進入迴圈。

如果玩家的交換並不能使得重新進入消除迴圈呢?那麼這個交換將重新換回原樣。

基本機制思考完畢,現在開始程式碼構建:

首先考慮到方塊們會進行大量的動畫過程(主要是四種:移動,消除,下墜,冒出),於是我們使用絕對定位來安排這些方塊,並且在其行類樣式當中新增屬性:transition,用css來實現這些方塊的動畫。具體實現如下:

移動:通過left和top值的改變,控制方塊的移動。

消除:通過修改transform,修改為scale(0),以實現消除的動畫。

下墜:通過top值的改變,同移動。

冒出:通過修改transform,將本來為scale(0)的transform值修改為scale(1),以實現冒出的動畫。

考慮到這些動畫是一個接一個的執行,我們應該是需要使用非同步來執行這些動畫的,當然使用回撥函數也能實現,但回撥函數可能會很麻煩,所以我們使用Promise物件來解決這些麻煩。

廢話太多了!現在開始寫程式碼。

棋盤

首先是棋盤的實現,簡單操作就定義了一個棋盤的整體結構出來。當然,給#app新增position:relative或者position:absolute是必不可少的。

<body>
    <div id="app">
    </div>
</body>

接下來我們用物件導向的思想,構造棋盤的具體內容:

首先一個棋盤有它的寬度和高度(x和y),我們還同時還定義它的方塊大小(size)。

matrix則為之後要用到的,存放不同type的矩陣,types則為所有的棋子種類。

除此之外,還有幾個屬性,這些之後再說。

class GameMap {
	constructor(x, y, size) {
			this.x = x;
			this.y = y;
			this.size = size;
			this.matrix = [];
			this.useSwap = false;
			this.handleable = true;
			this.types = emojis.length;
		}
}

我們再來構造“棋子”,棋子的屬性很多,所以我們通過僅將options作為引數,並將options解構,來賦予棋子這些屬性,這些屬性分別是

class Cell {
	constructor(options) {
		const { position, status, type, left, top, right, bottom, instance } = options;
			this.type = type;
			this.position = position;
			this.status = status;
			this.top = top;
			this.bottom = bottom;
			this.left = left;
			this.right = right;
			this.instance = instance;
                    }
}

type 型別(顏色),number型別表示,相同的number即被視為同樣的型別。

position 位置,用一個形如[m,n]的二維陣列儲存

status 狀態,分為'common' 普通 'collapse' 崩塌 'emerge' 冒出,一共三種

top 棋子上方的棋子物件,值也是一個Cell範例,如果棋子上方沒有棋子,那它就是undefined

left 棋子的左側棋子物件

right 棋子的右側棋子物件

bottom 棋子的下方棋子物件

instance 根據上述屬性刻畫出的真實的棋子的DOM物件,最終這些物件會在GameMap中展現出來

在這裡我們使用emoji表情來展現這些棋子,我們定義全域性變數emojis:

const emojis = ['

IT145.com E-mail:sddin#qq.com