#DAYU200体验官# 经典小游戏之扫雷[初版] 原创 精华

Tuer白晓明
发布于 2022-7-6 17:34
浏览
2收藏

目录

1992年4月6日,"扫雷"小游戏首次搭载在Windows3.1,至今正好30周年,如今被贴上了"暴露年龄"标签😂😂,本节实现"扫雷"小游戏并运行在DAYU200开发板上

环境

  • 开发板:DAYU200
  • 系统版本:OpenHarmony v3.2 Beta1
  • Sdk版本:ohos-sdk 3.2.2.5
  • 开发工具:DevEco Studio 3.0.0.901(For OpenHarmony)

实现过程

  1. 创建MineSweeping项目
  2. 修改index.ets页面代码,使用Stack容器、Image组件、Text组件构建开始游戏按钮。
Stack({alignContent: Alignment.Center}) {
  Image($r('app.media.start_game'))
    .width(240)
    .height(120)
  Text('开始游戏')
    .fontSize(18)
    .fontColor(Color.White)
    .fontWeight(FontWeight.Bold)
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  1. 点击"开始游戏"进行初始化棋盘、棋盘格埋雷、计算棋盘格周边雷数。
  • 初始化棋盘
    当前以4*4棋盘格为例,使用Grid网格容器,由"行"和"列"分割的单元格组成棋盘。定义棋盘格类Board如下:
class Board {
  x: number	// 棋盘格行标识
  y: number	// 棋盘格列标识
  content: string	// 周边雷数
  isCover: boolean	// 默认显示图片
  isMine: boolean	// 是否雷区
  isClick: boolean	// 是否点击

  constructor(x: number, y: number, content: string, isCover: boolean, isMine: boolean, isClick: boolean) {
    this.x = x;
    this.y = y;
    this.content = content;
    this.isCover = isCover;
    this.isMine = isMine;
    this.isClick = isClick;
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.

通过循环渲染ForEach方式,构建Grid网格容器中的单元格GridItem

Grid() {
  ForEach(this.boards, (item: Board) => {
    GridItem() {
      Stack({alignContent: Alignment.Center}) {
        Image(item.isCover ? $r('app.media.loading_icon') : (item.isMine ? $r('app.media.app_icon') : $r('app.media.click_bg')))
          .width((!item.isCover && item.isMine) ? 80 : '100%')
        Text(item.isClick ? ((item.content === '9' || item.content === '0') ? '' : item.content) : '')
          .fontSize(26).fontWeight(FontWeight.Bold)
      }
      .width('100%').height(100)
    }
  }, (item: Board) => (item.x + ',' + item.y).toString())
}
.width('95%')
.columnsTemplate(this.gridFr)
.columnsGap(0)
.rowsGap(0)
.height(500)
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 棋盘格埋雷
    使用随机方式,进行埋雷,代码如下:
// 埋雷
setMine = (rows: number, cols: number) => {
  // 当达到设定的数量时跳出
  if (this.mineCount >= this.maxMineNum) {
    return false;
  }
  // 随机获取坐标值
  let randomX = Math.floor(Math.random() * rows);
  let randomY = Math.floor(Math.random() * cols);
  // 埋雷
  this.boards.forEach(item => {
    if (item.x === randomX && item.y === randomY) {
      if (!item.isMine) {
        item.isMine = true;
        this.mineCount++;
      }
    }
  })
  this.setMine(rows, cols);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 计算棋盘格周边雷数
    周边雷数的计算,使用9宫格的方式,以中间方格为基准,周边存在雷的方格数量累加在一起即为当前基准格的周边雷数。同时在计算时不能超出给定的行数和列数。
    #DAYU200体验官# 经典小游戏之扫雷[初版]-鸿蒙开发者社区
// 统计周边雷数
boardAreaMine = (rows: number, cols: number) => {
  // 判断周边雷,并计数
  let boards = this.boards;
  for (let i = 0; i < boards.length; i++) {
    let cell = boards[i];
    if (cell.isMine) {
      continue;
    }
    let count = 0;
    // 左上
    let leftTopCellX = cell.x - 1, leftTopCellY = cell.y - 1;
    if (leftTopCellX >= 0 && leftTopCellY >= 0 && leftTopCellX < rows && leftTopCellY < cols) {
      boards.filter(item => {
        if (item.x === leftTopCellX && item.y === leftTopCellY && item.isMine) {
          count++;
        }
      })
    }
    // 上
    let topCellX = cell.x - 1, topCellY = cell.y;
    if (topCellX >= 0 && topCellY >= 0 && topCellX < rows && topCellY < cols) {
      boards.filter(item => {
        if (item.x === topCellX && item.y === topCellY && item.isMine) {
          count++;
        }
      })
    }
    // 右上
    let rightTopCellX = cell.x - 1, rightTopCellY = cell.y + 1;
    if (rightTopCellX >= 0 && rightTopCellY >= 0 && rightTopCellX < rows && rightTopCellY < cols) {
      boards.filter(item => {
        if (item.x === rightTopCellX && item.y === rightTopCellY && item.isMine) {
          count++;
        }
      })
    }
    // 右
    let rightCellX = cell.x, rightCellY = cell.y + 1;
    if (rightCellX >= 0 && rightCellY >= 0 && rightCellX < rows && rightCellY < cols) {
      boards.filter(item => {
        if (item.x === rightCellX && item.y === rightCellY && item.isMine) {
          count++;
        }
      })
    }
    // 右下
    let rightBottomCellX = cell.x + 1, rightBottomCellY = cell.y + 1;
    if (rightBottomCellX >= 0 && rightBottomCellY >= 0 && rightBottomCellX < rows && rightBottomCellY < cols) {
      boards.filter(item => {
        if (item.x === rightBottomCellX && item.y === rightBottomCellY && item.isMine) {
          count++;
        }
      })
    }
    // 下
    let bottomCellX = cell.x + 1, bottomCellY = cell.y;
    if (bottomCellX >= 0 && bottomCellY >= 0 && bottomCellX < rows && bottomCellY < cols) {
      boards.filter(item => {
        if (item.x === bottomCellX && item.y === bottomCellY && item.isMine) {
          count++;
        }
      })
    }
    // 左下
    let leftBottomCellX = cell.x + 1, leftBottomCellY = cell.y - 1;
    if (leftBottomCellX >= 0 && leftBottomCellY >= 0 && leftBottomCellX < rows && leftBottomCellY < cols) {
      boards.filter(item => {
        if (item.x === leftBottomCellX && item.y === leftBottomCellY && item.isMine) {
          count++;
        }
      })
    }
    // 左
    let leftCellX = cell.x, leftCellY = cell.y - 1;
    if (leftCellX >= 0 && leftCellY >= 0 && leftCellX < rows && leftCellY < cols) {
      boards.filter(item => {
        if (item.x === leftCellX && item.y === leftCellY && item.isMine) {
          count++;
        }
      })
    }
    if (count === 0) {
      count = 9;
    }
    cell.content = count.toString();
  }
  this.boards = boards;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  1. 给"开始游戏"按钮添加点击效果。
Stack({alignContent: Alignment.Center}) {
}
.onClick(() => {
   // 此处编写逻辑代码
   this.init();
})

// 初始化棋盘,埋雷,计算棋盘格周边雷数初始化方法
init = () => {
  this.initBoard(this.boardRowsNum, this.boardColsNum);
  this.setMine(this.boardRowsNum, this.boardColsNum);
  this.boardAreaMine(this.boardRowsNum, this.boardColsNum);
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  1. 点击棋盘格处理方式
// 需要引入prompt
import prompt from '@ohos.prompt';

GridItem() {...}
.onClick(() => {
  if ((this.clickCount - 1) === this.maxMineNum) {
    prompt.showToast({
      message: '恭喜你,成功排雷!',
      duration: 2000
    })
    this.boards = [];
    return false;
  }
  let tempBoards = this.boards;
  this.boards = new Array<Board>();
  tempBoards.forEach(temp => {
    if (temp.x === item.x && temp.y === item.y) {
      temp.isClick = true;
      temp.isCover = false
      if (temp.isMine) {
        AlertDialog.show({
          message: '您踩雷了,游戏结束~',
          autoCancel: false,
          primaryButton: {
            value: '重新开始',
            action: () => {
              this.init();
            }
          },
          secondaryButton: {
            value: '不玩了~',
            action: () => {
              this.boards = [];
            }
          },
          alignment: DialogAlignment.Center
        })
      } else {
        this.clickCount--;
      }
    }
  })
  this.boards = tempBoards;
})
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.

预览效果

#DAYU200体验官# 经典小游戏之扫雷[初版]-鸿蒙开发者社区

说明

本项目已提交至开源仓:仓库地址

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
经典小游戏扫雷源码.rar 3.3M 106次下载
已于2022-7-6 17:39:41修改
6
收藏 2
回复
举报
6
2
2
2条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

非常经典的游戏,不过4*4扫雷会不会过于简单了。

回复
2022-7-6 18:14:40
Tuer白晓明
Tuer白晓明 回复了 红叶亦知秋
非常经典的游戏,不过4*4扫雷会不会过于简单了。

可以在源码里面改,可以尝试6*6...10*10...😊😊😊😊

回复
2022-7-6 18:24:01


回复
    相关推荐