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

【花雕动手做】Kitronik 可编程游戏开发板基于 ARCADE MakeCode之弹跳桶游戏 简单

头像 驴友花雕 2025.09.25 6 0

00 (3).jpg

Kitronik ARCADE 使用 Microsoft MakeCode 平台,具有以下优势:
图形化编程界面:适合初学者,支持拖拽式编程。
即时模拟器:可以实时测试游戏效果。
硬件兼容性:可部署到 Kitronik ARCADE 设备,实现实体游戏体验。
支持 Python/JavaScript:便于进阶学习。

 

00 (2).jpg

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

MicroPython实验代码
 

代码
@namespace
class SpriteKind:
    Ball = SpriteKind.create()
bouncers: List[Sprite] = []
balls: List[Image] = []
catcher: Sprite = None
deadball: Sprite = None
sitting = 0
playing = False
game.splash("Bouncer Bucket", "A = 1 ball, B = 10 balls")
balls.append(img("""
    . . 7 7 7 7 . .
    . 7 7 7 7 7 7 .
    7 7 7 7 7 7 7 7
    7 7 7 7 7 7 7 7
    7 7 7 7 7 7 7 7
    7 7 7 7 7 7 7 7
    . 7 7 7 7 7 7 .
    . . 7 7 7 7 . .
    """))
balls.append(img("""
    . . 2 2 2 2 . .
    . 2 2 2 2 2 2 .
    2 2 2 2 2 2 2 2
    2 2 2 2 2 2 2 2
    2 2 2 2 2 2 2 2
    2 2 2 2 2 2 2 2
    . 2 2 2 2 2 2 .
    . . 2 2 2 2 . .
    """))
balls.append(img("""
    . . 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 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 . .
    """))
catcher = sprites.create(img("""
        . . . . . . . . . . . . . . . .
        . . . . . . . . . . . . . . . .
        1 . . . . . . . . . . . . . . 1
        f e e . . . . . . . . . . e e f
        1 f e e . . . . . . . . e e f 1
        1 1 f e e e e e e e e e e f 1 1
        . 1 e f e e e e e e e e f e 1 .
        . 1 e f e e e e e e e e f e 1 .
        . 1 e e f f e e e e f f e e 1 .
        . 1 e e e e f f f f e e e e 1 .
        . 1 1 e e e e e e e e e e 1 1 .
        . . 1 e e e e e e e e e e 1 . .
        . . 1 e e e e e e e e e e 1 . .
        . . 1 1 e e e e e e e e 1 1 . .
        . . . 1 e e e e e e e e 1 . . .
        . . . 1 1 1 1 1 1 1 1 1 1 . . .
        """),
    SpriteKind.player)
catcher.bottom = scene.screen_height() - 1
catcher.set_stay_in_screen(True)
info.set_score(0)

def on_on_overlap(sprite, otherSprite):
    if sprite.x > otherSprite.x - 2 and sprite.x < otherSprite.x + 2:
        if sitting > 300:
            otherSprite.say("nope", 200)
            sprite.vy = sprite.vy * -2
        else:
            normalScore = sprite.vx
            if normalScore < 0:
                normalScore = normalScore * -1
            otherSprite.say("" + str(normalScore), 200)
            info.set_score(info.score() + normalScore)
            sprite.destroy()
    elif sprite.x <= otherSprite.x:
        sprite.vx = sprite.vx * -2
    else:
        sprite.vx = sprite.vx * 2
sprites.on_overlap(SpriteKind.Ball, SpriteKind.player, on_on_overlap)

def on_countdown_end():
    global playing
    playing = False
    game.over(False)
info.on_countdown_end(on_countdown_end)

def on_on_destroyed(sprite2):
    global deadball
    j = 0
    while j <= len(bouncers) - 1:
        if bouncers[j] == sprite2:
            deadball = bouncers.remove_at(j)
        j += 1
    makeBouncer()
sprites.on_destroyed(SpriteKind.Ball, on_on_destroyed)

def on_a_pressed():
    global playing
    if not playing:
        playing = True
        makeBouncer()
        info.start_countdown(60)
controller.A.on_event(ControllerButtonEvent.PRESSED, on_a_pressed)

def on_b_pressed():
    global playing
    if not playing:
        playing = True
        for i in range(10):
            makeBouncer()
        info.start_countdown(30)
controller.B.on_event(ControllerButtonEvent.PRESSED, on_b_pressed)

def makeBouncer():
    ballChoice = randint(0, 2)
    ballsCount = bouncers.unshift(sprites.create(balls[ballChoice], SpriteKind.Ball))
    bouncers[0].set_flag(SpriteFlag.AUTO_DESTROY, True)
    bouncers[0].x = randint(0, scene.screen_width() / 4)
    bouncers[0].y = randint(0, scene.screen_height() / 3)
    bouncers[0].vx = 10 + ballChoice * 10
    bouncers[0].ay = 100

