天天看點

C#開發------對對碰遊戲

轉載請标明是引用于 http://blog.csdn.net/chenyujing1234

 例子代碼:

 http://www.rayfile.com/zh-cn/files/9d09926e-736b-11e1-b9a4-0015c55db73d/

設計思路:

由10*10組成,圖案更不相同,為存儲遊戲畫面中的圖案方塊,采用Block類二維數組blocks[10,10];

在定時器控制下,不停地統計使用者的得分,并控制生命進度條,如果生命進度條為0,則遊戲結束。

當使用者滑鼠連續選中兩相鄰塊firstblock2和secondblock2,交換以後調用check()檢測是否有符合消去

的方塊,如果有被消去的方塊則修改要繪制的圖案代号rectan2[10,10]數組對應的元素值,不需要繪制為0.

通過按列統計rectan2數組0值,得出每列被消去的方塊的個數,并調用fill()從遊戲螢幕該列上方重新随機産生新的方塊,

依次下移填充被削去方塊,重畫需要繪制的所有方塊,進而看到動态效果。

下面介紹設計過程:

1、建立一C# windows窗體工程。

将Form1.cs改名為Start.cs

在解決方案中添加兩個檔案平:images sound并把相關圖檔與聲音資源包含進來.

C#開發------對對碰遊戲

給Start窗體的ICON選擇圖檔小狗.ico

2、窗體Start.cs添加新控件

progressBar記得value值選100

C#開發------對對碰遊戲
C#開發------對對碰遊戲

在加載聲音pictureBox時為Image屬性選擇圖檔

C#開發------對對碰遊戲

在加入了statusStrip contextMenuStrip timer1後,接下來為statusStrip添加toolStripDropDownButton

方法是右擊statusSctrip1右選擇編輯項,然後從清單中選擇toolStripDropDownButton1然後點添加

3、界面算是畫好了,接下來開始進行代碼設計.

建立Block.cs檔案來定義方塊的坐标位置、小方塊圖案、圖案種類代号字段成員及通路相應的屬性.

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using SuperPeng.Properties;

namespace SuperPeng
{
    /*本類描述的對象是對對碰的每個小方塊*/
    class Block
    {
        private Point location; //小方塊坐标
        private Bitmap blockImage; //小方塊圖案
        private int imageType;  //圖檔種類
        public int ImageType//ImageType屬性
        {
            get
            {
                return imageType;
            }
        }
        public Point Location//Location屬性
        {
            get
            {
                return location;
            }
            set
            {
                location= value;
                
            }
        }

        public Block(int imageIndex,int x,int y)
        {
            location = new Point(x, y);
            imageType = imageIndex;
            //初始化小方塊圖案
            switch (imageIndex)
            {
                case 1:
                    blockImage = Resources._1;
                    break;
                case 2:
                    blockImage = Resources._2;
                    break;
                case 3:
                    blockImage = Resources._3;
                    break;
                case 4:
                    blockImage = Resources._4;
                    break;
                case 5:
                    blockImage = Resources._5;
                    break;
                case 6:
                    blockImage = Resources._6;
                    break;
                case 7:
                    blockImage = Resources._7;
                    break;
                case 8:
                    blockImage = Resources._8;
                    break;
                default:
                    blockImage = Resources._4;
                    imageType = 4;
                    break;
            }
        }

        /*畫對象*/
        public void Draw(Image img)
        {
            Graphics g = Graphics.FromImage(img);
            Rectangle r = new Rectangle(location, new Size(50, 50));
            g.DrawImage(blockImage, r);
        }
        public void DrawSelectedBlock(Graphics g)
        {
            //畫選中方塊的示意邊框線
            Pen myPen = new Pen(Color.Black, 3);
            Rectangle r = new Rectangle(location, new Size(50, 50));
            g.DrawRectangle(myPen, r);
        }
        public void ClearSelectedBlock(int x, int y, Graphics g)
        {
            //清除選中方塊

        }
    }
}
           

