驴友花雕 发表于 4 天前

【花雕动手做】基于 Kitronik 可编程开发板之红色弹球

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

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

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







驴友花雕 发表于 4 天前

【花雕动手做】基于 Kitronik 可编程开发板之红色弹球


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

MicroPython实验参考代码




@namespace
class SpriteKind:
    Projectile2 = SpriteKind.create()
    snake = SpriteKind.create()

def on_on_overlap(sprite, otherSprite):
    global falling
    falling = sprites.create(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 . .
            """),
      SpriteKind.projectile)
    falling.set_bounce_on_wall(True)
    falling.set_position(sprite.x, sprite.y - 5)
    falling.set_velocity(sprite.vx, 0 - sprite.vy)
    falling.ay = sprite.ay
    sprite.destroy()
sprites.on_overlap(SpriteKind.Projectile2, SpriteKind.player, on_on_overlap)

def on_on_overlap2(sprite2, otherSprite2):
    info.set_score(info.score() + 1)
    sprite2.destroy()
sprites.on_overlap(SpriteKind.projectile, SpriteKind.player, on_on_overlap2)

def on_hit_wall(sprite3, location):
    if tiles.tile_at_location_equals(location, assets.tile("""
      tile3
      """)):
      info.change_life_by(-1)
      sprite3.destroy()
scene.on_hit_wall(SpriteKind.Projectile2, on_hit_wall)

def on_hit_wall2(sprite4, location2):
    if tiles.tile_at_location_equals(location2, assets.tile("""
      tile3
      """)):
      info.change_life_by(-1)
      sprite4.destroy()
scene.on_hit_wall(SpriteKind.projectile, on_hit_wall2)

limit = 0
falling: Sprite = None
s4Dir = 1
info.set_life(3)
basket = sprites.create(img("""
      . . . . . . . . . . . . . . . .
      . . . . . . . . . . . . . . . .
      . . . . . . . . . . . . . . . .
      . . . . . . . . . . . . . . . .
      . . . . . . . . . . . . . . . .
      . . 7 7 7 7 7 7 7 7 7 7 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 1 7 1 7 1 7 1 7 1 7 . . .
      . . 7 7 7 7 7 7 7 7 7 7 7 . . .
      . . . . . . . . . . . . . . . .
      """),
    SpriteKind.player)
basket.set_position(80, 100)
controller.move_sprite(basket, 160, 0)
mySprite4 = sprites.create(img("""
      . . . . . . . . . . . . . . . .
      . 8 8 8 8 8 8 8 1 1 1 1 1 . . .
      8 8 8 8 8 8 8 8 1 1 1 1 1 1 . .
      8 8 8 8 8 8 8 8 1 1 1 1 1 1 . .
      8 8 8 8 8 8 8 8 1 1 1 1 1 1 . .
      8 8 8 8 8 1 8 8 1 1 1 1 1 1 . .
      8 8 8 8 8 1 1 8 1 1 1 1 1 1 . .
      8 8 8 8 8 1 1 1 1 1 1 1 1 1 . .
      8 8 8 8 8 1 1 1 1 1 1 1 1 1 . .
      8 8 8 8 8 1 1 8 1 1 1 1 1 1 . .
      8 8 8 8 8 1 8 8 1 1 1 1 1 1 . .
      8 8 8 8 8 8 8 8 1 1 1 1 1 1 . .
      8 8 8 8 8 8 8 8 1 1 1 1 1 1 . .
      . 8 8 8 8 8 8 8 1 1 1 1 1 . . .
      . . . 8 8 8 . . . . . . . . . .
      . . . . . . . . . . . . . . . .
      """),
    SpriteKind.snake)
mySprite4.set_flag(SpriteFlag.GHOST, True)
mySprite4.set_position(-7, 100)
tiles.set_tilemap(tilemap("""
    level
    """))

def on_update_interval():
    global s4Dir
    mySprite4.vx = 10 * s4Dir
    s4Dir = s4Dir * -1
game.on_update_interval(2200, on_update_interval)

def on_update_interval2():
    global falling, limit
    if info.score() < 10 or randint(1, min(50, info.score())) < 10:
      falling = sprites.create(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 . .
                """),
            SpriteKind.projectile)
    else:
      falling = sprites.create(img("""
                . . 8 8 8 8 . .
                . 8 8 8 8 8 8 .
                8 8 8 8 8 8 8 8
                8 8 8 8 8 8 8 8
                8 8 8 8 8 8 8 8
                8 8 8 8 8 8 8 8
                . 8 8 8 8 8 8 .
                . . 8 8 8 8 . .
                """),
            SpriteKind.Projectile2)
    falling.set_position(randint(20, 140), 20)
    limit = min(10, info.score())
    falling.set_velocity(randint(-100, 100), randint(0 - limit, 5))
    falling.ay = 20
    falling.set_bounce_on_wall(True)
game.on_update_interval(2000, on_update_interval2)


驴友花雕 发表于 4 天前

【花雕动手做】基于 Kitronik 可编程开发板之红色弹球

这是一个弹球收集游戏,玩家控制底部的篮子接住从上方落下的弹球。游戏包含两种弹球:普通弹球(得分)和特殊弹球(需要反弹处理)。玩家有3条生命,碰到危险墙壁会失去生命。

核心代码解析

1. 自定义精灵类型
python
@namespace

class SpriteKind:

    Projectile2 = SpriteKind.create()# 特殊弹球(需要反弹)

    snake = SpriteKind.create()         # 蛇形障碍物

