iis服务器助手广告
返回顶部
首页 > 资讯 > 移动开发 >Android Flutter实现在多端运行的扫雷游戏
  • 540
分享到

Android Flutter实现在多端运行的扫雷游戏

摘要

目录前言效果图开始实现第一步:定义游戏设置第二步:定义游戏参数第三步:编写扫雷初始化游戏逻辑第四步:编写用户交互游戏逻辑第五步:封装格子第六步:游戏布局优化-第七步:游戏时间前言 当

前言

当我们回忆起小时候的经典电脑游戏,扫雷一定是其中之一。这个简单而富有挑战的游戏不仅考验我们的智力和耐性,而且在完成后还会让我们感到一种无与伦比的成就感。现在,您可以使用Flutter来重新体验这个经典游戏,无论您是Flutter新手还是老手,都能通过本文,让您在Flutter的世界中开发出一个令人满意的扫雷游戏。

代码仓库:https://GitHub.com/taxze6/flutter_game_collection/tree/main/mine_sweeping

注:本文demo未使用任何第三方插件,Flutter版本3.7.3

效果图

话不多说,先上效果图。(包含不同端、不同难度、不同游戏主题)

windows

网页端

Android

开始实现

第一步:定义游戏设置

定义GameSetting单例类,确保扫雷程序中只有一个实例,并且该实例可以被全局访问,主要用于共享资源。

class GameSetting {
  GameSetting._();
}

然后定义一个私有的、静态的、不可变的 _default 对象,它是 GameSetting 类的默认实例,该实例在第一次使用时被创建。再定义一个 GameSetting 工厂构造函数,它通过返回 _default 对象实现了单例模式的实例化,该工厂构造函数是唯一可以实例化 GameSetting 对象的方法。

static final GameSetting _default = GameSetting._();
factory GameSetting() => _default;

完成了单例类的基本定义,现在再来定义与扫雷相关的,先定义游戏的难度。在扫雷中游戏的难度主要有两部分组成:

棋盘格子的数量

///游戏的难度,默认为8*8
int difficulty = 8;

雷的数量

///雷的数量 (格子总数 * 0.18 向下取整),通常扫雷的雷数在0.16-0.2之间。
int get mines => (difficulty * difficulty * 0.18).floor();

最后在定义一些游戏的颜色主题:

List<Color> c_5ADFD0 = [
  Color(0xFF299794),
  Color(0xFF2EC4C0),
  Color(0xFF2EC4C0)
];

List<Color> c_A0BBFF = [
  Color(0xFF5067C5),
  Color(0xFF838CFF),
  Color(0xFFA0BBFF),
];

///默认主题
Color themeColor = Color(0xFF5ADFD0);

第二步:定义游戏参数

在进行扫雷游戏的时候,需要记录棋盘格子上每个格子的参数,记录格子是否被标记为雷、是否被翻开。也需要记录游戏是否获胜、是否踩到了地雷。

late List<List<int>> board; // 棋盘
late List<List<bool>> revealed; // 记录格子是否被翻开
late List<List<bool>> flagged; // 记录格子是否被标记
late bool gameOver; // 游戏是否结束
late bool win; // 是否获胜

其他初始化参数:

late int numRows; // 行数
late int numCols; // 列数
late int numMines; // 雷数

//游戏时间
late int _playTime;

第三步:编写扫雷初始化游戏逻辑

定义了游戏的参数后,在游戏开始时,需要对其进行赋值。

numRows = gameSetting.difficulty;
numCols = gameSetting.difficulty;
numMines = gameSetting.mines;
// 初始化棋盘
board = List.generate(numRows, (_) => List.filled(numCols, 0));
// 初始化格子是否被翻开
revealed = List.generate(numRows, (_) => List.filled(numCols, false));
// 初始化格子是否被标记
flagged = List.generate(numRows, (_) => List.filled(numCols, false));
// 将游戏定义为未结束
gameOver = false;
// 将游戏定义为还未获胜
win = false;

通过while循环在棋盘上随机放置地雷,直到放置的地雷数量达到预定的 numMines

int numMinesPlaced = 0;
while (numMinesPlaced < numMines) {
	...
}

