我们专注孝感网站设计 孝感网站制作 孝感网站建设
成都网站建设公司服务热线:18982081108

网站建设知识

十年网站开发经验 + 多家企业客户 + 靠谱的建站团队

量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决

C#如何开发扫雷游戏-创新互联

简单的总结一下,如何利用C#进行WinForm 扫雷小游戏的开发:

目前成都创新互联已为1000+的企业提供了网站建设、域名、虚拟空间、网站托管运营、企业网站设计、南乐网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。

扫雷游戏的主要设计的类有三个: Main、Pane 、MineField

1)Main 是主控窗体,负责项目的启动和关闭;并协调内部各个组建模块的协调工作。

2)Pane是一个方格的封装,是雷区的重要组建;它表示一个方格的当前状态,以及是否布雷等信息。

3)MineField是雷区的封装,是游戏的核心组建;它负责方格的布局以及地雷的分布;并控制玩家的基本操作以及正确的响应。

类的实现:

一、 Pane类

功能描述:Pane是一个方格的封装,是雷区的重要组建;它表示一个方格的当前状态,以及是否布雷等信息

One.它所具有的公共属性:

名称

可见性

返回值类型

功能描述

AroundMineCount

public

int

获取或设置当前方块周围地雷的数量

HasMine

Public

bool

获取或设置当前方块是否又雷

State

Public

PaneState

获取或设当前方块扫雷的状态

Two.它所具有的公共方法:

名称

可见性

返回类型

参数

功能描述

Mark

public

void

无

把当前方块标记为【有雷】状态,即:插上一个小红旗。

Open

public

void

无

打开该方块。

打开后如果如果有雷,则显示地理图标;否则如果周围有相邻的地理,则显示地雷数量。

Reset

public

void

无

恢复关闭状态,即:取消Mark()的操作结果。

Three:源码:

//默认的构造方法

public Pane()

        {InitializeComponent();

this.BackgroundImageLayout = ImageLayout.Stretch;

}

//公有属性:

        Public  bool  HasMine { get; set; }

Public  int  AroundMineCount { get; set; }

Public  PaneState  State { get; set; }  //由于它有几种状态,设置一个枚举类型属性

public enum PaneState

        {

           Closed,   //关闭状态

           Opened,  //打开状态

           Marked,  //标记状态

     }

//共有方法:

public void Mark()    //标记当前方格为又雷状态,插个小红旗

        {

            this.BackgroundImage = Properties.Resources.Marked;

            this.State = PaneState.Marked;

        }

  public void Reset()   //恢复标记状态,取消小红旗标记

        {

            this.BackgroundImage = null;

            this.State = PaneState.Closed;

        }

//打开方法

     //打开后如果如果有雷,则显示地理图标;否则如果周围有相邻的地理,则显示地雷数量。

      public void Open()

        {

            if (this.HasMine)

            {

                this.BackgroundImage = Properties.Resources.MineBomp;

                this.Enabled = false;

            }

            else

            {

                switch (this.AroundMineCount)

                {

                    case 0:

                        this.BackgroundImage = null;

                        this.Enabled = false;

                        break;

                    case 1:

                        this.BackgroundImage = Properties.Resources.Num1;

                        this.Enabled = false;

                        break;

                    case 2:

                        this.BackgroundImage = Properties.Resources.Num2;

                        this.Enabled = false;

                        break;

                    case 3:

                        this.BackgroundImage = Properties.Resources.Num3;

                        this.Enabled = false;

                        break;

                    case 4:

                        this.BackgroundImage = Properties.Resources.Num4;

                        this.Enabled = false;

                        break;

                    case 5:

                        this.BackgroundImage = Properties.Resources.Num5;

                        this.Enabled = false;

                        break;

                    case 6:

                        this.BackgroundImage = Properties.Resources.Num6;

                        this.Enabled = false;

                        break;

                    case 7:

                        this.BackgroundImage = Properties.Resources.Num7;

                        this.Enabled = false;

                        break;

                    case 8:

                        this.BackgroundImage = Properties.Resources.Num8;

                        this.Enabled = false;

                        break;

                }

            }

       }

二、 MineField类

功能描述:CrlMineField是雷区的封装,是游戏的核心组建;它负责方格的布局以及地雷的分布;并控制玩家的基本操作以及正确的响应。

One.它所具有的公有方法

名称

可见性

返回值类型

参数

功能描述

InitMineField

Public

Void

int paneNumber, int mineNumber

初始化雷区。布局方格并随机分布地理。

DisplayAll

Public

Void

无

明示雷区的全部方块里的内容。当踩雷以后,给玩家显示所有地雷位置。

DisplayAround

Pubic

Void

Pane pane

明示与给定方格相关联的无地雷的方格。玩家点击一个无雷方格后使用。

Two.它有具有的私有方法

名称

可见性

返回值类型

参数

功能描述

