1. 程式人生 > >一個簡單的俄羅斯方塊實現

一個簡單的俄羅斯方塊實現

最近在看《.NET遊戲程式設計入門經典 C#篇》 第一章介紹瞭如何製作俄羅斯方塊,自己試了試按照書上的步驟,可算是完成了。

於是寫下這篇文章留作紀念。

1.類的設計

在充分分析遊戲的特點後,遊戲大概可以分為3個類:Square 小正方形,Block 由4個小正方形組合成的一個圖形, GameField 遊戲的驅動引擎

2.程式碼的編寫

按照從小到大,從簡單到複雜的順序,先完成Square類,Square很簡單,只需要提供Show,Hide方法以及Size,Location屬性。

接下來是Block,Block相對比較複雜,分為以下幾種:


它應該有4個Square 編號可以按照個人習慣,當然之後計算座標的時候也要根據個人的編號來進行。

Block應該有Hide,Show,Left,Right,Rotate一些方法,屬性的話為了計算座標 應該有Square的大小,還有Color

要注意的是Rotate方法將Block順時針旋轉90°,圖上已經標出旋轉的中心。

最後剩下的就是GameField了,他應該有一個數組,儲存背景中所有的Square,以及哪些位置有Square的 位標誌陣列,對每一行的檢查(是否消去得分)以及消去所有方塊下移操作。

這些類完成後就可以簡單的寫遊戲邏輯了,因為太簡單就不說了,簡單的貼一下程式碼

        private Block currentBlock;
        private Block nextBlock;
        private int score;
        private bool blockFalling;

        private void button1_Click(object sender, EventArgs e)
        {
            pictureBox1.Refresh();
            currentBlock = new Block(new Point(GameField.Width / 2 * GameField.SquareSize, 0), Block.BlockTypes.Undefined);
            currentBlock.Show(GameField.WinHandle);
            nextBlock = new Block(new Point(15, 15), Block.BlockTypes.Undefined);
            nextBlock.Show(pictureBox2.Handle);
            timer1.Enabled = true;
            button1.Enabled = false;
            Focus();
            score = 0;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            GameField.WinHandle = pictureBox1.Handle;
            GameField.BackColor = pictureBox1.BackColor;
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (currentBlock == null)
            {
                return;
            }
            switch (e.KeyCode)
            {
                case Keys.W:
                    currentBlock.Rotate();
                    break;
                case Keys.S:
                    currentBlock.Down();
                    break;
                case Keys.A:
                    currentBlock.Left();
                    break;
                case Keys.D:
                    currentBlock.Right();
                    break;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (!currentBlock.Down())
            {
                blockFalling = false;
                //塞滿了 遊戲結束  0 0
                if (currentBlock.Top() == 0)
                {
                    timer1.Enabled = false;
                    button1.Enabled = true;
                    GameField.Reset();
                    MessageBox.Show("恭喜你跪了");
                    return;
                }
                
            }
            else
            {
                blockFalling = true;
            }
            if (!blockFalling)
            {
                //檢查得分
                int earseCount = GameField.CheckLines();
                if (earseCount > 0)
                {
                    score += earseCount * 20;
                    label1.Text = score.ToString();
                    //使圖片框重繪 清楚Block
                    pictureBox1.Invalidate();
                    Application.DoEvents();
                    GameField.Redraw();
                }
                pictureBox2.Invalidate();
                Application.DoEvents();
                currentBlock = new Block(new Point(GameField.Width / 2 * GameField.SquareSize, 0), nextBlock.BlockType);
                currentBlock.Show(GameField.WinHandle);


                nextBlock = new Block(new Point(15, 15), Block.BlockTypes.Undefined);
                nextBlock.Show(pictureBox2.Handle);
                blockFalling = true;
            }
        }

        private void Form1_Activated(object sender, EventArgs e)
        {
            GameField.Redraw();
            if (nextBlock !=null)nextBlock.Show(pictureBox2.Handle);
        }

3.總結

這個簡單的遊戲,可謂是剛好適合新手。可以學到衝突檢測(CheckLines),遊戲中基本元素與遊戲驅動的理解。