驴友花雕 发表于 昨天 08:39

【花雕动手做】基于 Kitronik 可编程开发板之叠羊罗汉

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

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

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





驴友花雕 发表于 昨天 08:43

【花雕动手做】基于 Kitronik 可编程开发板之叠羊罗汉

作为学习、练习与尝试,这里创建一个叠羊罗汉的小游戏。
打开网页版: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,
      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 = []
moving_goat: Sprite = None
bottom_goat: Sprite = None
top_goat: Sprite = None
goat_species: List = []
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

驴友花雕 发表于 昨天 08:48

【花雕动手做】基于 Kitronik 可编程开发板之叠羊罗汉

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,

      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时游戏结束

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

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

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

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

驴友花雕 发表于 昨天 08:52

【花雕动手做】基于 Kitronik 可编程开发板之叠羊罗汉

图形编程参考实验程序


驴友花雕 发表于 昨天 08:54

【花雕动手做】基于 Kitronik 可编程开发板之叠羊罗汉

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





实验场景记录







驴友花雕 发表于 昨天 08:57

【花雕动手做】基于 Kitronik 可编程开发板之叠羊罗汉


页: [1]
查看完整版本: 【花雕动手做】基于 Kitronik 可编程开发板之叠羊罗汉