GetPanesAround

Private

List

Pane pane

获取与当前方格相邻的所有方格。

GetMineCountAround

Private

int

Pane pane

获取周围地雷的总数量

GetPaneSize

Private

Size

无

获取每个小方格的大小

LayoutPanes

Private

Void

无

排列有所方格,完成布雷

LayMines

Private

Void

int mineNumber

随机布雷

IsAllMineSweeped

Private

Bool

无

判断是否扫雷成功

Three.事件处理

名称

可见性

返回值类型

参数

功能描述

MineField_SizeChanged

Private

Void

object sender, EventArgs e

如果雷区面板尺寸有变化,则重新进行布局。

OnPaneMouseDown

Private

Void

object sender, EventArgs e

仅处理鼠标左键和右键事件,忽略其他按键。

Four.源码

//事件的委托

public delegate void MineSweepingCompletedEventHandler(object sender, EventArgs e);

public delegate void MineSweepingFailedEventHandler(object sender, EventArgs e);

public partial class CrlMineField : UserControl

{

//成功和失败两个委托事件的申明

        public event MineSweepingCompletedEventHandler MineSweepingCompleted;

        public event MineSweepingFailedEventHandler MineSweepingFailed;

        public CrlMineField()

        {

            InitializeComponent();

        }

        /// 

        /// 初始化雷区

        /// 

        /// 每排方块的数量

        /// 地雷的数量

        public void InitMineField(int paneNumber, int mineNumber)

        {

            if (mineNumber >= paneNumber * paneNumber)

            {

                throw new ApplicationException("地雷太多了,不合法游戏规则。");

            }

            // 清空现有的所有方块

            if (this.Controls.Count > 0)

            {

                this.Controls.Clear();

            }

            //添加雷区方格

            for (int i = 0; i < paneNumber * paneNumber; i++)

            {

                Pane pane = new Pane();

                pane.MouseDown += new MouseEventHandler(OnPaneMouseDown);

                this.Controls.Add(pane);

            }

          // 布局方格

            this.LayoutPanes();

            // 随机部署地雷

            this.LayMines(mineNumber);

            // 设置每个方格周边的地雷数

            foreach (Pane p in this.Controls)

            {

                p.AroundMineCount = this.GetMineCountAround(p);

            }

        }

        /// 

        /// 明示雷区的全部方块里的内容

        /// 

        public void DisplayAll()

        {

            foreach (Pane pane in this.Controls)

            {

                if (pane.State != PaneState.Opened)

                {

                    pane.Open();

                }

            }

        }

        /// 

        /// 明示与给定方格相关联的无地雷的方格

        /// 

        /// 

        public void DisplayAround(Pane pane)

        {

            if (pane.State == PaneState.Opened || pane.HasMine)

            {

                return;

            }

            // 明示当前方格本身

            pane.Open();

            // 通过递归明示当前方格四周的所有方格

            List panesAround = this.GetPanesAround(pane);

            foreach (Pane p in panesAround)

            {

                // 如果该方格四周没有相邻的地雷,则递归

                if (this.GetMineCountAround(p) == 0)

                {

                    this.DisplayAround(p);

                }

                else

                {

                    if (p.State != PaneState.Opened && !p.HasMine)

                    {

                        p.Open();

                    }

                }

            }

}

#region 私有方法

        /// 

        /// 获取与当前方格相邻的所有方格。

        /// 

        /// 当前方格

        /// 

        private List GetPanesAround(Pane pane)

        {

            List result = new List();

            // 通过递归明示当前方格四周的所有方格

            int paneHeight = this.GetPaneSize().Height;

            int paneWidth = this.GetPaneSize().Width;

            foreach (Pane p in this.Controls)

            {

                逐个扫描当前方格四周地雷数目

                if (Math.Abs(p.Top - pane.Top) == 0 && Math.Abs(p.Left - pane.Left) == paneWidth

                    ||

                    Math.Abs(p.Left - pane.Left) == 0 && Math.Abs(p.Top - pane.Top) == paneHeight

                    ||

                    Math.Abs(p.Top - pane.Top) == paneHeight && Math.Abs(p.Left - pane.Left) == paneWidth

                    ||

                    Math.Abs(p.Left - pane.Left) == paneWidth && Math.Abs(p.Top - pane.Top) == paneHeight)

                {

                    result.Add(p);

                }

            }

            return result;

        }

        /// 

        /// 获取当前方格四周地雷数量

        /// 

        /// 当前方格

        /// 

        private int GetMineCountAround(Pane pane)

        {

            int result = 0;

            List panes = this.GetPanesAround(pane);

            foreach (Pane p in panes)

            {

                if (p.HasMine)

                {

                    result++;

                }

            }

            return result;

        }

        /// 

        /// 获取当前每个方格的尺寸

        /// 

        /// 

        private Size GetPaneSize()