使用 Random().nextInt 方法生成两个随机数 i 和 j,分别用于表示棋盘中的行和列。

int i = Random().nextInt(numRows);
int j = Random().nextInt(numCols);

通过 board[i][j] != -1 的判断语句,检查这个位置是否已经放置了地雷。如果没有则将 board[i][j] 的值设置为 -1,表示在这个位置放置了地雷,并将numMinesPlaced 的值加 1。

if (board[i][j] != -1) {
  board[i][j] = -1;
  numMinesPlaced++;
}

放完了地雷,那么就到了扫雷的核心逻辑,计算每个非地雷格子周围的地雷数量,然后将计算得到的地雷数量保存在对应的格子上。具体实现的逻辑为:通过两个嵌套的 for 循环遍历整个棋盘,内层的两个嵌套循环会计算这个格子周围的所有格子中地雷的数量,并将这个数量保存在 count 变量中。

for (int i = 0; i < numRows; i++) {
  for (int j = 0; j < numCols; j++) {
    ...
  }
}

循环中具体的逻辑是:在每个单元格上,如果它不是地雷(值不为为-1)则内部嵌套两个循环遍历当前单元格周围的所有单元格,计算地雷数量并存储在当前单元格中。

if (board[i][j] != -1) {
  int count = 0;
  for (int i2 = max(0, i - 1); i2 <= min(numRows - 1, i + 1); i2++) {
    for (int j2 = max(0, j - 1);
        j2 <= min(numCols - 1, j + 1);
        j2++) {
      if (board[i2][j2] == -1) {
        count++;
      }
    }
  }
  board[i][j] = count;
}

第四步:编写用户交互游戏逻辑

只要用户点击了,就要将格子设置为翻开了。

void reveal(int i, int j) {
	revealed[i][j] = true;
}

当用户点击了一个格子后,我们需要判断以下几点:

如果翻开的是地雷

if (board[i][j] == -1) {
  //将所有的地雷翻开,告诉用户所有的地雷位置
  for (int i2 = 0; i2 < numRows; i2++) {
    for (int j2 = 0; j2 < numCols; j2++) {
      if (board[i2][j2] == -1) {
        revealed[i2][j2] = true;
      }
    }
  }
  //游戏结束
  gameOver = true;
	//结束动画
	...
}

如果点击的格子周围都没有雷就自动翻开相邻的空格

if (board[i][j] == 0) {
  for (int i2 = max(0, i - 1); i2 <= min(numRows - 1, i + 1); i2++) {
    for (int j2 = max(0, j - 1); j2 <= min(numCols - 1, j + 1); j2++) {
      if (!revealed[i2][j2]) {
        reveal(i2, j2);
      }
    }
  }
}

检查是否胜利

///它会遍历整个棋盘,检查每一个未被翻开的格子是否都是地雷,
bool checkWin() {
  for (int i = 0; i < numRows; i++) {
    for (int j = 0; j < numCols; j++) {
      if (board[i][j] != -1 && !revealed[i][j]) {
        return false;
      }
    }
  }
  return true;
}


if (checkWin()) {
  win = true;
  gameOver = true;
  _timer?.cancel();
  //获胜动画
  ...
}

第五步:封装格子

定义枚举类BlockType,用于判断不同的状态下显示不同的格子样式。

enum BlockType {
  //数字
  figure,
  //雷
  mine,
  //标记
  label,
  //未标记(未被翻开)
  unlabeled,
}

封装格子的代码其实很简单,根据不同的状态封装即可,这里就不过多展示了。

第六步:游戏布局

此处只分析游戏棋盘的布局。

通过GridView.builder构建棋盘,使用SliverGridDelegateWithFixedCrossAxisCount实现每一行具有相同数量的列。

GridView.builder(
  gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
    crossAxisCount: numCols,
    childAspectRatio: 1.0,
  ),
  itemBuilder: (BuildContext context, int index) {
  	...
  }
)

通过对index的整除和取模,得到行和列,然后根据每个格子的当前状态对封装好的格子布局传入不同的参数。

