8浏览
查看: 8|回复: 4

[项目] 【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏

[复制链接]
【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图1

Kitronik ARCADE 是一款由英国教育科技公司 Kitronik 精心打造的可编程游戏机开发板,专为编程教学与创客实践而设计。该设备原生支持微软的 MakeCode Arcade 平台,用户可通过图形化或 JavaScript 编程方式,轻松创建、下载并运行复古风格的街机游戏。

它集成了彩色 LCD 显示屏、方向控制键、功能按键、蜂鸣器和震动马达等交互组件,提供完整的游戏输入输出体验。无论是初学者进行编程启蒙,还是创客群体开发交互式作品,Kitronik ARCADE 都能作为理想的硬件载体,助力创意实现。

凭借其开源友好、易于上手、兼容性强等特点,该开发板广泛应用于中小学编程课程、创客工作坊、游戏开发教学以及个人项目原型设计,深受教育者与技术爱好者的喜爱。


【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图2

驴友花雕  中级技神
 楼主|

发表于 1 小时前

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏

作为学习、练习与尝试,这里创建一个扫地雷的小游戏。
打开网页版:https://arcade.makecode.com/,设置项目名称:扫地雷

MicroPython实验代码

  1. @namespace
  2. class SpriteKind:
  3.     Collison = SpriteKind.create()
  4.     Tile = SpriteKind.create()
  5.     secret = SpriteKind.create()
  6. def on_overlap_tile(sprite, location):
  7.     sprite.destroy()
  8. scene.on_overlap_tile(SpriteKind.Tile,
  9.     assets.tile("""
  10.         tile16
  11.         """),
  12.     on_overlap_tile)
  13. def flood_reveal(num: number, num2: number):
  14.     global number_of_gophers_but_here
  15.     if not (tiles.tile_is_wall(tiles.get_tile_location(num, num2))):
  16.         if not (tiles.tile_at_location_equals(tiles.get_tile_location(num, num2),
  17.             assets.tile("""
  18.                 tile
  19.                 """))):
  20.             return
  21.         else:
  22.             tiles.place_on_tile(recursive_target, tiles.get_tile_location(num, num2))
  23.             number_of_gophers_but_here = count_gophers_where_i_am(recursive_target)
  24.             tiles.set_tile_at(tiles.get_tile_location(num, num2),
  25.                 tile_Numbers[number_of_gophers_but_here])
  26.             if 0 < number_of_gophers_but_here:
  27.                 return
  28.             else:
  29.                 flood_reveal(num - 1, num2 - 1)
  30.                 flood_reveal(num - 1, num2 - 0)
  31.                 flood_reveal(num - 0, num2 - 1)
  32.                 flood_reveal(num + 1, num2 - 0)
  33.                 flood_reveal(num + 1, num2 + 1)
  34.                 flood_reveal(num + 0, num2 + 1)
  35.                 flood_reveal(num - 1, num2 + 1)
  36.                 flood_reveal(num + 1, num2 - 1)
  37. def game_over():
  38.     currentTile.destroy()
  39.     for value in sprites.all_of_kind(SpriteKind.Tile):
  40.         value.destroy()
  41.         pause(10)
  42.     game.over(False)
  43. def on_a_pressed():
  44.     global temp_number
  45.     if target.overlaps_with(currentTile):
  46.         if tiles.tile_at_location_equals(tiles.location_of_sprite(currentTile),
  47.             assets.tile("""
  48.                 tile2
  49.                 """)):
  50.             game_over()
  51.         temp_number = count_gophers_where_i_am(currentTile)
  52.         if 0 < temp_number:
  53.             tiles.set_tile_at(tiles.location_of_sprite(currentTile),
  54.                 tile_Numbers[temp_number])
  55.         else:
  56.             flood_reveal(tiles.location_xy(tiles.location_of_sprite(currentTile), tiles.XY.COLUMN),
  57.                 tiles.location_xy(tiles.location_of_sprite(currentTile), tiles.XY.ROW))
  58.         currentTile.destroy()
  59.     if len(sprites.all_of_kind(SpriteKind.Tile)) <= number_of_gophers:
  60.         game.over(True)
  61. controller.A.on_event(ControllerButtonEvent.PRESSED, on_a_pressed)
  62. def on_overlap_tile2(sprite2, location2):
  63.     sprite2.destroy()
  64. scene.on_overlap_tile(SpriteKind.Tile,
  65.     assets.tile("""
  66.         tile17
  67.         """),
  68.     on_overlap_tile2)
  69. def on_overlap_tile3(sprite3, location3):
  70.     sprite3.destroy()
  71. scene.on_overlap_tile(SpriteKind.Tile,
  72.     assets.tile("""
  73.         tile19
  74.         """),
  75.     on_overlap_tile3)
  76. def on_overlap_tile4(sprite4, location4):
  77.     sprite4.destroy()
  78. scene.on_overlap_tile(SpriteKind.Tile,
  79.     assets.tile("""
  80.         tile18
  81.         """),
  82.     on_overlap_tile4)
  83. def on_b_pressed():
  84.     if not (sprites.read_data_boolean(currentTile, "revealed")):
  85.         if currentTile.image.equals(unseenTileImage):
  86.             currentTile.set_image(seenTileImage)
  87.         else:
  88.             currentTile.set_image(unseenTileImage)
  89. controller.B.on_event(ControllerButtonEvent.PRESSED, on_b_pressed)
  90. def on_overlap_tile5(sprite5, location5):
  91.     sprite5.destroy()
  92. scene.on_overlap_tile(SpriteKind.Tile,
  93.     assets.tile("""
  94.         tile14
  95.         """),
  96.     on_overlap_tile5)
  97. def on_overlap_tile6(sprite6, location6):
  98.     sprite6.destroy()
  99. scene.on_overlap_tile(SpriteKind.Tile,
  100.     assets.tile("""
  101.         tile15
  102.         """),
  103.     on_overlap_tile6)
  104. def on_overlap_tile7(sprite7, location7):
  105.     sprite7.destroy()
  106. scene.on_overlap_tile(SpriteKind.Tile,
  107.     assets.tile("""
  108.         tile12
  109.         """),
  110.     on_overlap_tile7)
  111. def make_cover_tiles():
  112.     global tile
  113.     for value2 in tiles.get_tiles_by_type(assets.tile("""
  114.         tile
  115.         """)):
  116.         tile = sprites.create(img("""
  117.                 9 1 1 1 1 1 1 d
  118.                 1 b b b b b b c
  119.                 1 b b b b b b c
  120.                 1 b b b b b b c
  121.                 1 b b b b b b c
  122.                 1 b b b b b b c
  123.                 1 b b b b b b c
  124.                 d c c c c c c f
  125.                 """),
  126.             SpriteKind.Tile)
  127.         tile.set_flag(SpriteFlag.INVISIBLE, False)
  128.         tiles.place_on_tile(tile, value2)
  129.         sprites.set_data_boolean(tile, "revealed", False)
  130. def count_gophers_where_i_am(mySprite: Sprite):
  131.     global currentTileLocation, number_of_gophers_next_to_me
  132.     currentTileLocation = tiles.location_of_sprite(mySprite)
  133.     number_of_gophers_next_to_me = 0
  134.     if tiles.tile_is(tiles.location_in_direction(tiles.location_in_direction(currentTileLocation, CollisionDirection.LEFT),
  135.             CollisionDirection.TOP),
  136.         assets.tile("""
  137.             tile2
  138.             """)):
  139.         number_of_gophers_next_to_me += 1
  140.     if tiles.tile_is(tiles.location_in_direction(currentTileLocation, CollisionDirection.TOP),
  141.         assets.tile("""
  142.             tile2
  143.             """)):
  144.         number_of_gophers_next_to_me += 1
  145.     if tiles.tile_is(tiles.location_in_direction(tiles.location_in_direction(currentTileLocation, CollisionDirection.TOP),
  146.             CollisionDirection.RIGHT),
  147.         assets.tile("""
  148.             tile2
  149.             """)):
  150.         number_of_gophers_next_to_me += 1
  151.     if tiles.tile_is(tiles.location_in_direction(currentTileLocation, CollisionDirection.LEFT),
  152.         assets.tile("""
  153.             tile2
  154.             """)):
  155.         number_of_gophers_next_to_me += 1
  156.     if tiles.tile_is(tiles.location_in_direction(currentTileLocation, CollisionDirection.RIGHT),
  157.         assets.tile("""
  158.             tile2
  159.             """)):
  160.         number_of_gophers_next_to_me += 1
  161.     if tiles.tile_is(tiles.location_in_direction(tiles.location_in_direction(currentTileLocation, CollisionDirection.BOTTOM),
  162.             CollisionDirection.LEFT),
  163.         assets.tile("""
  164.             tile2
  165.             """)):
  166.         number_of_gophers_next_to_me += 1
  167.     if tiles.tile_is(tiles.location_in_direction(currentTileLocation, CollisionDirection.BOTTOM),
  168.         assets.tile("""
  169.             tile2
  170.             """)):
  171.         number_of_gophers_next_to_me += 1
  172.     if tiles.tile_is(tiles.location_in_direction(tiles.location_in_direction(currentTileLocation, CollisionDirection.BOTTOM),
  173.             CollisionDirection.RIGHT),
  174.         assets.tile("""
  175.             tile2
  176.             """)):
  177.         number_of_gophers_next_to_me += 1
  178.     return number_of_gophers_next_to_me
  179. def on_on_overlap(sprite8, otherSprite):
  180.     global currentTile
  181.     currentTile = otherSprite
  182. sprites.on_overlap(SpriteKind.Collison, SpriteKind.Tile, on_on_overlap)
  183. def on_overlap_tile8(sprite9, location8):
  184.     sprite9.destroy()
  185. scene.on_overlap_tile(SpriteKind.Tile,
  186.     assets.tile("""
  187.         tile0
  188.         """),
  189.     on_overlap_tile8)
  190. def on_overlap_tile9(sprite10, location9):
  191.     sprite10.destroy()
  192. scene.on_overlap_tile(SpriteKind.Tile,
  193.     assets.tile("""
  194.         tile13
  195.         """),
  196.     on_overlap_tile9)
  197. def place_gophers():
  198.     global allOpenTiles, random_tile_index
  199.     allOpenTiles = tiles.get_tiles_by_type(assets.tile("""
  200.         tile
  201.         """))
  202.     index = 0
  203.     while index <= number_of_gophers - 1:
  204.         random_tile_index = randint(0, len(allOpenTiles) - 1)
  205.         tiles.set_tile_at(allOpenTiles.remove_at(random_tile_index),
  206.             assets.tile("""
  207.                 tile2
  208.                 """))
  209.         index += 1
  210. random_tile_index = 0
  211. allOpenTiles: List[tiles.Location] = []
  212. number_of_gophers_next_to_me = 0
  213. currentTileLocation: tiles.Location = None
  214. tile: Sprite = None
  215. temp_number = 0
  216. currentTile: Sprite = None
  217. number_of_gophers_but_here = 0
  218. tile_Numbers: List[Image] = []
  219. number_of_gophers = 0
  220. seenTileImage: Image = None
  221. unseenTileImage: Image = None
  222. target: Sprite = None
  223. recursive_target: Sprite = None
  224. num_flags_placed = 0
  225. tiles.set_small_tilemap(tilemap("""
  226.     level1
  227.     """))
  228. recursive_target = sprites.create(img("""
  229.     3
  230.     """), SpriteKind.secret)
  231. recursive_target.set_flag(SpriteFlag.INVISIBLE, True)
  232. cursor = sprites.create(img("""
  233.         . . f . . . . .
  234.         . f 1 f . . . .
  235.         . f 1 f f f . .
  236.         . f 1 b 1 b f .
  237.         . f 1 b 1 b 1 f
  238.         f 1 1 1 1 1 1 f
  239.         f 1 1 1 1 1 1 f
  240.         . f f f f f f .
  241.         """),
  242.     SpriteKind.player)
  243. cursor.z = 10000000000
  244. target = sprites.create(img("""
  245.     2
  246.     """), SpriteKind.Collison)
  247. target.set_flag(SpriteFlag.INVISIBLE, True)
  248. controller.move_sprite(cursor, 50, 50)
  249. unseenTileImage = img("""
  250.     9 1 1 1 1 1 1 d
  251.     1 b b b b b b c
  252.     1 b b b b b b c
  253.     1 b b b b b b c
  254.     1 b b b b b b c
  255.     1 b b b b b b c
  256.     1 b b b b b b c
  257.     d c c c c c c f
  258.     """)
  259. seenTileImage = img("""
  260.     9 1 1 1 1 1 1 d
  261.     1 b b b b 2 2 c
  262.     1 b e e e e b 2
  263.     1 b f e f e 2 c
  264.     1 e e e e e b c
  265.     1 b e e e e 2 c
  266.     1 b b b b b b c
  267.     d c c c c c c f
  268.     """)
  269. number_of_gophers = 30
  270. tile_Numbers = [assets.tile("""
  271.         tile12
  272.         """),
  273.     assets.tile("""
  274.         tile0
  275.         """),
  276.     assets.tile("""
  277.         tile13
  278.         """),
  279.     assets.tile("""
  280.         tile14
  281.         """),
  282.     assets.tile("""
  283.         tile15
  284.         """),
  285.     assets.tile("""
  286.         tile16
  287.         """),
  288.     assets.tile("""
  289.         tile17
  290.         """),
  291.     assets.tile("""
  292.         tile18
  293.         """),
  294.     assets.tile("""
  295.         tile19
  296.         """)]
  297. make_cover_tiles()
  298. place_gophers()
  299. def on_on_update():
  300.     target.set_position(Math.floor(cursor.left) + 3, Math.floor(cursor.top) + 1)
  301. game.on_update(on_on_update)