        {

            if (this.Controls.Count == 0)

            {

                return new Size();

            }

            else

            {

                int paneNumber = (int)Math.Sqrt(this.Controls.Count);

                int paneWidth = this.Width / paneNumber;

                int paneHeight = this.Height / paneNumber;

                return new Size(paneWidth, paneHeight);

            }

        }

        /// 

        /// 排列所有雷区的方格,完成布局。

        /// 

        private void LayoutPanes()

        {

            if (this.Controls.Count <= 0)

            {

                return;

            }

            int paneNumber = (int)Math.Sqrt(this.Controls.Count);

            int paneHeight = this.GetPaneSize().Height;

            int paneWidth = this.GetPaneSize().Width;

            int paneIndex = 0;

            // 绘制雷区方块

            int paneLeft = 0;

            int paneTop = 0;

            for (int colNum = 0; colNum < paneNumber; colNum++)

            {

                paneTop = colNum * paneHeight;

                for (int rowNum = 0; rowNum < paneNumber; rowNum++)

                {

                    paneLeft = rowNum * paneWidth;

                    Pane pane = this.Controls[paneIndex] as Pane;

                    pane.Location = new Point(paneLeft, paneTop);//设置方块位置

                    pane.Size = new Size(paneWidth, paneHeight);//设置方块大小

                    paneIndex++;

                }

            }

        }

        /// 

        /// 随机部署地雷

        /// 

        /// 

        private void LayMines(int mineNumber)

        {

            Random rdm = new Random();

            for (int i = 0; i < mineNumber; i++)

            {

                while (true)

                {

                    int index = rdm.Next(0, this.Controls.Count);

                    Pane pane = this.Controls[index] as Pane;

                    if (!pane.HasMine)

                    {

                        pane.HasMine = true;

                        break;

                    }

                }

            }

        }

        /// 

        /// 是否扫雷成功。即:所有地雷都已经正确作出标记

        /// 

        /// 

        private bool IsAllMineSweeped()

        {

            int markedCount = 0;

            int mineCount = 0;

            foreach (Pane pane in this.Controls)

            {

                if (pane.HasMine)

                {

                    mineCount++;

                }

                if (pane.State == PaneState.Marked)

                {

                    markedCount++;

                    if (!pane.HasMine)

                    {

                        //存在做了标记但没有地雷的方格,扫雷没有正确完成。

                        return false;

                    }

                }

            }

            return mineCount == markedCount;

        }

        #endregion

        #region 事件处理

        /// 

        /// 如果雷区面板尺寸有变化,则重新进行布局。

        /// 使得通过改变方格大小来整体适应雷区面板的尺寸。

        /// 

        /// 

        /// 

        private void CrlMineField_SizeChanged(object sender, EventArgs e)

        {

            try

            {

                this.LayoutPanes();

            }

            catch (Exception ex)

            {

                ExceptionHandler.OnException(ex);

            }

        }

        private void OnPaneMouseDown(object sender, MouseEventArgs e)

        {

            // 仅处理鼠标左键和右键事件,忽略其他按键。

            if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right)

            {

                return;

            }

            try

            {

                Pane pane = sender as Pane; //获取当前被鼠标点中的方格

                if (e.Button == MouseButtons.Left)//鼠标左键

                {

                    if (pane.HasMine) //踩地雷了

                    {

                        pane.Open();

                        this.DisplayAll();

                        if (this.MineSweepingFailed != null)

                        {

                            this.MineSweepingFailed(this, EventArgs.Empty);

                        }

                    }

                    else

                    {

                        //明示当前方格相邻的所有无地雷的方格

                        this.DisplayAround(pane);

                    }

                }

                else if (e.Button == MouseButtons.Right)//鼠标右键

                {

                    if (pane.State == PaneState.Marked)

                    {

                        pane.Reset();//取消小红旗标记

                    }

                    else

                    {

                        pane.Mark(); //插个小红旗做标记

                    }

                }

                // 所有地雷扫除成功

                if (this.IsAllMineSweeped())

                {

                    if (this.MineSweepingCompleted != null)

                    {

                        this.MineSweepingCompleted(this, EventArgs.Empty);

                    }

                }

            }

            catch (Exception ex)

            {

               ExceptionHandler.OnException(ex);

            }

        }

        #endregion

三、Main类

      还未完善,负责各个模块的协调工作,如导航菜单里面设置游戏的开始,结束,时间计时,保存结果,查看排行榜,游戏的级别等,由于周末两天的时间还未能将其完善,只实现了一个大体的功能,当然还存在一些Bug,有待调试!

附属插图:

C#如何开发扫雷游戏C#如何开发扫雷游戏C#如何开发扫雷游戏C#如何开发扫雷游戏

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网站栏目:C#如何开发扫雷游戏-创新互联
转载源于:http://www.ytofo.com/article/csdjjp.html

其他资讯