itemBuilder: (BuildContext context, int index) {
  int i = index ~/ numCols;
  int j = index % numCols;
  BlockType blockType;	
//格子被翻开
 if (revealed[i][j]) {
   //是地雷
   if (board[i][j] == -1) {
     blockType = BlockType.mine;
   } else {
     blockType = BlockType.figure;
   }
 } else {
   //被用户标记
   if (flagged[i][j]) {
     blockType = BlockType.label;
   } else {
     blockType = BlockType.unlabeled;
   }
 }
  return GestureDetector(
    onTap: () => reveal(i, j),
    onDoubleTap: () => toggleFlag(i, j),
    child: BlockContainer(
      backColor: gameSetting.themeColor,
      value: revealed[i][j] && board[i][j] != 0 ? board[i][j] : 0,
      blockType: blockType,
    ),
  );
},

其中,如果双击格子代表标记或取消标记,定义了一个方法toggleFlag

///标记雷
void toggleFlag(int i, int j) {
  if (!gameOver) {
    setState(() {
      flagged[i][j] = !flagged[i][j];
    });
  }
}

到这里,就完成了对扫雷这款游戏的实现。更改游戏的主题状态或游戏难度,只需更改不同的初始化参数即可。

优化-第七步:游戏时间

有一个计时器,会大大提高用户玩算法类、解谜类这样游戏的乐趣,例如魔方。在Flutter中通过Timer.periodic去实现计时器是很简答的,就不过多讲述了,主要看下如何格式化为时钟的形式:

String get playTime {
  int minutes = (_playTime ~/ 60); // 计算分钟数
  int seconds = (_playTime % 60); // 计算秒数
  //padLeft方法用于补齐不足两位的数字,第一个参数是补齐后的字符串总长度,第二个参数是用于补齐的字符。
  return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
}

以上就是Android Flutter实现在多端运行的扫雷游戏的详细内容,更多关于Android Flutter扫雷游戏的资料请关注编程网其它相关文章!

--结束END--

本文标题: Android Flutter实现在多端运行的扫雷游戏

