基础思路

像原版一样把扫雷分为三个难度:初级难度9*9,中级难度16*16,高级难度16*30

做一个游戏需要图片资源,去网上下载了关于 扫雷的有关文件,放在了项目中

扫雷的核心是用一个二维数组存储游戏区。在开始游戏时随机生成雷区,然后根据鼠标点击触发事件,思路是比较简单清晰的。雷的标记可以利用button类的Tag属性区分,0代表自身非雷周围8格有雷,1代表雷,2代表自身非雷但周围有雷。

1、首先是界面的设计

初始界面:有两个按钮,每个按钮中有三个选项

“难度”按钮中的选项应该只有一个被选中

     private void ToolStripMenuItem1_CheckedChanged(object sender, EventArgs e){foreach (ToolStripMenuItem item in 难度ToolStripMenuItem1.DropDownItems){item.Checked = false;}ToolStripMenuItem checkItem = sender as ToolStripMenuItem;checkItem.Checked = true;}

开始游戏按钮是游戏的入口,需进行窗体大小的调整、提示信息刷新、雷区大小调整、雷区初始化、生成地雷。

        //游戏入口private void 开始游戏ToolStripMenuItem_Click(object sender, EventArgs e){//先清空显示及btn数组if (btns != null){foreach(ButtonWithPos btn in btns) Controls.Remove(btn);Array.Clear(btns, 0, WIDTH * HEIGHT);}//难度选择if (初级ToolStripMenuItem1.Checked){level = 1;mineNum = 10;WIDTH = HEIGHT = 9;}else if (中级ToolStripMenuItem1.Checked){level = 2;mineNum = 40;WIDTH = HEIGHT = 16;}else if (高级ToolStripMenuItem1.Checked){level = 3;mineNum = 99;WIDTH = 30;HEIGHT = 16;}else Application.Exit();//对象初始化mines = new Coord[mineNum];for (int i = 0; i < mineNum; i++) mines[i] = new Coord();btns = new ButtonWithPos[HEIGHT, WIDTH];visited = new bool[HEIGHT, WIDTH];BoardInit();//Reveal()函数DFS递归算法所需visited数组初始化for (int i = 0; i < HEIGHT; ++i){for (int j = 0; j < WIDTH; ++j){visited[i, j] = false;}}Generate();}

