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并把相关图片与声音资源包含进来.

给Start窗体的ICON选择图片小狗.ico

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

progressBar记得value值选100

 

 

在加载声音pictureBox时为Image属性选择图片

在加入了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();
        }





  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值