c#實現簡單的俄羅斯方塊

夢在未名湖畔發表於2018-04-05

      由於最近剛進出c#,想快速上手,所以決定寫幾個小遊戲(後面會陸續更新)來熟悉語言,並且記錄學習winform的一些相關問題和解決方法。

      首先給我的感覺winform和c++中的介面設計MFC還是非常類似的(很可惜當時MFC深入淺出沒吃透徹),下面我們就從最基礎簡單的來實現俄羅斯方塊:

1首先弄出一個窗體:


我是在pictureBox控制元件上面實現畫圖的(因為沒找到圖片資源,所以我的方塊都是GDI繪製的)然後就是設定一個定時器,再點選開始選單的時候啟動定時器,具體時間間隔自己決定,其中可能要用到的定時器的函式和屬性:

timer.Enable  :表示定時器是否啟動,true是啟動,false是關閉。

timer.Interval:表示定時器的間隔時間。

然後是邏輯的設計:採用一個二維陣列記住pictureBox,然後1表示該格子是有方塊的,每次計時器中呼叫重新整理函式來重新整理窗體,這樣就可以呼叫paint函式來繪製圖形,然後邏輯的操作其實都是對二維陣列的操作,最後傳給paint函式的都是操作後的結果陣列。

this.Invalidate() :重新整理窗體,可以呼叫到paint函式。

然後再PictureBox上面畫圖的時候要注意,如果是直接繪製的話,會出現一些很奇怪的問題,所以我們採用繪製再點陣圖上面然後再貼在pictureBox上面(詳情請見上一篇)

下面貼上一些部分關鍵程式碼:

public partial class Form1 : Form
    {
        public int Down_Type;                                   //方塊的大種類
        public int Type_Direction;                               //方塊的什麼朝向
        public int Down_Speed = 25;
        public int Control_Speed = 25;                         //左右的速度
        public int[][] map;                                    //pictureBox的二維地圖對映
        public Boolean IsLand = true;                          //是否該產生塊
        public Point CorePosition;                             //左上角用來重新整理的時候定位用的點
        public Boolean Is_Go_Left = false;
        public Boolean Is_Go_Down = false;
        public Boolean Is_Go_Up = false;
        public Boolean Is_Go_Right = false;                    //是否右前進
        public int Max_Right,Max_Buttom;                       //最右邊的橫座標和最下面的豎著的座標
        public int Score = 0;                                  //記分器
        public int level = 1;                                  //難度級別
        public Form1()
        {
            InitializeComponent();
            this.ScorePain.Text = "0";
        }

下面是擦除的函式,實現動畫效果我是直接擦除上一次的痕跡然後重新繪製,但是由於可以按“↑”來改變圖形,多以在擦除的程式碼應該分情況。

 public void ClearScreen() 
        { 
            switch (Down_Type)
            {
                //14列大概是中點
                case 1:
                    {
                            //this.Timer.Text = (CorePosition.X + 1).ToString();
                            //擦除
                            if (Is_Go_Left)
                                CorePosition.Y += 1;
                            if (Is_Go_Right)
                                CorePosition.Y -= 1;
                            if (Is_Go_Down && CorePosition.X > 0)
                                CorePosition.X -= 1;
                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X + 1][CorePosition.Y] = 0;
                            map[CorePosition.X][CorePosition.Y+1] = map[CorePosition.X+1][CorePosition.Y+1] = 0;                        
                        break;
                    }
                case 2:
                    {
                            switch (Type_Direction)
                            {
                                case 1:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                         if (Is_Go_Left)
                                             CorePosition.Y += 1;
                                         if (Is_Go_Right)
                                             CorePosition.Y -= 1;
                                         if (Is_Go_Down)
                                             CorePosition.X -= 1;
                                        if(!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X+1][CorePosition.Y] = 0;
                                            map[CorePosition.X+2][CorePosition.Y] = map[CorePosition.X + 2][CorePosition.Y + 1] = 0;
                                         }
                                        else
                                        {
                                           map[CorePosition.X][CorePosition.Y] = map[CorePosition.X+1][CorePosition.Y] = 0;
                                           map[CorePosition.X + 1][CorePosition.Y + 1] = map[CorePosition.X + 1][CorePosition.Y + 2] = 0;
                                        }
                                        break;
                                    }
                                case 2:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if(!Is_Go_Up)
                                        {
                                           map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y+1] = 0;
                                           map[CorePosition.X][CorePosition.Y+2] = map[CorePosition.X -1][CorePosition.Y+2] = 0;  
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X+1][CorePosition.Y] = 0;
                                            map[CorePosition.X+2][CorePosition.Y] = map[CorePosition.X + 2][CorePosition.Y + 1] = 0;
                                        }
                                        break;
                                    }
                                case 3:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if(!Is_Go_Up)
                                        {
                                           map[CorePosition.X][CorePosition.Y] = map[CorePosition.X+1][CorePosition.Y] = 0;
                                           map[CorePosition.X + 1][CorePosition.Y + 1] = map[CorePosition.X + 1][CorePosition.Y + 2] = 0;
                                        }
                                        else
                                        {
                                           map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y+1] = 0;
                                           map[CorePosition.X][CorePosition.Y+2] = map[CorePosition.X -1][CorePosition.Y+2] = 0;  
                                        }
                                        break;
                                    }
                             }
                        break;
                    }
                case 3:
                    {
                            switch (Type_Direction)
                            {
                                case 1:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if (!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X + 1][CorePosition.Y + 1] = map[CorePosition.X + 1][CorePosition.Y + 2] = 0;
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X + 1][CorePosition.Y] = 0;
                                            map[CorePosition.X][CorePosition.Y + 1] = map[CorePosition.X - 1][CorePosition.Y + 1] = 0;
                                        }
                                        break;
                                    }
                                case 2:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if (!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X + 1][CorePosition.Y] = 0;
                                            map[CorePosition.X][CorePosition.Y + 1] = map[CorePosition.X - 1][CorePosition.Y + 1] = 0;
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X + 1][CorePosition.Y + 1] = map[CorePosition.X + 1][CorePosition.Y + 2] = 0;
                                        }
                                        break;
                                    }
                            }
                            break;
                    }
                case 4:
                    {
                            switch (Type_Direction)
                            {
                                case 1:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if (!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X][CorePosition.Y + 2] = map[CorePosition.X][CorePosition.Y + 3] = 0;
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X + 1][CorePosition.Y] = 0;
                                            map[CorePosition.X + 2][CorePosition.Y] = map[CorePosition.X + 3][CorePosition.Y] = 0; 
                                        }
                                        break;
                                    }
                                case 2:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if (!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X + 1][CorePosition.Y] = 0;
                                            map[CorePosition.X + 2][CorePosition.Y] = map[CorePosition.X + 3][CorePosition.Y] = 0;
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X][CorePosition.Y + 2] = map[CorePosition.X][CorePosition.Y + 3] = 0;
                                        }
                                        break;
                                    }
                            }
                            break;
                    }
                case 5:
                    {
                            switch (Type_Direction)
                            {
                                case 1:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if (!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X][CorePosition.Y + 2] = map[CorePosition.X - 1][CorePosition.Y + 1] = 0;
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X + 1][CorePosition.Y + 1] = map[CorePosition.X - 1][CorePosition.Y + 1] = 0;
                                        }
                                        break;
                                    }
                                case 2:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if (!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X][CorePosition.Y + 2] = map[CorePosition.X + 1][CorePosition.Y + 1] = 0;
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X][CorePosition.Y + 2] = map[CorePosition.X - 1][CorePosition.Y + 1] = 0;
                                        }
                                        break;
                                    }
                                case 3:
                                    {
                                        //this.Timer.Text = (CorePosition.X + 1).ToString();
                                        //擦除
                                        if (Is_Go_Left)
                                            CorePosition.Y += 1;
                                        if (Is_Go_Right)
                                            CorePosition.Y -= 1;
                                        if (Is_Go_Down)
                                            CorePosition.X -= 1;
                                        if (!Is_Go_Up)
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X + 1][CorePosition.Y + 1] = map[CorePosition.X - 1][CorePosition.Y + 1] = 0;
                                        }
                                        else
                                        {
                                            map[CorePosition.X][CorePosition.Y] = map[CorePosition.X][CorePosition.Y + 1] = 0;
                                            map[CorePosition.X][CorePosition.Y + 2] = map[CorePosition.X + 1][CorePosition.Y + 1] = 0;
                                        }
                                        break;
                                    }
                            }
                            break;
                        }
            }
        }