BoardInit函数用于窗口大小调整、提示信息刷新以及button数组(即雷区)的初始化:

     public void BoardInit(){int x0 = 20, y0 = 120;if (level == 1){Height = 500;Width = 375;}else if (level == 2){Height = 730;Width = 620;}else if (level == 3){Height = 730;Width = 1110;}else Application.Exit();lblMineSum.Left = x0;lblMineChecked.Left = x0;btnShow.Left = Width / 2 - 20;int  d = 35;Console.WriteLine(WIDTH + " " + HEIGHT);for (int i = 0; i < HEIGHT; ++i){for (int j = 0; j < WIDTH; ++j){ButtonWithPos button = new ButtonWithPos();button.Width = d;button.Height = d;button.Top = y0 + i * d;button.Left = x0 + j * d;button.BackgroundImage = imgNormal;button.BackgroundImageLayout = ImageLayout.Stretch;button.X = j;button.Y = i;button.Tag = 0;//Tag = 0,周围无雷;1,地雷;2,周围有雷;button.Visible = true;button.Enabled = true;button.MouseDown += Button_MouseDown;btns[i, j] = button;Controls.Add(button);}}btnShow.BackgroundImage = imgSmile;btnShow.BackgroundImageLayout = ImageLayout.Stretch;lblMineSum.Text = "地雷总数:" + mineNum.ToString();lblMineChecked.Text = "已标记地雷数:" + mineMarked.ToString();}

Generate函数用随机数来生成雷区

     void Generate(){Random random = new Random();bool flag;for (int i = 0; i < mineNum; ++i){int newX = random.Next(0, HEIGHT);int newY = random.Next(0, WIDTH);flag = true;while (true){flag = true;for (int j = 0; j < i; ++j){if (mines[j].X == newX && mines[j].Y == newY){flag = false;break;}}if (flag){mines[i].X = newX;mines[i].Y = newY;btns[newX, newY].Tag = 1;int left = newX - 1, right = newX + 1;int top = newY - 1, bottom = newY + 1;for (int k = left; k <= right; ++k){for (int l = top; l <= bottom; ++l){if (k >= 0 && k < HEIGHT && l >= 0 && l < WIDTH){if (k == newX && l == newY) continue;if ((int)btns[k, l].Tag != 1) btns[k, l].Tag = 2;}}}break;}else{newX = random.Next(0, HEIGHT);newY = random.Next(0, WIDTH);}}}}

2、鼠标点击处理

左键是翻开,右键是标记地雷。右键只需要进行显示的更新、标记地雷数的刷新以及检查是否胜利。左键要分翻开的类型。如果踩雷直接输掉,打开周围有雷的格子显示对应周围的雷数

        private void Button_MouseDown(object sender, MouseEventArgs e){ButtonWithPos button = sender as ButtonWithPos;if (e.Button == MouseButtons.Right){if (button.BackgroundImage != imgMarked){button.BackgroundImage = imgMarked;button.BackgroundImageLayout = ImageLayout.Stretch;++mineMarked;}else{button.BackgroundImage = imgNormal;--mineMarked;}lblMineChecked.Text = "已标记地雷数:" + mineMarked.ToString();bool win = CheckWin();if (win) Win();}else if (e.Button == MouseButtons.Left){int row = button.Y, col = button.X;Console.WriteLine("BUTTON DOWN: " + row + col);if ((int)button.Tag == 1){Lose(button);}else if ((int)button.Tag == 2){int mineAroundSum = CalcMineAround(row, col);MineAroundShow(button, mineAroundSum);}else if ((int)button.Tag == 0){button.BackgroundImage = imgNull;Reveal(row, col);}}}

打开周围无雷的格子要复杂一些。我们实际玩扫雷的时候有时候会一下翻开一片区域,这是因为当翻开了一个周围无雷的格子,程序会继续尝试翻周围的格子,直到翻开一个周围有雷的格子。这可以用DFS算法递归实现

        void Reveal(int row, int col){visited[row, col] = true;int mineAroundSum;int left = row - 1, right = row + 1;int top = col - 1, bottom = col + 1;if ((int)btns[row, col].Tag == 0) btns[row, col].BackgroundImage = imgNull;else if ((int)btns[row, col].Tag == 1) return;else if ((int)btns[row, col].Tag == 2){mineAroundSum = CalcMineAround(row, col);MineAroundShow(btns[row, col], mineAroundSum);return;}for (int i = left; i <= right; ++i){for (int j = top; j <= bottom; ++j){if (i >= 0 && i < HEIGHT && j >= 0 && j < WIDTH){if (!visited[i, j]){//Console.WriteLine("REVEAL: " + i + j);Reveal(i, j);}}}}}

一些判断胜利失败以及胜利失败的表示的函数

 void Lose(ButtonWithPos button){btnShow.BackgroundImage = imgLose;btnShow.BackgroundImageLayout = ImageLayout.Stretch;foreach (ButtonWithPos btn in btns){if ((int)btn.Tag == 1) btn.BackgroundImage = imgMineNotChosen;}button.BackgroundImage = imgMineChosen;MessageBox.Show("正中地雷!", "Oops");开始游戏ToolStripMenuItem.Enabled = true;}//检查是否胜利bool CheckWin(){bool flag = true;foreach (ButtonWithPos btn in btns){if ((int)btn.Tag == 1){if (btn.BackgroundImage != imgMarked){flag = false;break;}}}if (mineMarked != mineNum) flag = false;return flag;}//胜利表示void Win(){btnShow.BackgroundImage = imgVictory;btnShow.BackgroundImageLayout = ImageLayout.Stretch;MessageBox.Show("排雷成功!干得漂亮", "You Win!");}}

游戏截图

总结

总体来讲用C#编写一个小游戏的过程不算困难,最主要的设计的思路,这个扫雷小游戏就利用了一个随机数来生成地雷和翻格子的时候用DFS递归算法来实现,具体界面的设计在平时作业“编写一个游戏客户端”的时候已经学习到了,利用了C#窗体应用开发。

这次实验主要是了解了.NET框架

.NET的特点:

多平台:可用于开发 服务器程序,桌面程序,PDA,移动电话程序。

行业标准:支持多种通信协议,XML,HTTP,SOAP,WSDL

C#与C++和C都不同,它更面向对象

C#窗体应用开发运用在这次实验上

  • 理解事件驱动程序设计
  • 窗体属性、方法和事件
  • 基本控件的属性、方法和事件
  • 消息对话框的使用

这次实验学到了很多

C#编写一个扫雷游戏相关推荐

  1. 编写一个扫雷游戏,我们首先要清楚游戏规则

    编写一个扫雷游戏,我们首先要清楚游戏规则:         扫雷就是要把所有非地雷的格子揭开即胜利:踩到地雷格子就算失败.游戏主区域由很多个方格组成.使用鼠标左键随机点击一个方格,方格即被打开并显示出 ...

  2. python3扫雷代码_GitHub - pantaduce/minesweeper: Python代码编写的扫雷游戏

    Minesweeper(扫雷) 这是一个由Python编写的扫雷游戏,基于tkinter/Tkinter开发,支持python2和python3. 功能 概述 基本功能:左键扫雷,右键标记 记录游戏步 ...

  3. 用js制作一个扫雷游戏(vue版)

    使用js来制作一个扫雷游戏,可以分为以下几个步骤 1.根据不同难度构建扫雷游戏区域: 2.在游戏区域中放置地雷: 3.处理点击事件: 4.处理游戏结束事件 1.根据不同难度构建扫雷游戏区域 创建一个二 ...

  4. 用C语言编写一个小游戏

    这是一个比较通用的方法来编写一个小游戏用 C 语言: 首先,确定游戏的目标和规则.这可能包括游戏的玩法.胜负条件.游戏元素和游戏流程等. 其次,确定游戏的用户界面.这可能包括游戏的菜单.按钮.文本框. ...

  5. Java扫雷游戏项目-1小时编写出扫雷游戏

    <扫雷>是一款大众类的益智小游戏,想必有很多人都玩过这款小游戏,但是我们如何用代码编写出这款小游戏呢? 小编整理了[Java扫雷游戏项目]视频教程,只要90分钟就可以完成一个你自己亲手开发 ...

  6. Pygame:编写一个小游戏

    大学最后的考试终于结束了,迎来了暑假和大四的漫长的"自由"假期.当然要自己好好"玩玩"了. 我最近在学习Python,本意是在机器学习深度学习上使用Python ...

  7. 如何用python编一个扫雷游戏_用 Python 做一个 Windows 扫雷游戏

    原标题:用 Python 做一个 Windows 扫雷游戏 本文代码基于 python3.6 和 pygame1.9.4. Windows XP 上的扫雷是无数80/90后的集体回忆,今天我们就用 P ...

  8. python编写一个弹球游戏_Python实战案例:用Python写一个弹球游戏,就是这么强

    我们前面讲了几篇关于类的知识点,为了让大家更好的掌握类的概念,并灵活的运用这些知识,我写了一个有趣又好玩的弹球的游戏,一来可以把类的知识融会一下,二来加深对Python的兴趣.你会发现哎呀Python ...

  9. 用python3.7.3编写一个问答游戏

    我们先来看一下效果: 代码如下: import random,time #首先初始化 number1 = 0 number2 = 0 answer1 = 0 answer2 = 0 score = 0 ...

最新文章

  1. TypeScript 3.4.5 发布,修复节点运行问题
  2. windows pxe 安装linux,菜鸟学Linux 第103篇笔记 pxe自动化安装linux
  3. 预告 | CSIG图像图形学科前沿讲习班:图神经网络
  4. php用array_merge实现无限级分类
  5. Java单例模式优化写法
  6. Oracle 自己主动诊断资料档案库 (ADR)、自己主动诊断工作流、ADRCI工具
  7. 开源巨头 SUSE 收购 Rancher Labs,云原生时代来临
  8. 打包或者编译python程序
  9. 整理全网可视化大屏有关资料,学习大屏设计,大屏原型参考,大屏设计参考
  10. ip纯真 mysql_纯真ip导入mysql
  11. 【条码检测算法】不起眼的条码识别也能玩出这么多花样
  12. selenium实现模拟点击QQ一键登录
  13. linux修改文件名的三种方法
  14. react从零基础入门到项目实战视频教程
  15. 《中国综合算力指数》《中国算力白皮书》《中国存力白皮书》《中国运力白皮书》在首届算力大会上重磅发出
  16. R语言 自定义函数之趣味程序--老虎机
  17. 电商上行大势已定,店宝宝扶持新手开展网店创业
  18. 在自动UNDO管理情况下,如何手工增加undo段
  19. 星期、干支、二十八宿计算公式
  20. 大学计算机基础 小报,word制作电子小报教案.doc

热门文章

  1. [Swift5] Swift 设置自定义预编译宏
  2. 数据库基础操作和配置的整合集成-新手适用
  3. ARFoundation系列讲解 - 35 AR看车二
  4. 算法导论第三版第8章思考题
  5. 搜狗输入法输入汉字时候选栏乱码
  6. 【SCI征稿】中科院2区(TOP)录用后立即出版!
  7. Centos7安装WPS打开无反应
  8. python制作酷炫动画_Python+Kepler.gl轻松制作酷炫路径动画
  9. Web Print打印服务
  10. 用于Arduino、esp32或esp8266的Ebyte LoRa E32(SX1278)设备:省电和发送结构化数据 - 第五部分