八、随机布雷

/// <summary>
/// 随机布地雷
/// </summary>
/// <param name="mineNum">地雷数</param>
private void SetRndMine(int mineNum)
{
for (int k = ; k < mineNum; k++)
{
int nullnum = ; for (int j = ; j < _gameLevel._colGrid; j++)
{
for (int i = ; i < _gameLevel._rowGrid; i++)
{
if (_backData[j, i] == (int)BackState.BLANK)
nullnum++;
}
} if (nullnum < )
return; int index = rnd.Next(, nullnum);
nullnum = ;
for (int j = ; j < _gameLevel._colGrid; j++)
{
for (int i = ; i < _gameLevel._rowGrid; i++)
{
if (_backData[j, i] == )
{
nullnum++;
if (nullnum != index)
continue; _backData[j, i] = (int)BackState.MINE; // 设置为地雷
}
}
}
}
}
这个方法是不是很熟悉,我们在2048游戏中用到过,这里就不再多说了。

九、设置地雷旁边的格子标注的地雷数值
原理就是读取地雷位置,然后分别给不是地雷的格子数值+1。
/// <summary>
/// 设置地雷周围格子雷数
/// </summary>
private void SetCellMineNumber()
{
for (int y = ; y < _gameLevel._colGrid; y++)
{
for (int x = ; x < _gameLevel._rowGrid; x++)
{
if (_backData[y, x] == (int)BackState.MINE) // 遇到地雷则周围8格分别+1
{
if (x - > - && y - > - && _backData[y - , x - ] != (int)BackState.MINE)
_backData[y - , x - ]++; if (y - > - && _backData[y - , x] != (int)BackState.MINE)
_backData[y - , x]++; if (y - > - && x + < _gameLevel._rowGrid && _backData[y - , x + ] != (int)BackState.MINE)
_backData[y - , x + ]++; if (x - > - && _backData[y, x - ] != (int)BackState.MINE)
_backData[y, x - ]++; if (x + < _gameLevel._rowGrid && _backData[y, x + ] != (int)BackState.MINE)
_backData[y, x + ]++; if (y + < _gameLevel._colGrid && x - > - && _backData[y + , x - ] != (int)BackState.MINE)
_backData[y + , x - ]++; if (y + < _gameLevel._colGrid && _backData[y + , x] != (int)BackState.MINE)
_backData[y + , x]++; if (y + < _gameLevel._colGrid && x + < _gameLevel._rowGrid && _backData[y + , x + ] != (int)BackState.MINE)
_backData[y + , x + ]++;
}
}
}
}

十、设置背景区图片组

循环读取背景区数据,根据数值设置对应的图片源。

private void SetBackCellImage()
{
BackCanvas.Children.Clear(); for (int y=; y<_gameLevel._colGrid; y++)
{
for (int x=; x<_gameLevel._rowGrid; x++)
{
_backImage[y, x] = new Image();
if (_backData[y, x] == (int)BackState.BLANK)
{
_backImage[y, x].Source = ImageHelper.CutImage(_bmpSpace, new Int32Rect(, , _cellSize.Width, _cellSize.Height));
}
else if (_backData[y, x] == (int)BackState.MINE)
{
_backImage[y, x].Source = ImageHelper.CutImage(_bmpMine, new Int32Rect(, , _cellSize.Width, _cellSize.Height));
}
else
{
for (int i = ; i < ; i++)
{
if (_backData[y, x] == (i+))
{
_backImage[y, x].Source = ImageHelper.CutImage(
_bmpNum1_8, new Int32Rect(i * _cellSize.Width, , _cellSize.Width, _cellSize.Height));
break;
}
}
} _backImage[y, x].SetValue(Canvas.LeftProperty, x * (double)_cellSize.Width);
_backImage[y, x].SetValue(Canvas.TopProperty, y * (double)_cellSize.Height);
BackCanvas.Children.Add(_backImage[y, x]);
}
}
}

十一、开始游戏准备

根据游戏级别分别调用随机布雷、设置雷边数值方法,同时添加背景图片数组到游戏背景区。

private void ResetGame()
{
InitialGameState();
InitGameData(_level);
textBlockMineNum.Text = _gameLevel._mineNum.ToString(); SetRndMine(_gameLevel._mineNum);
SetCellMineNumber();
SetBackCellImage();
}