Block()構造函數,參數提供了方塊圖案種類的代号imageIndex 及坐标位置(x,y),該構造函數中Switch(/case根據方塊種類代号設定相應的方塊圖案。

Draw(方法将方塊畫在Image對象上,而不是遊戲面闆上,這樣便于采用雙緩沖技術。

DrawSelectedBlock将方塊周圍選中的示意邊框線,這是直接畫在傳遞過來的遊戲面闆上,而不是IMage對象上

4、接下來設計GameField.cs。

它是遊戲執行個體,首先定義在遊戲面闆中存儲所有方塊的容器 ----  二維數組 blocks[10,10],記錄要繪制方塊的圖案代号rectan2[10,10]數組

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Media;
using SuperPeng.Properties;

namespace SuperPeng
{
    /*
     * 場景大小:500×500
     * 方塊大小:50×50
     */
    class GameField
    {
        public  IntPtr winHandle;
        public  Image bufferImage;  //雙緩存
        public  Block[,] blocks=new Block[10,10]; //場景中所有的小圖檔
        //存儲繪制的方塊圖案帶代号的數組,不需繪制的值為0
        private int[,] rectan2 = new int[10, 10];
        private int[] empty = new int[10];//每列有多少個可以消去方塊
        private int RowSames = 1; //檢測到同行相同數
        private int ColumSames = 1; //檢測到同列相同數
        private SoundPlayer sound = new SoundPlayer();
        public  bool soundSwitch = true;//聲音開關   true為開
           

遊戲場景類GameField中生成場景中所有的Block方塊對象,調用createAll畫在遊戲面闆中

/*生成場景中所有的對象*/
        public void createAll()
        {
            Random rand = new Random();
            for (int i = 0; i < 10; i++)
                for (int j = 0; j < 10; j++)
                {
                    Block b = new Block(rand.Next(8) + 1, j * 50, i * 50);
                    blocks[i, j] = b;
                    //rectan[i,j] = b.ImageType;//******************7-06
                    rectan2[i, j] = b.ImageType;
                }
            reDraw();
        }
           

reDraw();采用雙緩沖技術。先将所有的方塊繪制在Image對象bufferImage上,然後将繪制好的bufferImage顯示在遊戲面闆上.

exchange(int x1, int y1, int x2, int y2)交換選中兩個相鄰的方塊

/*交換兩個方塊,參數x,y為矩陣坐标*/
        public void exchange(int x1, int y1, int x2, int y2)
        {
            //交換blocks
            Block temp = blocks[x1, y1];
            blocks[x1, y1] = blocks[x2, y2];
            blocks[x2, y2] = temp;

            交換rectan  //******************7-06
            //rectan[x1, y1] = blocks[x1, y1].ImageType;
            //rectan[x2, y2] = blocks[x2, y2].ImageType;

            //交換rectan2
            rectan2[x1, y1] = blocks[x1, y1].ImageType;
            rectan2[x2, y2] = blocks[x2, y2].ImageType;

            //交換坐标
            Point tmploc = blocks[x1, y1].Location;
            blocks[x1, y1].Location = blocks[x2, y2].Location;
            blocks[x2, y2].Location = tmploc;

            PlaySound("Exchange");
            //重畫一下
            reDraw();

        }
           

check()完成檢測是否有3上以上方塊對象有相同的圖像并傳回可以消除的方塊個數。

若有超過3個(含3個)則儲存要繪制方塊的圖案代号的rectan2[10,10]數組對應元素的值為0,通過統計rectan2數組0值,

得出每列被消去方塊的個數及所有列被消去方塊的總線.

/*對對碰檢測,傳回可以消除方塊對象的個數*/
        public  int check()
        {
            //檢測是否同行或列有超過3個一樣
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    //for内開始
                    //行檢測
                    if (j == 0)
                        RowSames = 1;
                    else
                    {
                        if (blocks[i, j - 1].ImageType == blocks[i, j].ImageType)//圖案相同
                            RowSames++;
                        else
                        {
                            if (RowSames >= 3)
                            {
                                //該位置之前rowsames個格子的物體都要消除
                                for (int n = 1; n <= RowSames; n++)
                                    rectan2[i, j - n] = 0;
                            }
                            RowSames = 1;
                        }
                        if (j==9&&RowSames >= 3)
                        {
                            //該位置之前rowsames個格子的物體都要消除
                            for (int n = 1; n <= RowSames; n++)
                                rectan2[i, 10 - n] = 0;
                        }
                    }
                    
                   
                    //列檢測
                    if (j == 0)
                        ColumSames = 1;
                    else
                    {
                        if (blocks[j - 1, i].ImageType == blocks[j, i].ImageType)//圖案相同
                            ColumSames++;
                        else
                        {
                            if (ColumSames >= 3)
                            {
                                //該位置之上的columsames個格子的物體要消除
                                for (int n = 1; n <= ColumSames; n++)
                                    rectan2[j - n, i] = 0;
                            }
                            ColumSames = 1;
                        }
                        if (j==9&&ColumSames >= 3)
                        {
                            //該位置之前rowsames個格子的物體都要消除
                            for (int n = 1; n <= ColumSames; n++)
                                rectan2[10 - n, i] = 0;
                        }
                    }
                    //for内結束
                }
            }
            RowSames = 1;
            ColumSames = 1;
            //檢測每列有多少個空格
            int temp=0;
            int result = 0;//總和
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 10; j++)
                {
                    if (rectan2[j, i] == 0)
                        temp++;
                }
                empty[i] = temp;
                result += temp;
                temp = 0;
            }
            //reDraw();
            return result;
        }
           

fill()從遊戲螢幕該列上方重新随機産生新的方塊,依次下移填充被削去的方塊,重畫需要繪制的所有方塊

/*生成填補*/
        public  void fill() 
        {
            Random rand = new Random();
            for (int j = 0; j < 10;j++ ) //每列
            {
                if(empty[j] > 0)
                {
                    for (int i = 0; i < 10; i++) //每行
                    {
                        while(rectan2[i, j] == 0)
                        {
                            if (i >0)
                            {//空格之後的所有圖檔向下移一位
                                for (int n = i-1; n>=0; n--)
                                    down(n,j);
                            }
                            //填充最頂上一格方塊
                            Block tb = new Block(rand.Next(8) + 1, j * 50,0 );
                            blocks[0, j] = tb;
                            //rectan[0, j] = tb.ImageType;
                            rectan2[0, j] = tb.ImageType;
                        }
                    }
                   //本來想在這裡重畫,不料令遊戲速度太慢
                }
            }
            PlaySound("AddScore");
            //重畫一下
            reDraw();
        }




           

繼續閱讀