复制代码


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 1 小时前

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏

这是一个使用MakeCode Arcade开发的扫雷游戏代码。

游戏核心机制

1. 初始化设置
python
  1. # 创建自定义精灵类型
  2. class SpriteKind:
  3.     Collison = SpriteKind.create()  # 碰撞检测
  4.     Tile = SpriteKind.create()      # 地砖覆盖层
  5.     secret = SpriteKind.create()    # 秘密精灵(用于递归计算)
复制代码


2. 游戏组件
地图:使用tilemap创建游戏网格
光标:玩家控制的可移动光标
目标标记:用于检测当前选中的格子
地砖覆盖:覆盖在每个格子上的可点击层

3. 核心函数解析
地雷放置函数 place_gophers()

python
  1. def place_gophers():
  2.     global allOpenTiles, random_tile_index
  3.     allOpenTiles = tiles.get_tiles_by_type(assets.tile("tile"))  # 获取所有可放置位置
  4.     # 随机放置指定数量的地雷
  5.     for i in range(number_of_gophers):
  6.         random_tile_index = randint(0, len(allOpenTiles) - 1)
  7.         tiles.set_tile_at(allOpenTiles.remove_at(random_tile_index), assets.tile("tile2"))
复制代码

地雷计数函数 count_gophers_where_i_am()