将该方法添加到开始游戏菜单中,并计时器打开。

private void MenuGameStart_Click(object sender, RoutedEventArgs e)
{
ResetGame();
_gameState = GameState.START; // 开始计时
_stopWatchGame.Start();
_timerSetTimeText.Start();
}

重复点击开始菜单,看看效果。

十二、调整游戏级别

根据菜单设置的当前级别值设置菜单选择状态。

/// <summary>
/// 设置级别菜单状态
/// </summary>
/// <param name="level"></param>
private void SetMenuLevelState(Level level)
{
switch (level)
{
case Level.SIMPLE:
MenuLowLevel.IsChecked = true;
MenuMiddleLevel.IsChecked = false;
MenuHighLevel.IsChecked = false;
break;
case Level.NORMAL:
MenuLowLevel.IsChecked = false;
MenuMiddleLevel.IsChecked = true;
MenuHighLevel.IsChecked = false;
break;
case Level.HARD:
MenuLowLevel.IsChecked = false;
MenuMiddleLevel.IsChecked = false;
MenuHighLevel.IsChecked = true;
break;
}
}
/// <summary>
/// 初级级别菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuLowLevel_Click(object sender, RoutedEventArgs e)
{
if (_level == Level.SIMPLE)
return; if (MessageBox.Show("将用新难度级别重置游戏,确认要继续吗?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Asterisk)
== MessageBoxResult.Yes)
{
_level = Level.SIMPLE;
SetMenuLevelState(_level); ResetGame();
}
} /// <summary>
/// 中级级别菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuMiddleLevel_Click(object sender, RoutedEventArgs e)
{
if (_level == Level.NORMAL)
return; if (MessageBox.Show("将用新难度级别重置游戏,确认要继续吗?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Asterisk)
== MessageBoxResult.Yes)
{
_level = Level.NORMAL;
SetMenuLevelState(_level);
ResetGame();
}
} /// <summary>
/// 高级级别菜单
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void MenuHighLevel_Click(object sender, RoutedEventArgs e)
{
if (_level == Level.HARD)
return; if (MessageBox.Show("将用新难度级别重置游戏,确认要继续吗?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Asterisk)
== MessageBoxResult.Yes)
{
_level = Level.HARD;
SetMenuLevelState(_level);
ResetGame();
}
}

十三、设置前景区图片组

/// <summary>
/// 设置前景图片数组
/// </summary>
private void SetForeCellImages()
{
ForeCanvas.Children.Clear(); for (int y = ; y < _gameLevel._colGrid; y++)
{
for (int x = ; x < _gameLevel._rowGrid; x++)
{
if (_foreData[y, x] > (int)ForeState.NONE)
{
_foreImage[y, x] = new Image();
_foreImage[y, x].Source = ImageHelper.CutImage(_bmpForeground, new Int32Rect(, , _cellSize.Width, _cellSize.Height)); _foreImage[y, x].SetValue(Canvas.LeftProperty, x * (double)_cellSize.Width);
_foreImage[y, x].SetValue(Canvas.TopProperty, y * (double)_cellSize.Height);
ForeCanvas.Children.Add(_foreImage[y, x]);
}
}
}
}

在ResetGame()方法最后位置加入对该方法的调用。
 运行程序,看看效果。

练手WPF(三)——扫雷小游戏的简易实现(中)的更多相关文章

  1. WEBGL学习笔记(七):实践练手1-飞行类小游戏之游戏控制

    接上一节,游戏控制首先要解决的就是碰撞检测了 这里用到了学习笔记(三)射线检测的内容了 以鸟为射线原点,向前.上.下分别发射3个射线,射线的长度较短大概为10~30. 根据上一节场景的建设,我把y轴设 ...

  2. 练手WPF(三)——扫雷小游戏的简易实现(上)

    一.创建项目1.创建WPF项目,设置初始化窗口大小(初级难度):高x宽为430x350.2.添加文件夹Images,并添加相关图片. 3.xaml中引入图片资源. <Window.Resourc ...

  3. 练手WPF(三)——扫雷小游戏的简易实现(下)

    十四.响应鼠标点击事件    (1)设置对应坐标位置为相应的前景状态 /// <summary> /// 设置单元格图样 /// </summary> /// <para ...

  4. Angular4 扫雷小游戏

    扫雷小游戏,可以升级过关,难度随关卡增加.但是有很明显的bug,以后有时间会继续优化! HTML: <div class="mainContent"> <div ...

  5. 扫雷小游戏PyQt5开发【附源代码】

    也没啥可介绍哒,扫雷大家都玩过. 雷的分布算法也很简单,就是在雷地图(map:二维数组)中,随机放雷,然后这个雷的8个方位(上下左右.四个对角)的数字(非雷的标记.加一后不为雷的标记)都加一. 如何判 ...

  6. 练手WPF(二)——2048游戏的简易实现(上)

    1.创建游戏界面编辑MainWindow.xaml,修改代码如下: <Window.Resources> <Style TargetType="Label"> ...

  7. web版扫雷小游戏(一)

    作为一名程序猿,平时的爱好也不多,说起游戏,我不太喜欢大型的网游,因为太耗时间,偶尔玩玩经典的单机小游戏,比如windows下自带的游戏扫雷(秀一下,高级下最高纪录110s). 现阶段正在致力于web ...

  8. 练手WPF(一)——模拟时钟与数字时钟的制作(上)

    一.Visual Studio创建一个WPF项目. 简单调整一下MainWindow.xaml文件.主要使用了两个Canvas控件,分别用于显示模拟和数字时钟,命名为AnalogCanvas.digi ...

  9. C++扫雷小游戏(基于CMD命令行)

    这个小游戏是笔者在大一C语言课程设计的时候写的,基于命令行,为了显得漂亮一些,特别加上了彩色特效~~~ 注意:Win10系统须将命令行调为旧版命令行,否则有可能会显示乱码! 代码示例: #includ ...

随机推荐

  1. Razor 页面解说

    自己开始从头深造- 本是想将时间缩短,但发现自己还是很难呀.希望你理解吧,这里的知识 是 页面的基本信息.也页面的跳转关系和 Tag的帮助标签. Section   PartView.  @page ...

  2. Implement Dependent Reference Properties实现依赖引用属性 (EF)

    In this lesson, you will learn how to implement properties whose values can depend on other properti ...

  3. JavaEE之Hibernate(开放源代码的对象关系映射框架)

    Hibernate(开放源代码的对象关系映射框架) 1.简介 Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全 ...

  4. PHP-RPM 安装指南(亲测有用)

      小注:此教程可能有很多弯路,但是最终是肯定安装成功了的,一个问题就是刚开始安装编译的指令版本好像不对,但是后面纠正过来了,但是此教程一共遇到了 十多个问题,也一并解决了,具有一定的借鉴意义,还有( ...

  5. 记录console的使用

    一般信息:console.info("这是info") 除错信息:console.debug() 警告提示:console.warn() 错误提示:console.error() ...

  6. python从入门到放弃之协程

    协程 协程,又称微线程,纤程.英文名Coroutine. 协程的概念很早就提出来了,但直到最近几年才在某些语言(如Lua)中得到广泛应用. 子程序,或者称为函数,在所有语言中都是层级调用,比如A调用B ...

  7. oracle数据库不小心删除了数据

    1.select * from SYS_DICT as of timestamp to_timestamp('2019-11-05 10:00:00','yyyy-mm-dd hh24:mi:ss') ...

  8. postman---postman参数关联

    我们做接口测试的时候都会遇到一个场景,就是参数关联,所谓的参数关联就是上一个参数的返回值用于下一个参数的请求中,通过python中requests我们知道如何请求,那么通过postman如何请求? 参 ...

  9. appium----Monkey测试

    做过app测试的应该都知道Monkey测试,今天简单的介绍下Monkey如何测试 什么是Monkey monkey测试的原理就是利用socket通讯的方式来模拟用户的按键输入,触摸屏输入,手势输入等, ...

  10. nginx典型官方模块解释

    模块名称 作用 语法 默认 配置位置 配置举例 结果验证 备注 1 --with-http_stub_status_module 监控Nginx的服务器连接状态 stub_status   serve ...