回到首页 返回首页
回到顶部 回到顶部
返回上一页 返回上一页

【花雕动手做】Kitronik 可编程开发板基于 ARCADE MakeCode 之叠羊罗汉游戏 简单

头像 驴友花雕 2025.09.16 6 0

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

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

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

 

00 (2).jpg
00 (3).jpg
00 (4).jpg

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

MicroPython实验代码

 

代码
@namespace
class SpriteKind:
    Mountain = SpriteKind.create()
    Goat = SpriteKind.create()
def drop_goat():
    moving_goat.ay = 300
    moving_goat.vx = 0
    moving_goat.set_flag(SpriteFlag.BOUNCE_ON_WALL, False)

def on_a_pressed():
    drop_goat()
controller.A.on_event(ControllerButtonEvent.PRESSED, on_a_pressed)

# calculate new center of gravity
def will_the_stack_fall_down_():
    global mountain_goats, center_of_gravity
    mountain_goats = sprites.all_of_kind(SpriteKind.Mountain)
    center_of_gravity = 0
    for value in mountain_goats:
        center_of_gravity += value.x
    if center_of_gravity / len(mountain_goats) < bottom_goat.left or center_of_gravity / len(mountain_goats) > bottom_goat.right:
        return True
    return False
def will_the_goat_fall_off(falling_goat: Sprite, mountain_goat: Sprite):
    if falling_goat.x > mountain_goat.right:
        falling_goat.set_velocity(50, -50)
        falling_goat.set_flag(SpriteFlag.GHOST, True)
        falling_goat.set_flag(SpriteFlag.AUTO_DESTROY, True)
        info.change_life_by(-1)
        return True
    elif falling_goat.x < mountain_goat.left:
        falling_goat.set_velocity(-50, 50)
        falling_goat.set_flag(SpriteFlag.GHOST, True)
        falling_goat.set_flag(SpriteFlag.AUTO_DESTROY, True)
        info.change_life_by(-1)
        return True
    else:
        return False

def on_hit_wall(sprite, location):
    if sprite.is_hitting_tile(CollisionDirection.BOTTOM):
        game.over(False)
scene.on_hit_wall(SpriteKind.Goat, on_hit_wall)

def explode_goats():
    global current_goat
    current_goat = bottom_goat
    while current_goat:
        current_goat.set_flag(SpriteFlag.GHOST, True)
        current_goat.set_velocity(randint(-200, 200), randint(-200, 200))
        current_goat = sprites.read_data_sprite(current_goat, "goat on top of me")
        scene.camera_follow_sprite(None)

def on_on_overlap(sprite2, otherSprite):
    global goat_fell_off, top_goat
    sprite2.vy = 0
    sprite2.ay = 0
    sprite2.set_kind(SpriteKind.Mountain)
    goat_fell_off = will_the_goat_fall_off(sprite2, otherSprite)
    if goat_fell_off:
        sprite2.start_effect(effects.fire)
    elif will_the_stack_fall_down_():
        sprites.set_data_sprite(otherSprite, "goat on top of me", sprite2)
        explode_goats()
        pause(1000)
        game.over(False)
    else:
        top_goat = sprite2
        scene.camera_follow_sprite(sprite2)
        sprites.set_data_sprite(otherSprite, "goat on top of me", sprite2)
    make_a_new_goat()
sprites.on_overlap(SpriteKind.Goat, SpriteKind.Mountain, on_on_overlap)

def make_a_new_goat():
    global moving_goat
    moving_goat = sprites.create(goat_species[randint(0, len(goat_species) - 1)],
        SpriteKind.Goat)
    moving_goat.set_position(80, top_goat.y - 30)
    moving_goat.set_flag(SpriteFlag.BOUNCE_ON_WALL, True)
    moving_goat.vx = 40