python
  1. def count_gophers_where_i_me(mySprite: Sprite):
  2.     # 检查当前格子周围8个方向的地雷数量
  3.     number_of_gophers_next_to_me = 0
  4.     # 检查左上、上、右上、左、右、左下、下、右下8个位置
  5.     return number_of_gophers_next_to_me
复制代码

洪水揭示算法 flood_reveal()

python
  1. def flood_reveal(num: number, num2: number):
  2.     # 递归揭示空白区域(类似标准扫雷的连片空白揭示)
  3.     if 当前格子不是墙且未被揭示:
  4.         if 周围地雷数 > 0:
  5.             显示数字
  6.             return
  7.         else:
  8.             # 递归检查周围8个方向
  9.             flood_reveal(num-1, num2-1)  # 左上
  10.             flood_reveal(num-1, num2)    # 上
  11.             flood_reveal(num, num2-1)    # 左
  12.             # ... 其他方向
复制代码


4. 玩家控制
A键按下 - 揭示格子

python
  1. def on_a_pressed():
  2.     if 点击到地雷: game_over()  # 游戏结束
  3.     if 周围有地雷: 显示数字
  4.     else: flood_reveal()  # 递归揭示空白区域
复制代码

B键按下 - 标记/取消标记

python
  1. def on_b_pressed():
  2.     # 切换地砖图像(标记/取消标记)
  3.     if currentTile.image.equals(unseenTileImage):
  4.         currentTile.set_image(seenTileImage)
  5.     else:
  6.         currentTile.set_image(unseenTileImage)
复制代码


5. 游戏结束条件
失败:点击到地雷格子(tile2)
胜利:所有非地雷格子都被揭示(剩余地砖数 ≤ 地雷数)

6. 视觉表现
未揭示格子:灰色覆盖层
已揭示格子:显示数字或空白
数字显示:使用不同的tile图像表示1-8的数字

游戏特点
经典扫雷玩法:数字表示周围地雷数量
递归揭示:空白区域自动连片揭示
标记功能:可标记疑似地雷位置
逐步揭示:动画效果展示游戏过程

这个实现完整地复现了经典Windows扫雷游戏的核心机制,包括地雷生成、数字计算、递归揭示和胜负判定等关键功能。

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 1 小时前

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏

图形编程参考实验程序

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图1

通过模拟器,调试与模拟运行

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图6

实验场景记录

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图3

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图2

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图5

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图4

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 1 小时前

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏

【花雕动手做】基于Kitronik可编程开发板之扫地雷游戏图1
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail