上次編寫俄羅斯方塊,好像是N年前的大學時代,使用TC2.0在DOS平台上開發的,由于當時的代碼是儲存在3.5寸軟碟上的,到現在那些程式早已經作了古,沒有了蹤影。俄羅斯方塊其實編寫并不太容易,要考慮的東西還是蠻多的,以前想在PPC上用.Net精簡架構集實作,後來起了個頭,沒有太大的動力,也就作罷了。現在對MF充滿了激情,是以從零做起(沒有參考任何現成代碼,隻不過還是依照我早期的思路編寫而成),花費我大半天的時間才編寫完畢(在編寫過程中,還發現MF對二維數組支援不大好,我後面會提到)。
好了,讓我們在.Net Micro Framework模拟器(由于我這裡沒有帶LCD屏的MF開發闆,是以很遺憾,不知道在實際的裝置上該程式的性能會怎樣)上體驗一下俄羅斯方塊遊戲吧。
進入MF Windows(姑且這麼叫吧),單擊“開始”菜單按鈕(MF平台不支援滑鼠,是單擊模拟器上的Menu按鈕,或在鍵盤敲“空格”或“Windows”鍵),我們用光标鍵選中“俄羅斯方塊”遊戲,按OK鍵(或按鍵盤上的“回車”鍵)進入遊戲。
通過開始菜單進入“俄羅斯方塊”遊戲 編寫的俄羅斯方塊遊戲可是具備經典版的所有功能喲!可以翻轉,可以移動,可以得分,可以快速降落等等!要認真玩,否則很快就“Game Over”的。在編寫過程中發現MF對二維數組支援不是太好。
下面的代碼編譯時會報錯:
bool[,] bFlag=new bool[10,20];
是以在MF中二維數組必須這樣聲明才行:
bool[][] bShowFlag = new bool[22][]; //主顯示區含邊框
for (int i = 0; i < 22; i++)
{
bShowFlag[i] = new bool[12];
}
附:MF俄羅斯方塊核心代碼
//俄羅斯方塊(葉帆工作室:http://blog.csdn.net/yefanqiu)
public class ElsGame
{
int Current_Y = -2, Current_X =3;
int intGrade = 0;
bool[][] bShowFlag = new bool[22][]; //主顯示區含邊框
bool[][] bMetaShowFlag = new bool[4][]; //下一個方塊顯示區
bool[][] bCurrentMetaShowFlag = new bool[4][]; //目前方塊顯示區
int intNextNo = 0; //下一個方塊索引
int intCurrentNo = 0; //目前方塊索引
enum MoveWay{Left,Down,Right};
DispatcherTimer GameTimer; //遊戲時鐘
bool bGameRunFlag = false; //遊戲運作标志
public ElsGame(DispatcherTimer GameTimer)
{
this.GameTimer = GameTimer;
Init();
}
//元素
private bool[][] GetElsMeta(int intNo)
{
bool[][] ElsMetaFlag = new bool[4][];
for (int i = 0; i < 4; i++)
{
ElsMetaFlag[i] = new bool[4];
}
switch (intNo)
{
case 0: //田
ElsMetaFlag[1][1] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[2][2] = true;
return ElsMetaFlag;
case 1: //-
ElsMetaFlag[2][0] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[2][3] = true;
return ElsMetaFlag;
case 2: //|
ElsMetaFlag[0][2] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[3][2] = true;
return ElsMetaFlag;
case 3: //┻
ElsMetaFlag[1][2] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[2][3] = true;
return ElsMetaFlag;
case 4: //┣
ElsMetaFlag[2][2] = true;
ElsMetaFlag[1][1] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[3][1] = true;
return ElsMetaFlag;
case 5: //┳
ElsMetaFlag[2][2] = true;
ElsMetaFlag[1][1] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[1][3] = true;
return ElsMetaFlag;
case 6: //┫
ElsMetaFlag[2][1] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[3][2] = true;
return ElsMetaFlag;
case 7: //┖
ElsMetaFlag[3][2] = true;
ElsMetaFlag[1][1] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[3][1] = true;
return ElsMetaFlag;
case 8: //┍
ElsMetaFlag[2][1] = true;
ElsMetaFlag[1][1] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[1][3] = true;
return ElsMetaFlag;
case 9: //┒
ElsMetaFlag[1][1] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[3][2] = true;
return ElsMetaFlag;
case 10: //┙
ElsMetaFlag[1][3] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[2][3] = true;
return ElsMetaFlag;
case 11: //┕
ElsMetaFlag[1][1] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[2][3] = true;
return ElsMetaFlag;
case 12: //┎
ElsMetaFlag[1][2] = true;
ElsMetaFlag[1][1] = true;
ElsMetaFlag[2][1] = true;
ElsMetaFlag[3][1] = true;
return ElsMetaFlag;
case 13: //┑
ElsMetaFlag[2][3] = true;
ElsMetaFlag[1][1] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[1][3] = true;
return ElsMetaFlag;
case 14: //┚
ElsMetaFlag[3][1] = true;
ElsMetaFlag[1][2] = true;
ElsMetaFlag[2][2] = true;
ElsMetaFlag[3][2] = true;
return ElsMetaFlag;
}
return null;
}
//翻轉
private int GetTurnMeta(int intNo)
{
switch (intNo)
{
case 0: //田
return 0;
case 1: //-
return 2;
case 2: //|
return 1;
case 3: //┻
return 4;
case 4: //┣
return 5;
case 5: //┳
return 6;
case 6: //┫
return 3;
case 7: //┖
return 8;
case 8: //┍
return 9;
case 9: //┒
return 10;
case 10: //┙
return 7;
case 11: //┕
return 12;
case 12: //┎
return 13;
case 13: //┑
return 14;
case 14: //┚
return 11;
}
return intNo;
}
//初始化
public void Init()
{
if (!bGameRunFlag)
{
//主顯示區
for (int i = 0; i < 22; i++)
{
bShowFlag[i] = new bool[12];
for (int j = 0; j < 12; j++)
{
if (i == 21 || j == 0 || j == 11)
{
bShowFlag[i][j] = true;
}
else
{
bShowFlag[i][j] = false;
}
}
}
//輔助顯示區
for (int i = 0; i < 4; i++)
{
bMetaShowFlag[i] = new bool[4];
for (int j = 0; j < 4; j++)
{
bMetaShowFlag[i][j] = false;
}
}
//方塊初始化
Microsoft.SPOT.Math.Randomize();
intCurrentNo = Microsoft.SPOT.Math.Random(15);
bCurrentMetaShowFlag = GetElsMeta(intCurrentNo);
intNextNo = Microsoft.SPOT.Math.Random(15);
bMetaShowFlag = GetElsMeta(intNextNo);
//時鐘開始
GameTimer.Start();
//積厘清零
intGrade = 0;
//遊戲運作标志
bGameRunFlag = true;
}
}
//下降
public bool DoDownMove()
{
if (IsMove(Current_X, Current_Y, bCurrentMetaShowFlag, MoveWay.Down) && bGameRunFlag)
{
Current_Y++;
MoveBlock(Current_X, Current_Y, bCurrentMetaShowFlag, MoveWay.Down);
}
else
{
//時鐘恢複正常
GameTimer.Interval = new TimeSpan(0, 0, 1);
//判斷是否得分及遊戲是否結束
int intRet=GetGameState() ;
if (intRet == -1)
{
GameTimer.Stop();
bGameRunFlag = false;
//主顯示區
for (int i = 0; i < 22; i++)
{
bShowFlag[i] = new bool[12];
for (int j = 0; j < 12; j++)
{
if (i==1 || i == 20 || j == 1 || j == 10)
{
bShowFlag[i][j] = true;
}
else
{
bShowFlag[i][j] = false;
}
}
}
}
else
{
intGrade += intRet;
Current_Y = -3;
Current_X = 3;
NextBlock();
}
}
return true;
}
//判斷遊戲狀态
private int GetGameState()
{
bool bFlag = false;
int intNum = 0;
//判斷遊戲是否結束
for (int i = 1; i < 11; i++)
{
if (bShowFlag[1][i])
{
return -1;
}
}
//判斷得分
for (int i = 1; i < 21; i++)
{
bFlag = true;
for (int j = 1; j < 11; j++)
{
if (!bShowFlag[i][j]) bFlag = false;
}
if (bFlag)
{
//移動數組
for (int e = i; e>0; e--)
{
for (int k = 1; k < 11; k++)
{
bShowFlag[e][k] =bShowFlag[e-1][k];
}
}
intNum++;
}
}
switch (intNum)
{
case 1:
intNum = 100;
break;
case 2:
intNum = 300;
break;
case 3:
intNum = 500;
break;
case 4:
intNum = 800;
break;
}
return intNum;
}
//左移
public bool DoLeftMove()
{
if (!bGameRunFlag) return false;
if (IsMove(Current_X, Current_Y, bCurrentMetaShowFlag, MoveWay.Left))
{
Current_X--;
MoveBlock(Current_X, Current_Y, bCurrentMetaShowFlag, MoveWay.Left);
return true;
}
return false;
}
//右移
public bool DoRightMove()
{
if (!bGameRunFlag) return false;
if (IsMove(Current_X, Current_Y, bCurrentMetaShowFlag, MoveWay.Right))
{
Current_X++;
MoveBlock(Current_X, Current_Y, bCurrentMetaShowFlag, MoveWay.Right);
return true;
}
return false;
}
//方塊翻轉
public bool DoTurn()
{
if (!bGameRunFlag) return false;
#region //判斷是否能翻轉
int mX=0, mY = 0;
bool bFlag = true;
//翻轉後的标志
bool[][] bFlags = GetElsMeta(GetTurnMeta(intCurrentNo));
SetBlock(Current_X, Current_Y, bCurrentMetaShowFlag, false);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
mX = Current_X + j + 1;
mY = Current_Y + i + 1;
if (mX > -1 && mX < 12 && mY > -1 && mY < 22)
{
if (bShowFlag[mY][mX] && bFlags[i][j])
{
bFlag = false;
}
}
}
}
SetBlock(Current_X, Current_Y, bCurrentMetaShowFlag, true);
#endregion
if (bFlag)
{
SetBlock(Current_X, Current_Y, bCurrentMetaShowFlag, false);
intCurrentNo = GetTurnMeta(intCurrentNo);
bCurrentMetaShowFlag = GetElsMeta(intCurrentNo);
SetBlock(Current_X, Current_Y, bCurrentMetaShowFlag, true);
return true;
}
return false;
}
//設定方塊
private void SetBlock(int X, int Y, bool[][] bFlags, bool bFlag)
{
略 ;-)
}
//下一個方塊
private void NextBlock()
{
intCurrentNo = intNextNo;
bCurrentMetaShowFlag = bMetaShowFlag;
intNextNo = Microsoft.SPOT.Math.Random(15);
bMetaShowFlag = GetElsMeta(intNextNo);
}
//移動方塊
private void MoveBlock(int X, int Y, bool[][] bFlags,MoveWay mw)
{
switch (mw)
{
case MoveWay.Left:
SetBlock(X+1, Y, bCurrentMetaShowFlag, false);
SetBlock(X, Y, bCurrentMetaShowFlag, true);
break;
case MoveWay.Down:
SetBlock(X, Y - 1, bCurrentMetaShowFlag, false);
SetBlock(X, Y, bCurrentMetaShowFlag, true);
break;
case MoveWay.Right:
SetBlock(X-1, Y, bCurrentMetaShowFlag, false);
SetBlock(X, Y, bCurrentMetaShowFlag, true);
break;
default:
break;
}
}
//是否可以移動
private bool IsMove(int X, int Y, bool[][] bFlags, MoveWay mw)
{
略 ;-)
}
//繪制
public void Draw(DrawingContext dc)
{
int BarTop = 26;
int BarHeight = SystemMetrics.ScreenHeight - BarTop * 2;
dc.DrawRectangle(new SolidColorBrush(Colors.Gray), new Pen(Colors.Gray), 0, BarTop, SystemMetrics.ScreenWidth, BarHeight);
//主顯示區
dc.DrawRectangle(new SolidColorBrush(Colors.Black), new Pen(Colors.White), 79, BarTop + 3, 92, 182);
//輔助顯示區
dc.DrawRectangle(new SolidColorBrush(Colors.Black), new Pen(Colors.White), 222,120, 38, 38);
//積分區
dc.DrawRectangle(new SolidColorBrush(Colors.White), new Pen(Colors.Blue), 205, 180, 74, 20);
dc.DrawText(intGrade.ToString(), YFWinApp.YFFont,ColorUtility.ColorFromRGB(0,120,0), 224 + 17 - intGrade.ToString().Length * 3, 184);
//顯示
DrawEls(80, BarTop + 4, 9, 9, dc);
//結束
if (!bGameRunFlag)
{
dc.DrawText("Game Over!", YFWinApp.YFFont, Colors.Red,96, 110);
}
}
//顯示方塊
private void DrawEls(int X,int Y,int Width,int Height,DrawingContext dc)
{
SolidColorBrush sb=new SolidColorBrush(Colors.Green);
Pen pen=new Pen(Colors.Blue);
//主顯示區
for (int i = 0; i < 20; i++)
{
for (int j = 0; j < 10; j++)
{
if(bShowFlag[i+1][j+1])
dc.DrawRectangle(sb, pen, X +j * Width, Y + i * Height, Width, Height);
}
}
//輔助顯示區
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if(bMetaShowFlag[i][j])
dc.DrawRectangle(sb, pen,223 + j * Width, 121 + i * Height, Width, Height);
}
}
}
}