def on_on_update():
    global sitting
    moveX = controller.dx()
    if moveX != 0:
        sitting = 0
        catcher.x += moveX
game.on_update(on_on_update)

def on_update_interval():
    global sitting
    for bouncer in bouncers:
        if bouncer.bottom >= scene.screen_height() and bouncer.vy > 0:
            bouncer.vy = bouncer.vy * -1
            bouncer.ay = bouncer.ay + 20
    sitting += 1
game.on_update_interval(10, on_update_interval)

这段 Arcade MakeCode 的《弹跳桶游戏》使用 MicroPython 编写,是一个反应类得分游戏,玩家控制一个“桶”接住弹跳球以获得分数。玩家通过按下 A 或 B 键启动游戏,控制底部的“桶”左右移动,接住从上方弹跳下来的球。每接住一个球,根据其水平速度获得相应分数。游戏有时间限制,球也会不断反弹。

代码结构详解

1、精灵种类定义
python
@namespace
class SpriteKind:
   Ball = SpriteKind.create()
创建一个新的精灵种类 Ball,用于标记弹跳球。

2、球的图像与列表初始化
python
balls: List[Image] = []
balls.append(img("""..."""))  # 三种不同颜色的球
创建三种不同颜色的球图像并存入列表,供后续随机选择。

3、玩家桶设置
python
catcher = sprites.create(img("""..."""), SpriteKind.player)
catcher.bottom = scene.screen_height() - 1
catcher.set_stay_in_screen(True)
创建玩家控制的“桶”精灵,放置在屏幕底部。
限制其不离开屏幕。

4、得分机制与碰撞处理
python
def on_on_overlap(sprite, otherSprite):
   if sprite.x > otherSprite.x - 2 and sprite.x < otherSprite.x + 2:
       if sitting > 300:
           otherSprite.say("nope", 200)
           sprite.vy = sprite.vy * -2
       else:
           normalScore = abs(sprite.vx)
           otherSprite.say(str(normalScore), 200)
           info.set_score(info.score() + normalScore)
           sprite.destroy()
   elif sprite.x <= otherSprite.x:
       sprite.vx = sprite.vx * -2
   else:
       sprite.vx = sprite.vx * 2
当球与桶重叠时:
如果桶长时间未移动(sitting > 300),球弹回并显示“nope”。
否则,根据球的水平速度 vx 计算得分。
球被销毁,得分显示在桶上方。
如果碰撞位置偏左或偏右,球会反弹或加速。

5、 倒计时结束处理
python
def on_countdown_end():
   playing = False
   game.over(False)
游戏时间结束后,游戏失败。

6、球销毁后自动补球
python
def on_on_destroyed(sprite2):
   ...
   makeBouncer()
当球被销毁时,从列表中移除,并补充一个新球。

7、控制器启动游戏
python
def on_a_pressed():
   makeBouncer()
   info.start_countdown(60)

def on_b_pressed():
   for i in range(10):
       makeBouncer()
   info.start_countdown(30)
按 A 键:生成 1 个球,游戏时间 60 秒。
按 B 键:生成 10 个球,游戏时间 30 秒。

8、生成弹跳球函数
python
def makeBouncer():
   ballChoice = randint(0, 2)
   bouncer = sprites.create(balls[ballChoice], SpriteKind.Ball)
   bouncer.set_flag(SpriteFlag.AUTO_DESTROY, True)
   bouncer.x = randint(0, scene.screen_width() / 4)
   bouncer.y = randint(0, scene.screen_height() / 3)
   bouncer.vx = 10 + ballChoice * 10
   bouncer.ay = 100
随机选择一种球图像。
设置初始位置、速度和重力加速度。

9、玩家移动与静止检测
python
def on_on_update():
   moveX = controller.dx()
   if moveX != 0:
       sitting = 0
       catcher.x += moveX
玩家通过方向键移动桶。
如果桶移动了,sitting 重置为 0。

10、球反弹逻辑与静止计数
python
def on_update_interval():
   for bouncer in bouncers:
       if bouncer.bottom >= scene.screen_height() and bouncer.vy > 0:
           bouncer.vy = bouncer.vy * -1
           bouncer.ay += 20
   sitting += 1
每 10 毫秒检查球是否触底并反弹。
增加重力加速度使球更难接。
增加 sitting 计数,用于判断桶是否长时间未动。

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

 

00219--.gif
00219---.gif


实验场景记录

 

182 (1).jpg
182 (2).jpg
183 (1).jpg
183 (2).jpg

评论

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