goat_fell_off = False
current_goat: Sprite = None
center_of_gravity = 0
mountain_goats: List[Sprite] = []
moving_goat: Sprite = None
bottom_goat: Sprite = None
top_goat: Sprite = None
goat_species: List[Image] = []
goat_species = [img("""
        . . . . . . . . . . . . f e e .
        . . . . . . . . . . . . . e e .
        . . . . . . . . . . . . d c d c
        . . . . . . . . . . . . d d d d
        e d d d d d d d d d d d d a d d
        . d d d d d d d d d d d d d a a
        . d d d d d d d d d d d d . . .
        . d d d d d d d d d d d d . . .
        . . d d d d d d d d d d . . . .
        . . . d . d . . d . d . . . . .
        . . . d . d . . d . d . . . . .
        . . . e . e . . e . e . . . . .
        """),
    img("""
        . . . . f f . . . . . . . . . . . . .
        . . d f f d f . . . . . . . . . . . .
        . 4 4 4 4 4 4 4 . . . . . . . . . . .
        . . 1 4 4 1 . . . . . . . . . . . . .
        . 4 4 4 4 4 4 . . . . . . . . . . . .
        . 4 4 4 4 4 4 . . . . . . . . . . . .
        4 4 4 2 4 4 4 4 4 4 4 4 4 4 4 4 4 . .
        . 4 2 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
        . . 2 . . 4 4 4 4 4 4 4 4 4 4 4 4 4 .
        . . . . . 4 4 4 4 4 4 4 4 4 4 4 4 4 .
        . . . . . 4 2 4 2 2 2 2 2 2 2 2 2 . .
        . . . . . 4 . 4 . . . . . 2 . 4 . . .
        . . . . . 4 . 4 . . . . . 2 . 4 . . .
        . . . . . 4 . 4 . . . . . 2 . 4 . . .
        """),
    img("""
        . . . . . . . . b b d . . d d b . . .
        . . . . . . . . b b b b b b b b . . .
        . . . . . . . . . b b d b b d . . . .
        . . . . . . . . . . b b b b b c . . .
        . b . . . . . . . b b b b b b b . . .
        . b . . . . b b b b b b b b b b . . .
        . c b b b b b b b b b b . . . . . . .
        . c b b b b b b b b b b . . . . . . .
        . . c b b b b b b b b b . . . . . . .
        . . c c b b b b b b b c . . . . . . .
        . . c c c c c c c c c c . . . . . . .
        . . c . b . . . c c c c . . . . . . .
        . . c . b . . . . b . c . . . . . . .
        . . c . b . . . . b . c . . . . . . .
        """),
    img("""
        . . . . . . . . . . . . e . . e . . .
        . . . . . . . . . . . e e e e e e . .
        . . . . . . . . . . e e e e e e e e .
        . . . . . . . . . e e e e c c c e e e
        . . . . . . . . . . . . c c b c . . .
        . . . c c c c c c c c c c f b f c . .
        . . c c b b b b b b b b b f b f . . .
        . . c b b b c c c b b b b b b c . . .
        . c c b b c b b b b b b f b b c . . .
        c c b b c b b b b b b b b f f f . . .
        c b b b b b b b b b b b c c c . . . .
        c c c c c c c c c c c c c . . . . . .
        . . . . c . c . . . c . c . . . . . .
        . . . . c . c . . . c . c . . . . . .
        """),
    img("""
        . . . 1 . . . . . . . . . . . . . .
        . . 1 c c c . . . . . . . . . . . .
        . 1 1 1 1 c c . . . . . . . . . . 1
        1 1 f 1 c 1 c c . . . . . . . . . 1
        1 1 1 c 1 1 c c 1 1 1 1 1 1 1 1 1 1
        1 1 1 c c c c 1 1 1 1 1 1 1 1 1 1 .
        . . . 1 c c 1 1 1 1 1 1 1 1 1 1 1 .
        . . . . 1 1 1 1 1 1 1 1 1 1 1 1 1 .
        . . . . 1 1 1 1 1 1 1 1 1 1 1 1 1 .
        . . . . 1 1 1 1 1 1 1 1 1 1 1 1 1 .
        . . . . 1 1 1 1 1 1 1 1 1 1 1 1 1 .
        . . . . 1 . 1 . . . . . . . 1 . 1 .
        . . . . 1 . 1 . . . . . . . 1 . 1 .
        . . . . 1 . 1 . . . . . . . 1 . 1 .
        . . . . 1 . 1 . . . . . . . 1 . 1 .
        . . . . c . c . . . . . . . c . c .
        """),
    img("""
        .........................
        ff.............ff...ff...
        .ff............ffffff....
        ..ff............ff2f2ffff
        ...f............fffffffff
        ...f............ffffff...
        ...ff2f2ffffffffffffff...
        ....f2f22fffffffff.......
        ....f2ff2fffffffff.......
        ....ff22ffffffffff.......
        ....ffffffffffffff.......
        ....fffffffff222ff.......
        ....ffffffff2ff2ff.......
        ....ffffffff22f2ff.......
        ....fffffffff222f........
        .....f...f...f..f........
        .....f...f...f..f........
        .....f...f...f..f........
        """)]
