C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小

本文实例为大家分享了C#实现扫雷游戏的具体代码,供大家参考,具体内容如下

文章目录

    • 本期内容主要任务是
    • 本期实现的内容如下:
    • 实现代码
    • 实现图片
  • 源代码下载

本期内容主要任务是

1、掌握c#窗体和控件的常用属性和功能
2、完成扫雷游戏的基本功能

本期实现的内容如下:

1、游戏基本功能必须实现。鼠标左键点非雷点,否则游戏结束;鼠标右键一次标记雷点,右键二次取消标记。
2、可以对游戏设置
3、符合游戏逻辑。每个点周围的雷的个数必须正确
4、点开雷点,显示游戏结束,并且显示各个点的情况,还会显示排名
5、点开所有非雷点或者标记完所有雷点时,能够显示游戏胜利
6、不接受键盘操作,只接受鼠标操作

实现代码

主窗体代码

        private void Form1_Load(object sender, EventArgs e)
        {
            //初始化数据
            numbers = new int[length, length];
            isBomb = new bool[length, length];
            isClicked = new bool[length, length];
            isFlaged = new bool[length, length];
            startTime = 0;
            endTime = 0;
            clickNumber = 0;
            this.Text = "扫雷(大小:" + length + ",雷数:" + bombNumber + ")";
            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < length; j++)
                {
                    numbers[i, j] = 0;
                    isBomb[i, j] = false;
                    isClicked[i, j] = false;
                    isFlaged[i, j] = false;
                }
            }
            //初始化按钮
            btns = new Button[length * length];
            //旗子数量
            flagNumber = 0;
            //显示按钮
            int x0 = 5, y0 = 5, w = 30, d = w + 5;

            for (int i = 0; i < btns.Length; i++)
            {
                Button btn = new Button();

                int r = i / length;  //行
                int c = i % length;  //列

                btn.Left = x0 + c * d;
                btn.Top = y0 + r * d;
                btn.Width = w;
                btn.Height = w;
                btn.Font = new Font("楷体", 14);

                btn.Visible = true;
                btns[i] = btn;
                this.pnlBoard.Controls.Add(btn);

                btn.MouseDown += new System.Windows.Forms.MouseEventHandler(this.UpdateClick);

                btn.Name = i.ToString();
            }
        }


        protected void UpdateClick(object sender, MouseEventArgs e)
        {
            //获取按钮
            Button button = (Button)sender;

            //获取该位置数据
            int placeMouse = int.Parse(button.Name);

            //获取坐标
            int x = placeMouse / length;
            int y = placeMouse % length;

            if (e.Button == MouseButtons.Left)
            {
                //MessageBox.Show(button.Name+" ("+x+","+y+")");

                //等价于对button操作
                //判断是否为初次点击
                if (firstClick)
                {
                    initialX = x;
                    initialY = y;

                    //将该位置更改为有地雷再进行生成
                    isBomb[x, y] = true;

                    /
                    /随机生成地图
                    GenerateMap();

                    //这个位置不可能是地雷啊喂!
                    isBomb[x, y] = false;

                    //不再是初次点击
                    firstClick = false;
                }

                //处理当前点击的按钮的信息

                //按钮已被点击过
                if (isClicked[x, y])
                    return;//直接返回

                //点击了一次
                clickNumber++;

                //如果该位置是地雷
                if (isBomb[x, y])
                {
                    GameOver();//游戏结束
                    return;
                }

                //其他情况,特别对待

                //被点击过了
                isClicked[x, y] = true;

                //更改色调,以区分点击与未点击
                button.BackColor = Color.DarkGray;

                //显示地图
                if (numbers[x, y] != 0)
                    button.Text = numbers[x, y].ToString();

                spreadMap(x, y);

                //点击获胜
                if(clickNumber==length*length-bombNumber)
                {
                    GameWin();
                }
            }
            else if (e.Button == MouseButtons.Right)
            {
                //点击过了,就直接跳过
                if (isClicked[x, y] == true)
                    return;

                if(isFlaged[x,y]==false)
                {
                    // 显示炸弹图
                    button.BackgroundImage = Image.FromFile(flagPath);

                    //标记
                    isFlaged[x, y] = true;

                    //插旗数量++
                    flagNumber++;
                }
                else
                {
                    //撤回标记
                    button.BackgroundImage = null;
                    isFlaged[x, y] = false;

                    flagNumber--;
                }

                //判断是否能通过插旗获得游戏胜利
                if (flagNumber==bombNumber)
                {
                    for (int i = 0; i < length; i++)
                    {
                        for (int j = 0; j < length; j++)
                        {
                            if (isFlaged[i, j] == false)
                                continue;
                            if (isBomb[i, j] == false)
                                return;//插旗错误,无法获得游戏胜利
                        }
                    }
                    //执行到这个语句表明找对了
                    GameWin();
                }
            }

        }

       

        public void GameOver()
        {
            //显示地图全貌
            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < length; j++)
                {
                    //如果之前被插了旗子
                    if (isFlaged[i, j] == true)
                    {
                        isFlaged[i, j] = false;
                        btns[i * length + j].BackgroundImage = null;
                    }

                    if (isClicked[i, j] == true)
                        continue;

                    //更改色调,以区分点击与未点击
                    btns[i*length+j].BackColor = Color.DarkGray;

                    //全部设置为完成点击
                    isClicked[i, j] = true;

                    //如果是炸弹
                    if (isBomb[i, j])
                    {
                        btns[i * length + j].BackgroundImage = Image.FromFile(bombPath,true);
                        continue;
                    }

                    //显示地图
                    if (numbers[i, j] != 0)
                        btns[i * length + j].Text = numbers[i, j].ToString();
                }
            }

            MessageBox.Show("你输了!");

            RestartGame(bombNumber, length);
        }

        public void GameWin()
        {
            //显示地图全貌
            for (int i = 0; i < length; i++)
            {
                for (int j = 0; j < length; j++)
                {
                    //如果之前被插了旗子
                    if (isFlaged[i, j] == true)
                    {
                        isFlaged[i, j] = false;
                        btns[i * length + j].BackgroundImage = null;
                    }

                    if (isClicked[i, j] == true)
                        continue;

                    //更改色调,以区分点击与未点击
                    btns[i * length + j].BackColor = Color.DarkGray;

                    //全部设置为完成点击
                    isClicked[i, j] = true;

                    //如果是炸弹
                    if (isBomb[i, j])
                    {
                        btns[i * length + j].BackgroundImage = Image.FromFile(bombPath, true);
                        continue;
                    }

                    //显示地图
                    if (numbers[i, j] != 0)
                        btns[i * length + j].Text = numbers[i, j].ToString();
                }
            }

            游戏胜利__ fp = new 游戏胜利__(length, bombNumber, endTime - startTime);
            fp.Owner = this;
            this.Hide();
            fp.ShowDialog();

        }

        //以x,y为起点扩展地图
        public void spreadMap(int x,int y)
        {
            //判断该位置的八个方向
            //左上
            if (x != 0 && y != 0 && isBomb[x - 1, y - 1] == false && isClicked[x - 1, y - 1] == false)
            {
                //点击过了
                isClicked[x - 1, y - 1] = true;

                //更改色调,以区分点击与未点击
                btns[(x - 1) * length + y - 1].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x-1, y-1] == true)
                {
                    isFlaged[x-1, y-1] = false;
                    btns[(x - 1) * length + y - 1].BackgroundImage = null;
                }

                if (numbers[x - 1, y - 1] != 0)
                    btns[(x - 1) * length + y - 1].Text = numbers[x - 1, y - 1].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x - 1, y - 1);
                }
            }
            //正上
            if (x != 0 && isBomb[x - 1, y] == false && isClicked[x - 1, y ] == false)
            {
                //点击过了
                isClicked[x - 1, y] = true;

                //更改色调,以区分点击与未点击
                btns[(x - 1) * length + y].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x - 1, y ] == true)
                {
                    isFlaged[x - 1, y - 1] = false;
                    btns[(x - 1) * length + y ].BackgroundImage = null;
                }

                if (numbers[x - 1, y] != 0)
                    btns[(x - 1) * length + y].Text = numbers[x - 1, y].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x - 1, y);
                }
            }
            //右上
            if (x != 0 && y!=length-1&&isBomb[x - 1, y+1] == false && isClicked[x - 1, y + 1] == false)
            {
                //点击过了
                isClicked[x - 1, y + 1] = true;

                //更改色调,以区分点击与未点击
                btns[(x - 1) * length + y + 1].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x - 1, y + 1] == true)
                {
                    isFlaged[x - 1, y + 1] = false;
                    btns[(x - 1) * length + y + 1].BackgroundImage = null;
                }

                if (numbers[x - 1, y + 1] != 0)
                    btns[(x - 1) * length + y + 1].Text = numbers[x - 1, y + 1].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x - 1, y + 1);
                }
            }
            //正左方
            if (y != 0 && isBomb[x, y - 1] == false && isClicked[x , y - 1] == false)
            {
                //点击过了
                isClicked[x, y - 1] = true;

                //更改色调,以区分点击与未点击
                btns[x * length + y - 1].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x , y - 1] == true)
                {
                    isFlaged[x , y - 1] = false;
                    btns[x * length + y - 1].BackgroundImage = null;
                }

                if (numbers[x, y - 1] != 0)
                    btns[x * length + y - 1].Text = numbers[x, y - 1].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x, y - 1);
                }
            }
            //正右方
            if (y != length - 1 && isBomb[x, y + 1] == false && isClicked[x, y + 1] == false)
            {
                //点击过了
                isClicked[x, y + 1] = true;

                //更改色调,以区分点击与未点击
                btns[x * length + y + 1].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x, y + 1] == true)
                {
                    isFlaged[x, y + 1] = false;
                    btns[x * length + y + 1].BackgroundImage = null;
                }

                if (numbers[x, y + 1] != 0)
                    btns[x * length + y + 1].Text = numbers[x, y + 1].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x, y + 1);
                }
            }
            //左下方
            if (x != length - 1 && y != 0 && isBomb[x + 1, y - 1] == false && isClicked[x + 1, y - 1] == false)
            {
                //点击过了
                isClicked[x + 1, y - 1] = true;

                //更改色调,以区分点击与未点击
                btns[(x + 1) * length + y - 1].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x + 1, y - 1] == true)
                {
                    isFlaged[x + 1, y - 1] = false;
                    btns[(x + 1) * length + y - 1].BackgroundImage = null;
                }

                if (numbers[x + 1, y - 1] != 0)
                    btns[(x + 1) * length + y - 1].Text = numbers[x + 1, y - 1].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x + 1, y - 1);
                }
            }
            //正下方
            if (x != length - 1 && isBomb[x + 1, y] == false && isClicked[x + 1, y] == false)
            {
                //点击过了
                isClicked[x + 1, y] = true;

                //更改色调,以区分点击与未点击
                btns[(x + 1) * length + y].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x + 1, y ] == true)
                {
                    isFlaged[x + 1, y ] = false;
                    btns[(x + 1) * length + y ].BackgroundImage = null;
                }

                if (numbers[x + 1, y] != 0)
                    btns[(x + 1) * length + y].Text = numbers[x + 1, y].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x + 1, y);
                }
            }
            //右下方
            if (x != length - 1 && y != length - 1 && isBomb[x + 1, y + 1] == false && isClicked[x + 1, y + 1] == false)
            {
                //点击过了
                isClicked[x + 1, y + 1] = true;

                //更改色调,以区分点击与未点击
                btns[(x + 1) * length + y + 1].BackColor = Color.DarkGray;

                //点击次数
                clickNumber++;

                if (isFlaged[x + 1, y + 1] == true)
                {
                    isFlaged[x + 1, y + 1] = false;
                    btns[(x + 1) * length + y + 1].BackgroundImage = null;
                }

                if (numbers[x + 1, y + 1] != 0)
                    btns[(x + 1) * length + y + 1].Text = numbers[x + 1, y + 1].ToString();
                else
                {
                    //非零需要继续拓展
                    spreadMap(x + 1, y + 1);
                }
            }

            //返回
            return;
        }

        private void 新游戏ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //MessageBox.Show()
            RestartGame(bombNumber, length);
        }

实现图片

扫雷界面
C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小_第1张图片
插红旗样式展示
C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小_第2张图片
输赢展示
C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小_第3张图片
C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小_第4张图片
游戏设置展示
C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小_第5张图片
C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小_第6张图片
排行榜展示
C# winfrom实现扫雷游戏、设置雷数、显示排名、设置大小_第7张图片

源代码下载

你可能感兴趣的:(C#,winfrom,扫雷,c#,游戏,开发语言)