第三個題目是俄羅斯方塊游戲。該游戲算法比較簡單,主要功夫都在界面體驗上了,比如方塊圖形、用戶控制、消去與累計等。
圖形我們采用GDI+畫圖方式顯示,共8種圖形,當然可以根據自己的喜好隨意定制。如何表示圖形?我們可以借鑒馬賽克效果。把所有圖形都用3*3矩陣表示,0表示背景色顯示,1表示著色顯示。比如
{0,0,0},
{0,1,0}, 表示T型,看出來了嗎?每個數字位置其實就是一個正方形小塊。
{1,1,1}
用戶控制?簡單KeyPress事件實現就好。當然還有一個無需用戶控制的就是自動下落,可以使用Timer實現。
消去算法?^_^,當然很簡單,如果一行上有為0的單元格,那麼表示沒有充滿,就不用消去;否則就要消去。累計就是數組追加,消去就是元素刪除。
當然了,消去與累計都需要將數據的變化體現到界面上,那就是畫圖。Graphics對象我們都會使用,在該windows窗體游戲中,我們可以實現OnPaint事件。每當需要重繪的時候,比如用戶控制,消去等,就調用窗體refresh,那麼自然會觸發Paint事件。以下是代碼示例:
public int[][,] figures = new int[8][,]//8種圖形
{
new int[3,3] {
{0,0,0},
{0,1,0},
{1,1,1}
},
new int[3,3]
{
{0,0,0},
{0,2,2},
{2,2,0}
},
new int[3,3]
{
{0,0,0},
{3,3,0},
{0,3,3}
},
new int[2,2]
{
{4,4},
{4,4}
},
new int[3,3]
{
{5,0,0},
{5,0,0},
{5,5,0}
},
new int[3,3]
{
{0,6,0},
{0,6,0},
{6,6,0}
},
new int[4,4]
{
{7,0,0,0},
{7,0,0,0},
{7,0,0,0},
{7,0,0,0}
},
new int[3,3]
{
{0,8,0},
{8,8,8},
{0,0,0}
}
};
你能從上面的定義看出有哪些圖形嗎?^_^,為什麼不為0的地方不全是1?因為我想讓不同的圖形顯示不同的顏色,如果無此要求則不必這樣。
在具體畫圖時,我們需要將將數組大小轉換為區域邊長方格數
int conversize(int sz)
{
int s = 0;
if (sz == 4) s = 2;
if (sz == 9) s = 3;
if (sz == 16) s = 4;
return s;
}
當然出現的圖形是隨機的,直接用Random就可以做到。
記住無論什麼動作引起的圖形變化,包括移動、旋轉等都要用Refresh,以便刷新游戲界面。例如向左
public void moveLeft()
{
if (check(figure, px - 1, py)) px = px - 1;
Refresh();//this.Refresh();
}
protected override void OnPaint(PaintEventArgs e)這個熟悉吧?嗯,界面就是它畫出來的。你要在界面顯示什麼,就在裡面畫什麼。記住,是全部界面,因為我們的這個游戲沒有任何其他資源,沒有任何控件,只有圖形。
當然了,圖形位置移動必須要要檢查越界和是否遇到障礙物。也就是上述的check方法。基本思路就是圖形經過的位置中無越界並且無不為0的單元格存在。
bool check(int[,] fg, int x, int y)
{
int sz = conversize(fg.Length);
for (int i = 0; i < sz; i++)
for (int j = 0; j < sz; j++)
{
int rx = i + x;
int ry = j + y;
if ((rx < 0 || rx > 9 || ry < 0 || ry > 19) && fg[i, j] != 0) return false;
if (!(rx < 0 || rx > 9 || ry < 0 || ry > 19))
if (board[rx, ry] != 0 && fg[i, j] != 0) return false;
}
return true;
}
旋轉怎麼實現?一個純數組倒序排列的簡單題目,不是嗎?
最後是游戲難度的問題,等級越高,降落速度越快,其實就是把等級數字跟計時器的Interval掛鉤就是了。
其他的就不多說了。有興趣的可以把它做成控件,方便大家使用。祝你玩的開心。
明天搞那個木馬記錄器……
本文出自 “王傑瑞的技術博客” 博客,請務必保留此出處http://wangjierui.blog.51cto.com/186879/56005