本文链接: https://www.lsjlt.com/news/199551.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android Flutter实现在多端运行的扫雷游戏
    目录前言效果图开始实现第一步:定义游戏设置第二步:定义游戏参数第三步:编写扫雷初始化游戏逻辑第四步:编写用户交互游戏逻辑第五步:封装格子第六步:游戏布局优化-第七步:游戏时间前言 当...
    99+
    2023-03-13
    Android Flutter实现扫雷游戏 Android 扫雷 Flutter 扫雷 Flutter 游戏
  • Android Flutter如何实现在多端运行的扫雷游戏
    这篇文章主要介绍“Android Flutter如何实现在多端运行的扫雷游戏”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android Flutter如何实现在多端运行的扫雷游...
    99+
    2023-07-05
  • 100行C#代码实现经典扫雷游戏
    目录布局生成雷区左键扫雷和右键标记翻面功能布局 布局效果如下,下面每个“网格”都是一个按钮,点击按钮,就会有相应的事件发生。 由于UniformGrid中每...
    99+
    2023-02-27
    C#实现扫雷游戏 C#扫雷游戏 C#扫雷 C#游戏
  • java实现简单的扫雷小游戏
    使用java制作一款简单的扫雷游戏,供大家参考,具体内容如下 import java.util.*; public class nephelokokkygia { ...
    99+
    2024-04-02
  • C语言二维数组运用实现扫雷游戏
    作为80后、90后的老年人,想必对扫雷游戏都不陌生。扫雷,是微软在win8版本之前系统自带的一款游戏——现在已经被下架了,童年的回忆,很难受。游戏操作很简单,...
    99+
    2024-04-02
  • C++基于CMD命令行实现扫雷小游戏
    本文实例为大家分享了C++基于CMD命令行实现扫雷小游戏的具体代码,供大家参考,具体内容如下 这个小游戏是笔者在大一C语言课程设计的时候写的,基于命令行,为了显得漂亮一些,特别加上了...
    99+
    2024-04-02
  • C语言扫雷游戏的简单实现
    今天来用c语言做一个扫雷功能的简单实现,首先创建一个test.c来用于在写代码的途中测试扫雷代码,game.h来存放实现扫雷函数需要用到的头文件,game.c来存放最终的成品。 首先...
    99+
    2024-04-02
  • Java实现扫雷游戏的代码分享
    目录效果展示主类:GameWin类底层地图MapBottom类顶层地图MapTop类底层数字BottomNum类初始化地雷BottomRay类工具GameUtil类总结效果展示 主...
    99+
    2024-04-02
  • C语言扫雷游戏的实现方法
    本文实例为大家分享了C语言扫雷游戏的实现代码,供大家参考,具体内容如下 实现扫雷 1、创建俩12*12的字符数组,一个用作放雷,一个呈现给用户 2、利用随机数往防雷数组中产生雷 3、...
    99+
    2024-04-02
  • C语言实现扫雷游戏的方法
    相信大家对扫雷一定都不陌生吧!但是你敢信仅仅使用一些C语言的初阶基础知识就能够制作一个扫雷简单小游戏?今天,我将带领大家一起走进扫雷,探究其基础算法奥秘。 一、基本思路 首先,既然是...
    99+
    2024-04-02
  • C语言实现简易的扫雷游戏
    本文实例为大家分享了C语言实现简易的扫雷游戏的具体代码,供大家参考,具体内容如下 在正式讲内容之前先说一说扫雷游戏的规则 游戏规则很简单,点击方格,如果是地雷,游戏失败,找到所有地...
    99+
    2024-04-02
  • C语言实现简易的扫雷小游戏
    这是一个用C语言实现的控制台扫雷小游戏,实现了随机布置炸弹、扫描炸弹、标记炸弹、百分百第一次不被炸死等功能。 编译器:vs2015 功能模块图 源代码 #include<st...
    99+
    2024-04-02
  • 基于C语言实现简单的扫雷游戏
    目录效果展示开始的界面选择标记地雷或者选择踩坐标在输入坐标处输入0 0结束游戏踩到炸弹,出现炸弹位置胜利代码test.cgame.hgame扫雷.c效果展示 开始的界面 输入0结束...
    99+
    2024-04-02
  • C语言实现一个简单的扫雷游戏
    前言 扫雷跟上一篇文章的三子棋一样,是C语言基础知识的综合运用的实例,对于巩固我们的基础知识非常重要,同时扫雷作为C语言的一个小项目,锻炼我们的编程思维,也是一个不可多得的实践。 提...
    99+
    2024-04-02
  • 怎么在python中使用tkinter实现一个扫雷游戏
    怎么在python中使用tkinter实现一个扫雷游戏?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。实现代码# 导入所需库from tkin...
    99+
    2023-06-15
  • 基于C语言实现简易的扫雷游戏
    对于C语言学习者来说,在完成C语言初级学习之后,扫雷游戏是一个很好的知识的总结和练习。 扫雷即在一个棋盘中,随机放入一定数量的雷,玩家通过输入坐标,得到坐标上的信息(以此点为中心四周...
    99+
    2024-04-02
  • C++ 情怀游戏扫雷的实现流程详解
    扫雷最原始的版本可以追溯到1973年一款名为“方块”的游戏。 不久,“方块”被改写成了游戏“Rlogic”。在“Rlogic”里,玩家的任务是作为美国海军陆战队队员,为指挥中心探出一...
    99+
    2024-04-02
  • JAVA实现经典扫雷游戏的示例代码
    目录前言主要设计功能截图代码实现总结前言 windows自带的游戏《扫雷》是陪伴了无数人的经典游戏,本程序参考《扫雷》的规则进行了简化,用java语言实现,采用了swing技术进行了...
    99+
    2024-04-02
  • 怎么在java中使用swing实现一个扫雷游戏
    这篇文章给大家介绍怎么在java中使用swing实现一个扫雷游戏,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。版本1:package awtDemo;import java.awt.event.Ac...
    99+
    2023-05-30
    java swing
  • C语言实现扫雷游戏的示例分析
    这篇文章给大家分享的是有关C语言实现扫雷游戏的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一,创建菜单先明确要做什么,选择合适的语句来对想法进行实现:test.c   vo...
    99+
    2023-06-29
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作