【花雕动手做】基于Kitronik可编程开发板之Boss 冲刺游戏
Kitronik ARCADE 是一款由英国教育科技公司 Kitronik 精心打造的可编程游戏机开发板,专为编程教学与创客实践而设计。该设备原生支持微软的 MakeCode Arcade 平台,用户可通过图形化或 JavaScript 编程方式,轻松创建、下载并运行复古风格的街机游戏。它集成了彩色 LCD 显示屏、方向控制键、功能按键、蜂鸣器和震动马达等交互组件,提供完整的游戏输入输出体验。无论是初学者进行编程启蒙,还是创客群体开发交互式作品,Kitronik ARCADE 都能作为理想的硬件载体,助力创意实现。
凭借其开源友好、易于上手、兼容性强等特点,该开发板广泛应用于中小学编程课程、创客工作坊、游戏开发教学以及个人项目原型设计,深受教育者与技术爱好者的喜爱。
【花雕动手做】基于Kitronik可编程开发板之Boss 冲刺游戏
作为学习、练习与尝试,这里创建一个Boss 冲刺的小游戏。打开网页版:https://arcade.makecode.com/,设置项目名称:Boss 冲刺
MicroPython实验代码
@namespace
class SpriteKind:
Boss = SpriteKind.create()
BossProjectile = SpriteKind.create()
Camera = SpriteKind.create()
"""
BERTHA
"""
"""
DARYL
"""
def createBoss(current: number):
global bossSpeed, bossHealth, timeBetweenBossFire, timeBetweenBossMove, theBoss, cameraSpeed, lastBossFireTime, bossHealthThreshold, bossLocations, currentFireIndex, darylHorizontalSpeed
if current == 0:
bossSpeed = 50
bossHealth = 100
timeBetweenBossFire = 100
timeBetweenBossMove = 2000
theBoss = sprites.create(img("""
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
cccccccccccccccccccccccc
"""),
SpriteKind.Boss)
theBoss.set_position(145, 58)
theBoss.set_velocity(0, 50)
resetHealth()
elif current == 1:
if bossHealth == 0:
bossHealth = 100
resetHealth()
cameraSpeed = 20
theBoss = sprites.create(img("""
b b b b b
b b b b b
b b b b b
b b b b b
b b b b b
"""),
SpriteKind.Boss)
theBoss.set_flag(SpriteFlag.GHOST_THROUGH_WALLS, True)
theBoss.set_position(12, 59)
lastBossFireTime = game.runtime()
animation.run_image_animation(theBoss,
[img("""
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
"""),
img("""
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
"""),
img("""
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
"""),
img("""
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
"""),
img("""
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
"""),
img("""
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
................
"""),
img("""
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
6666666666666666
""")],
150,
False)
statusbar.set_color(6, 1)
initialize_camera()
elif current == 2:
bossHealth = 50
bossHealthThreshold = bossHealth / 3
tiles.set_tilemap(tilemap("""
level6
"""))
tiles.place_on_tile(thePlayer, tiles.get_tile_location(2, 2))
bossLocations = tiles.get_tiles_by_type(assets.tile("""
tile3
"""))
currentFireIndex = 0
lastBossFireTime = game.runtime()
statusbar.set_color(4, 1)
resetHealth()
initialize_chase()
elif current == 3:
bossHealth = 100
darylHorizontalSpeed = 60
tiles.set_tilemap(tilemap("""
level7
"""))
theBoss = sprites.create(assets.image("""
daryl
"""), SpriteKind.Boss)
theBoss.ay = gravity
theBoss.right = 155
statusbar.set_color(8, 1)
resetHealth()
else:
create_final_boss()
def initialize_chase():
global bossSpawn, theBoss, lastBossFireTime
bossSpawn = bossLocations.shift()
theBoss = sprites.create(img("""
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
5 5 5 5 5 5 5 5 5 5 5
"""),
SpriteKind.Boss)
tiles.place_on_tile(theBoss, bossSpawn)
animation.run_image_animation(theBoss,
assets.animation("""
chase animation
"""),
150,
True)
theBoss.lifespan = 4000
bossLocations.append(bossSpawn)
lastBossFireTime += 2000
def clearStage():
theBoss.destroy()
for value in sprites.all_of_kind(SpriteKind.BossProjectile):
value.destroy()
for value2 in sprites.all_of_kind(SpriteKind.projectile):
value2.destroy()
for value22 in sprites.all_of_kind(SpriteKind.Camera):
value22.destroy()
def darylThrow(dir2: number):
global projectile
theBoss.say("Daryl Throw!", 500)
pause(500)
projectile = sprites.create_projectile_from_sprite(assets.image("""
daryl projectile
"""),
theBoss,
2 * (dir2 * darylHorizontalSpeed),
0)
projectile.set_kind(SpriteKind.BossProjectile)
projectile = sprites.create_projectile_from_sprite(assets.image("""
daryl projectile
"""),
theBoss,
2 * (dir2 * darylHorizontalSpeed),
-74)
projectile.set_kind(SpriteKind.BossProjectile)
pause(500)
def resetHealth():
statusbar.max = bossHealth
statusbar.value = bossHealth
def darylDash(dir3: number):
theBoss.say("Daryl Dash!", 500)
pause(500)
theBoss.vx = 2 * (dir3 * darylHorizontalSpeed)
pause(200)
def on_on_overlap(sprite, otherSprite):
global bossHealth, timeBetweenBossMove, bossSpeed
sprite.destroy(effects.disintegrate, 10)
bossHealth += -1
statusbar.value += -1
if bossHealth == 0:
next_boss()
elif bossHealth == 50 and currentBoss == 0:
timeBetweenBossMove = 1000
bossSpeed = 100
sprites.on_overlap(SpriteKind.projectile, SpriteKind.Boss, on_on_overlap)
def on_a_pressed():
if thePlayer.is_hitting_tile(CollisionDirection.BOTTOM):
thePlayer.vy = jumpVelocity
controller.A.on_event(ControllerButtonEvent.PRESSED, on_a_pressed)
# CHASE
def on_on_destroyed(sprite2):
if currentBoss == 2 and bossHealth > 0:
initialize_chase()
sprites.on_destroyed(SpriteKind.Boss, on_on_destroyed)
def darylJump(dir4: number):
theBoss.say("Daryl Jump!", 500)
pause(500)
theBoss.vy = Math.random_range(1.5 * jumpVelocity, jumpVelocity)
theBoss.vx = dir4 * darylHorizontalSpeed
def on_on_overlap2(sprite3, otherSprite2):
sprite3.destroy(effects.disintegrate, 10)
info.change_life_by(-1)
sprites.on_overlap(SpriteKind.BossProjectile, SpriteKind.player, on_on_overlap2)
def initialize_camera():
global camera_target
camera_target = sprites.create(img("""
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . 3 3 . . . . . . .
. . . . . . . 3 3 . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . .
"""),
SpriteKind.Camera)
camera_target.set_flag(SpriteFlag.GHOST, True)
camera_target.set_flag(SpriteFlag.INVISIBLE, True)
camera_target.set_velocity(cameraSpeed, 0)
scene.camera_follow_sprite(camera_target)
def on_overlap_tile(sprite4, location):
clearStage()
createBoss(currentBoss)
tiles.place_on_tile(thePlayer, tiles.get_tile_location(7, 4))
scene.on_overlap_tile(SpriteKind.player,
assets.tile("""
tile2
"""),
on_overlap_tile)
def on_on_overlap3(sprite5, otherSprite3):
if currentBoss == 1:
sprite5.destroy(effects.disintegrate, 10)
sprites.change_data_number_by(otherSprite3, "health", -1)
if sprites.read_data_number(otherSprite3, "health") == 8:
otherSprite3.image.replace(5, 4)
elif sprites.read_data_number(otherSprite3, "health") == 4:
otherSprite3.image.replace(4, 2)
elif sprites.read_data_number(otherSprite3, "health") == 0:
otherSprite3.destroy()
sprites.on_overlap(SpriteKind.projectile,
SpriteKind.BossProjectile,
on_on_overlap3)
def on_on_overlap4(sprite6, otherSprite4):
if currentBoss == 1:
if game.runtime() > lastBossFireTime + 1000:
info.change_life_by(-1)
camera_target.vx = cameraSpeed / 4
scene.camera_shake(4, 500)
pause(1000)
camera_target.vx = cameraSpeed
else:
info.change_life_by(-1)
pause(500)
sprites.on_overlap(SpriteKind.player, SpriteKind.Boss, on_on_overlap4)
projectile2: Sprite = None
darylDir = 0
chosenAction = 0
fireAngle = 0
isBossAttacking = False
lastFireTime = 0
isFacingLeft = False
camera_target: Sprite = None
projectile: Sprite = None
bossSpawn: tiles.Location = None
darylHorizontalSpeed = 0
currentFireIndex = 0
bossLocations: List = []
bossHealthThreshold = 0
lastBossFireTime = 0
cameraSpeed = 0
theBoss: Sprite = None
timeBetweenBossMove = 0
timeBetweenBossFire = 0
bossHealth = 0
bossSpeed = 0
statusbar: StatusBarSprite = None
currentBoss = 0
thePlayer: Sprite = None
jumpVelocity = 0
gravity = 0
tiles.set_tilemap(tilemap("""
level5
"""))
gravity = 300
jumpHeight = 34
playerSpeed = 100
projectileVelocity = 150
timeBetweenFire = 100
jumpVelocity = 0 - Math.sqrt(2 * (gravity * jumpHeight))
thePlayer = sprites.create(assets.image("""
player character
"""),
SpriteKind.player)
thePlayer.ay = gravity
controller.move_sprite(thePlayer, playerSpeed, 0)
info.set_life(10)
currentBoss = 0
statusbar = statusbars.create(100, 11, StatusBarKind.health)
statusbar.set_color(12, 1)
statusbar.set_bar_border(1, 3)
statusbar.right = 160
statusbar.top = 0
statusbar.set_flag(SpriteFlag.RELATIVE_TO_CAMERA, True)
createBoss(currentBoss)
def on_on_update():
global isFacingLeft, projectile, lastFireTime
if thePlayer.vx < 0:
isFacingLeft = True
elif thePlayer.vx > 0:
isFacingLeft = False
if controller.B.is_pressed():
if game.runtime() > lastFireTime + timeBetweenFire:
if controller.up.is_pressed():
projectile = sprites.create_projectile_from_sprite(assets.image("""
player projectile
"""),
thePlayer,
0,
0 - projectileVelocity)
elif isFacingLeft:
projectile = sprites.create_projectile_from_sprite(assets.image("""
player projectile
"""),
thePlayer,
0 - projectileVelocity,
0)
else:
projectile = sprites.create_projectile_from_sprite(assets.image("""
player projectile
"""),
thePlayer,
projectileVelocity,
0)
projectile.vx += thePlayer.vx
lastFireTime = game.runtime()
game.on_update(on_on_update)
def on_on_update2():
global projectile, lastBossFireTime, fireAngle, currentFireIndex
if currentBoss == 0:
if isBossAttacking:
if game.runtime() > lastBossFireTime + timeBetweenBossFire:
projectile = sprites.create_projectile_from_sprite(assets.image("""
albert projectile
"""),
theBoss,
-75,
0)
projectile.set_kind(SpriteKind.BossProjectile)
projectile.y += Math.random_range(-16, 16)
lastBossFireTime = game.runtime()
elif currentBoss == 1:
theBoss.left = scene.camera_left() + 12
theBoss.y = Math.map(Math.sin(game.runtime() / 1000),
-1,
1,
32,
scene.screen_height() - 32)
elif currentBoss == 2:
if game.runtime() > lastBossFireTime + timeBetweenBossFire:
animation.stop_animation(animation.AnimationTypes.ALL, theBoss)
theBoss.set_image(assets.image("""
chase
"""))
if bossHealth > bossHealthThreshold:
fireAngle = 0.7854 / 2 * currentFireIndex
projectile = sprites.create_projectile_from_sprite(assets.image("""
chase projectile
"""),
theBoss,
Math.cos(fireAngle) * projectileVelocity,
Math.sin(fireAngle) * projectileVelocity)
currentFireIndex += 1
projectile.set_kind(SpriteKind.BossProjectile)
else:
for index in range(8):
fireAngle = 0.7854 * index
projectile = sprites.create_projectile_from_sprite(assets.image("""
chase projectile
"""),
theBoss,
Math.cos(fireAngle) * projectileVelocity,
Math.sin(fireAngle) * projectileVelocity)
projectile.set_kind(SpriteKind.BossProjectile)
lastBossFireTime = game.runtime()
else:
pass
game.on_update(on_on_update2)
def on_on_update3():
if currentBoss == 1:
if thePlayer.right + 16 < scene.camera_left():
clearStage()
createBoss(currentBoss)
tiles.place_on_tile(thePlayer, tiles.get_tile_location(7, 4))
game.on_update(on_on_update3)
def on_forever():
global isBossAttacking, chosenAction, darylDir
if currentBoss == 0:
if theBoss.is_hitting_tile(CollisionDirection.BOTTOM) or theBoss.is_hitting_tile(CollisionDirection.TOP):
isBossAttacking = True
pause(timeBetweenBossMove)
isBossAttacking = False
if theBoss.is_hitting_tile(CollisionDirection.BOTTOM):
theBoss.vy = 0 - bossSpeed
else:
theBoss.vy = bossSpeed
pause(100)
elif currentBoss == 3:
if theBoss.is_hitting_tile(CollisionDirection.BOTTOM):
theBoss.vx = 0
chosenAction = Math.random_range(0, 2)
darylDir = 1
if thePlayer.x < theBoss.x:
darylDir = -1
if chosenAction == 0:
darylThrow(darylDir)
elif chosenAction == 1:
darylDash(darylDir)
else:
darylJump(darylDir)
forever(on_forever)
def on_update_interval():
global projectile2
if currentBoss == 1:
projectile2 = sprites.create_projectile_from_sprite(assets.image("""
bertha projectile
"""),
theBoss,
10,
0)
projectile2.set_kind(SpriteKind.BossProjectile)
projectile2.follow(thePlayer, 35)
sprites.set_data_number(projectile2, "health", 12)
game.on_update_interval(3000, on_update_interval)
【花雕动手做】基于Kitronik可编程开发板之Boss 冲刺游戏
图形编程参考实验程序通过模拟器,调试与模拟运行
实验场景记录
【花雕动手做】基于Kitronik可编程开发板之Boss 冲刺游戏
页:
[1]