scene.set_background_color(9)
tiles.set_tilemap(tilemap("""
    级别1
    """))
goat = sprites.create(img("""
        . . . . f f . . . . . . . . . . . . .
        . . d f f d f . . . . . . . . . . . .
        . 4 4 4 4 4 4 4 . . . . . . . . . . .
        . . 1 4 4 1 . . . . . . . . . . . . .
        . 4 4 4 4 4 4 . . . . . . . . . . . .
        . 4 4 4 4 4 4 . . . . . . . . . . . .
        4 4 4 2 4 4 4 4 4 4 4 4 4 4 4 4 4 . .
        . 4 2 2 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
        . . 2 . . 4 4 4 4 4 4 4 4 4 4 4 4 4 .
        . . . . . 4 4 4 4 4 4 4 4 4 4 4 4 4 .
        . . . . . 4 2 4 2 2 2 2 2 2 2 2 2 . .
        . . . . . 4 . 4 . . . . . 2 . 4 . . .
        . . . . . 4 . 4 . . . . . 2 . 4 . . .
        . . . . . 4 . 4 . . . . . 2 . 4 . . .
        """),
    SpriteKind.Mountain)
goat.ay = 300
goat.set_position(80, 600)
scene.camera_follow_sprite(goat)
top_goat = goat
make_a_new_goat()
how_much_does_a_goat_weigh = 22
info.set_life(3)
bottom_goat = goat

ARCADE MakeCode 之叠羊罗汉游戏代码解读
这是一个基于ARCADE MakeCode的"叠羊罗汉"平衡游戏,玩家需要控制山羊叠放在一起而不倒塌。解读代码如下:

1. 自定义精灵类型
python
@namespace
class SpriteKind:
   Mountain = SpriteKind.create()  # 已经落下的山羊
   Goat = SpriteKind.create()      # 正在移动的山羊

2. 放下山羊函数
python
def drop_goat():
   moving_goat.ay = 300          # 启用重力
   moving_goat.vx = 0            # 停止水平移动
   moving_goat.set_flag(SpriteFlag.BOUNCE_ON_WALL, False)  # 关闭墙壁反弹

def on_a_pressed():
   drop_goat()  # A键按下时放下当前山羊

controller.A.on_event(ControllerButtonEvent.PRESSED, on_a_pressed)

3. 平衡检测函数
检查整个堆栈是否会倒塌
python
def will_the_stack_fall_down_():
   global mountain_goats, center_of_gravity
   mountain_goats = sprites.all_of_kind(SpriteKind.Mountain)  # 获取所有已落下的山羊
   center_of_gravity = 0
   for value in mountain_goats:
       center_of_gravity += value.x  # 计算所有山羊的x坐标总和
   
   # 如果重心超出底部山羊的左右边界,则堆栈会倒塌
   if center_of_gravity / len(mountain_goats) < bottom_goat.left or center_of_gravity / len(mountain_goats) > bottom_goat.right:
       return True
   return False
检查单个山羊是否会掉落
python
def will_the_goat_fall_off(falling_goat: Sprite, mountain_goat: Sprite):
   if falling_goat.x > mountain_goat.right:  # 山羊超出右侧边界
       falling_goat.set_velocity(50, -50)    # 设置掉落速度和方向
       falling_goat.set_flag(SpriteFlag.GHOST, True)      # 变为幽灵状态(可穿透)
       falling_goat.set_flag(SpriteFlag.AUTO_DESTROY, True)  # 自动销毁
       info.change_life_by(-1)               # 减少生命值
       return True
   elif falling_goat.x < mountain_goat.left:  # 山羊超出左侧边界
       falling_goat.set_velocity(-50, 50)     # 设置掉落速度和方向
       falling_goat.set_flag(SpriteFlag.GHOST, True)
       falling_goat.set_flag(SpriteFlag.AUTO_DESTROY, True)
       info.change_life_by(-1)
       return True
   else:
       return False  # 山羊安全落在平台上