然後是難度的選擇,難度窗體我是在設計的一個窗體,所以需要在兩個窗體中傳遞資料,但是操作起來並沒有想象中的那麼難,直接新增變數就可以完成操作。:

private void menuItem5_Click(object sender, EventArgs e)
        {
            Level L = new Level();
            L.Text = "難度選擇";
            L.ShowDialog();
            level = L.level;
            //MessageBox.Show(level.ToString());
        }

然後是radioButton,有多個的時候想要在初始的時候選中其中一個,那麼它有個屬性Checked可以選擇上為True就行了。

還有一個Key的事件的問題:注意下面的

    KeyCode 獲取 KeyDown 或 KeyUp 事件的鍵盤程式碼。 
   KeyData 獲取 KeyDown 或 KeyUp 事件的鍵資料。 
   KeyValue 獲取 KeyDown 或 KeyUp 事件的鍵盤值。 

其中我使用的列舉值Keys.Up等是用KeyData來實現的:

private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            //MessageBox.Show("Left!");
            if (e.KeyData == Keys.Left && !Is_Go_Left)
            {
                if (CorePosition.Y > 0)
                {
                    CorePosition.Y -= 1;
                    Is_Go_Left = true;
                }
            }
            else if (e.KeyData == Keys.Right && !Is_Go_Right)
            {
                if (Max_Right < 16)
                {
                    CorePosition.Y += 1;
                    Is_Go_Right = true;
                }
            }
            else if (e.KeyData == Keys.Down && !Is_Go_Down)
            {
                if (Max_Buttom < 20)
                {
                    CorePosition.X += 1;
                    Is_Go_Down = true;
                }
            }
            else if (e.KeyData == Keys.Up && !Is_Go_Up)
            {
                  Is_Go_Up = true;
            }
        }


相關文章