2. 碰撞检测系统
特殊弹球与玩家碰撞
python
def on_on_overlap(sprite, otherSprite):

    global falling

    falling = sprites.create(img("""新弹球"""), SpriteKind.projectile)

    falling.set_bounce_on_wall(True)

    falling.set_position(sprite.x, sprite.y - 5)

    falling.set_velocity(sprite.vx, 0 - sprite.vy)# 速度反向

    falling.ay = sprite.ay# 保持相同的重力加速度

    sprite.destroy()# 销毁原弹球
当特殊弹球(Projectile2)碰到玩家篮子时

创建一个新的普通弹球,位置略高于原弹球

设置反弹速度(垂直方向反向)

保持相同的重力加速度

销毁原特殊弹球

普通弹球与玩家碰撞
python
def on_on_overlap2(sprite2, otherSprite2):

    info.set_score(info.score() + 1)# 得分+1

    sprite2.destroy()# 销毁弹球
当普通弹球碰到玩家篮子时

玩家得分增加1分

销毁弹球

弹球碰到危险墙壁
python
def on_hit_wall(sprite3, location):

    if tiles.tile_at_location_equals(location, assets.tile("tile3")):

      info.change_life_by(-1)# 生命值-1

      sprite3.destroy()# 销毁弹球
当特殊弹球碰到特定瓦片(tile3)时

玩家失去1条生命

销毁弹球

python
def on_hit_wall2(sprite4, location2):

    if tiles.tile_at_location_equals(location2, assets.tile("tile3")):

      info.change_life_by(-1)# 生命值-1

      sprite4.destroy()# 销毁弹球
当普通弹球碰到特定瓦片(tile3)时

玩家失去1条生命

销毁弹球

3. 游戏初始化
玩家设置
python
info.set_life(3)# 设置3条生命

basket = sprites.create(img("""篮子图像"""), SpriteKind.player)

basket.set_position(80, 100)# 底部中央位置

controller.move_sprite(basket, 160, 0)# 只能水平移动
玩家有3条生命

创建篮子精灵,使用ASCII艺术定义外观

将篮子放置在屏幕底部中央

设置只能水平移动(速度160)

蛇形障碍物
python
mySprite4 = sprites.create(img("""蛇图像"""), SpriteKind.snake)

mySprite4.set_flag(SpriteFlag.GHOST, True)# 设置为幽灵模式(无碰撞)

mySprite4.set_position(-7, 100)# 初始位置在左侧外部
创建蛇形障碍物,但设置为幽灵模式(不参与碰撞检测)

初始位置在屏幕左侧外部

游戏场景
python
tiles.set_tilemap(tilemap("level"))# 设置瓦片地图
使用名为"level"的瓦片地图

4. 游戏循环与更新
蛇形障碍物移动
python
def on_update_interval():

    global s4Dir

    mySprite4.vx = 10 * s4Dir# 设置水平速度

    s4Dir = s4Dir * -1# 方向反转

game.on_update_interval(2200, on_update_interval)# 每2200ms更新一次
蛇形障碍物每2.2秒改变一次移动方向

在左右方向之间来回移动

弹球生成系统
python
def on_update_interval2():

    global falling, limit

    if info.score() < 10 or randint(1, min(50, info.score())) < 10:

      falling = sprites.create(img("""红色弹球"""), SpriteKind.projectile)# 普通弹球

    else:

      falling = sprites.create(img("""蓝色弹球"""), SpriteKind.Projectile2)# 特殊弹球

   

    falling.set_position(randint(20, 140), 20)# 随机水平位置,顶部

    limit = min(10, info.score())# 根据得分限制速度范围

    falling.set_velocity(randint(-100, 100), randint(0 - limit, 5))# 随机速度

    falling.ay = 20# 重力加速度

    falling.set_bounce_on_wall(True)# 开启墙壁反弹

game.on_update_interval(2000, on_update_interval2)# 每2000ms生成一个弹球
每2秒生成一个新的弹球

根据得分决定生成普通弹球还是特殊弹球:

得分低于10时,主要生成普通弹球

得分高于10时,有概率生成特殊弹球

弹球从顶部随机位置生成

弹球具有随机速度和方向

设置重力加速度使弹球下落

开启墙壁反弹功能

游戏机制总结
控制方式:左右移动篮子接住弹球

得分系统:接住普通弹球得1分

生命系统:初始3条生命,弹球碰到危险墙壁失去1条生命

弹球类型:

普通弹球:直接得分

特殊弹球:需要反弹后才能接住

难度递增:随着得分增加,出现更多特殊弹球

技术特点
动态难度:根据玩家得分调整弹球类型和速度

物理模拟:使用速度、重力和反弹模拟弹球运动

瓦片地图:使用瓦片地图定义游戏场景和危险区域

幽灵模式:蛇形障碍物使用幽灵模式避免不必要的碰撞

驴友花雕 发表于 4 天前

【花雕动手做】基于 Kitronik 可编程开发板之红色弹球

图形编程参考实验程序


驴友花雕 发表于 4 天前

【花雕动手做】基于 Kitronik 可编程开发板之红色弹球

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



实验场景记录








驴友花雕 发表于 4 天前

【花雕动手做】基于 Kitronik 可编程开发板之红色弹球


页: [1]
查看完整版本: 【花雕动手做】基于 Kitronik 可编程开发板之红色弹球