4. 碰撞检测
python
def on_hit_wall(sprite, location):
   if sprite.is_hitting_tile(CollisionDirection.BOTTOM):  # 如果山羊碰到底部墙壁
       game.over(False)  # 游戏结束

scene.on_hit_wall(SpriteKind.Goat, on_hit_wall)

5. 山羊堆栈爆炸效果
python
def explode_goats():
   global current_goat
   current_goat = bottom_goat  # 从底部山羊开始
   while current_goat:
       current_goat.set_flag(SpriteFlag.GHOST, True)  # 变为幽灵状态
       # 设置随机速度,产生爆炸效果
       current_goat.set_velocity(randint(-200, 200), randint(-200, 200))
       # 获取堆叠在上面的山羊
       current_goat = sprites.read_data_sprite(current_goat, "goat on top of me")
       scene.camera_follow_sprite(None)  # 取消相机跟随

6. 山羊重叠事件处理(核心逻辑)
python
def on_on_overlap(sprite2, otherSprite):
   global goat_fell_off, top_goat
   sprite2.vy = 0      # 停止垂直移动
   sprite2.ay = 0      # 取消重力
   sprite2.set_kind(SpriteKind.Mountain)  # 变为已落下的山羊
   
   # 检查山羊是否会掉落
   goat_fell_off = will_the_goat_fall_off(sprite2, otherSprite)
   if goat_fell_off:
       sprite2.start_effect(effects.fire)  # 播放火焰效果
   elif will_the_stack_fall_down_():  # 检查整个堆栈是否会倒塌
       # 记录山羊堆叠关系
       sprites.set_data_sprite(otherSprite, "goat on top of me", sprite2)
       explode_goats()  # 爆炸效果
       pause(1000)
       game.over(False)  # 游戏结束
   else:
       top_goat = sprite2  # 更新顶部山羊
       scene.camera_follow_sprite(sprite2)  # 相机跟随新顶部山羊
       # 记录山羊堆叠关系
       sprites.set_data_sprite(otherSprite, "goat on top of me", sprite2)
   
   make_a_new_goat()  # 创建新的山羊

sprites.on_overlap(SpriteKind.Goat, SpriteKind.Mountain, on_on_overlap)

7. 创建新山羊函数
python
def make_a_new_goat():
   global moving_goat
   # 随机选择山羊种类
   moving_goat = sprites.create(goat_species[randint(0, len(goat_species) - 1)],
       SpriteKind.Goat)
   moving_goat.set_position(80, top_goat.y - 30)  # 放在顶部山羊上方
   moving_goat.set_flag(SpriteFlag.BOUNCE_ON_WALL, True)  # 开启墙壁反弹
   moving_goat.vx = 40  # 设置水平移动速度

8. 山羊种类定义
代码中定义了6种不同样式的山羊图像,增加了游戏的多样性。


9. 游戏初始化
python
scene.set_background_color(9)  # 设置背景颜色
tiles.set_tilemap(tilemap("级别1"))  # 设置地图

# 创建初始山羊
goat = sprites.create(..., SpriteKind.Mountain)
goat.ay = 300  # 启用重力
goat.set_position(80, 600)  # 设置位置
scene.camera_follow_sprite(goat)  # 相机跟随
top_goat = goat  # 设置顶部山羊
make_a_new_goat()  # 创建新山羊

how_much_does_a_goat_weigh = 22  # 山羊重量(可能用于后续扩展)
info.set_life(3)  # 设置初始生命值
bottom_goat = goat  # 设置底部山羊

 

游戏机制总结
控制方式:山羊左右移动,按A键放下

平衡系统:计算堆栈重心,如果超出底部山羊边界则倒塌

生命系统:山羊掉落减少生命值,生命值为0时游戏结束

堆叠关系:使用数据存储记录山羊之间的堆叠关系

视觉效果:掉落的山羊有火焰效果,倒塌时有爆炸效果

相机跟随:相机始终跟随最顶部的山羊

这是一个有趣的物理平衡游戏,玩家需要精确控制放下山羊的时机和位置,以保持堆栈的平衡。游戏通过重心计算和物理效果实现了真实的堆叠体验。

图形编程参考实验程序

 

127.jpg

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

 

00210---0.gif
00211.gif

 

实验场景记录

 

128 (1).jpg
128 (2).jpg
128 (3).jpg

评论

user-avatar
icon 他的勋章
    展开更多