今天被問到俄羅斯方塊的作法,於是動手實做了一下,簡單介紹一下大概的概念:
1. css layout 設計
Tetris_layout
利用div建立每一塊Block,這裡重要的屬性是display:inline-block,建立浮動的方塊元素。
1 | .stage{ |
2. 資料結構設計
每一個grid的結構1
2
3
4
5
6
7
8var blockStructure = function(){
//代表是否填滿,用來判斷是否要著色。
this.fill = false;
//代表是否為堆疊,用來判斷是否可以移動。
this.stacked = false;
//判斷顏色
this.color = '';
};
3. stage Canvas的設計
用一個一維array代表stage矩陣,例如(3, 4) => 4*Xcount + 3
4. shape形狀方塊
shape 用二維array表示,較好理解,例如這是我定義的幾個形狀
1 | Tetris.prototype.getShape = (function(){ |
5. 碰撞偵測
碰撞偵測部份是較複雜的部份,我利用兩個檢查函式來做檢查,為了理解容易,底下的判斷程式碼有點重複。
- 檢查是否到達邊界
- 檢查是否碰到堆積的grid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24var collision = _self.chkCollision(x, y);
var chkStacked = _self.chkStacked(x, y);
//collision dectection
if(collision){
//若已到達底,則更新狀態為堆積狀態
if(chkStacked){
status.stacked = true;
return;
}else{
return;
}
}else{
if(chkStacked){
//若碰到堆積的grid,先檢查是否可以往下,若可以往下,則退回,若否,則更新為堆積狀態
var chkStackedDown = _self.chkStacked(status.shapeX, status.shapeY+1);
if(chkStackedDown){
status.stacked = true;
return;
}else{
return;
}
}
}
6. 狀態更新
Game 的基本觀念是狀態的更新,每一次重新渲染畫面時都是在更新狀態,因此狀態的表示非常重要,在此我用shape來儲存現在動作的形狀,並紀錄目前shape的x, y,以及是否要進入堆疊狀態。1
2
3
4
5
6var status = {
shape:null,
shapeX:0,
shapeY:0,
stacked:false
};
7. refresh 渲染畫面
1 |
|
以上是我的基本概念,實做上其實code有點醜,而且也還有很多bug,不過因為是實驗性質的,也沒打算要產品化,就在這兒野人獻曝了。
DEMO