Lösung v01/v02
from microbit import *
import random
import time
def rand_x():
return random.randint(0,4)
AST_DELAY = 500
player_x = 2
ast_x = rand_x()
ast_y = 0
t0 = time.ticks_ms()
while True:
t1 = time.ticks_ms()
print(t1)
# update asteroid
if t1 - t0 > AST_DELAY:
if ast_y < 4:
ast_y += 1
else:
ast_x = rand_x()
ast_y = 0
t0 = t1
# update player
if button_a.get_presses() and player_x > 0:
player_x -= 1
elif button_b.get_presses() and player_x < 4:
player_x += 1
# collision check
if ast_y == 4 and ast_x == player_x:
display.show(Image.ANGRY)
break
# update display
display.clear()
display.set_pixel(player_x,4,9)
display.set_pixel(ast_x,ast_y,5)
sleep(10)
Lösung v03
from microbit import *
import random
import time
# CONSTANT
N_X = 5 # nr pixels in x direction
N_Y = 5 # nr pixels in x direction
ASTEROID_DELAY = 300
ASTEROID_BRIGHTNESS = 5
PLAYER_BRIGHTNESS = 9
SLEEP_TIME_MS = 20
# VARIABLES
player_x = 2
asteroid_x = random.randint(0,N_X-1)
asteroid_y = 0
game_over = False
time_last_update = time.ticks_ms()
while True:
# get current time
time_current = time.ticks_ms()
# update asteroid position
if time_current - time_last_update > ASTEROID_DELAY:
asteroid_y += 1
if asteroid_y >= N_Y:
asteroid_x, asteroid_y = random.randint(0,N_X-1), 0
time_last_update = time_current
# update player (button presses)
if button_a.get_presses() and player_x > 0:
player_x -= 1
elif button_b.get_presses() and player_x < N_X-1:
player_x += 1
# collision check
if asteroid_y == N_Y-1 and asteroid_x == player_x:
game_over = True
# update display
display.clear()
if game_over:
display.show(Image.ANGRY)
break
display.set_pixel(player_x,4,PLAYER_BRIGHTNESS)
display.set_pixel(asteroid_x,asteroid_y,ASTEROID_BRIGHTNESS)
# short sleep
sleep(SLEEP_TIME_MS)
Lösung v04
- asteroids_v04a.py
from microbit import *
import random
import time
# CONSTANTS
N_X = 5 # nr pixels in x direction
N_Y = 5 # nr pixels in x direction
ASTEROID_DELAY_MAX = 500
ASTEROID_DELAY_MIN = 100
ASTEROID_DELAY_DELTA = 50
TIME_LEVEL_UPDATE = 3000
ASTEROID_BRIGHTNESS = 5
PLAYER_BRIGHTNESS = 9
SLEEP_TIME_MS = 20
GAME_OVER_TIME = 1000
IMAGE_GAME_OVER = Image.ANGRY
# VARIABLES
player_x = N_X // 2
asteroid_x = random.randint(0,N_X-1)
asteroid_y = 0
asteroid_delay = ASTEROID_DELAY_MAX
game_over = False
level = 1
time_last_asteroid_update = time.ticks_ms()
time_last_level_update = time.ticks_ms()
# GAME LOOP
while True:
# get current time
t1 = time.ticks_ms()
# update level
if t1 - time_last_level_update > TIME_LEVEL_UPDATE:
if asteroid_delay > ASTEROID_DELAY_MIN: # speed up game
asteroid_delay -= ASTEROID_DELAY_DELTA
else: # avoid negative times
asteroid_delay = ASTEROID_DELAY_MIN
level += 1
time_last_level_update = t1
# update asteroid position
if t1 - time_last_asteroid_update > asteroid_delay:
if asteroid_y < N_Y-1:
asteroid_y += 1
else:
asteroid_x = random.randint(0,N_X-1)
asteroid_y = 0
time_last_asteroid_update = t1
# update player (button presses)
if button_a.get_presses() and player_x > 0:
player_x -= 1
elif button_b.get_presses() and player_x < N_X-1:
player_x += 1
# collision check
if asteroid_y == N_Y-1 and asteroid_x == player_x:
game_over = True
# update display
display.clear()
if game_over:
display.show(IMAGE_GAME_OVER)
sleep(GAME_OVER_TIME) # wait before can reset
display.scroll("Level: " + str(level))
display.show(Image.ANGRY)
while True:
# reset game (not great because is copy paste from above)
if button_a.get_presses() or button_b.get_presses():
player_x = N_X // 2
asteroid_x = random.randint(0,N_X-1)
asteroid_y = 0
asteroid_delay = ASTEROID_DELAY_MAX
game_over = False
time_last_asteroid_update = time.ticks_ms()
time_last_level_update = time.ticks_ms()
break
else:
display.set_pixel(player_x,N_Y-1,PLAYER_BRIGHTNESS)
display.set_pixel(asteroid_x,asteroid_y,ASTEROID_BRIGHTNESS)
# short sleep
sleep(SLEEP_TIME_MS)
An der Version oben ist unschön, dass die Anfangsbedingungen des Spiels beim Game Over copy-pasted werden müssen. Die Version unten umgeht dieses Problem.
- asteroids_v04b.py
from microbit import *
import random
import time
# CONSTANT
N_X = 5 # nr pixels in x direction
N_Y = 5 # nr pixels in x direction
ASTEROID_DELAY_MAX = 500
ASTEROID_DELAY_MIN = 100
ASTEROID_DELAY_DELTA = 50
TIME_LEVEL_UPDATE = 2000
GAME_OVER_SLEEP = 2000
IMAGE_GAME_OVER = Image.ANGRY
ASTEROID_BRIGHTNESS = 5
PLAYER_BRIGHTNESS = 9
SLEEP_TIME_MS = 20
def game():
# VARIABLES
player_x = N_X // 2
asteroid_x = random.randint(0,N_X-1)
asteroid_y = 0
asteroid_delay = ASTEROID_DELAY_MAX
t0 = time.ticks_ms()
time_last_asteroid_update = t0
time_last_level_update = t0
level = 1
# GAME LOOP
while True:
# get current time
t1 = time.ticks_ms()
# update level
if t1 - time_last_level_update > TIME_LEVEL_UPDATE:
if asteroid_delay > ASTEROID_DELAY_MIN:
asteroid_delay -= ASTEROID_DELAY_DELTA
else:
asteroid_delay = ASTEROID_DELAY_MIN
level += 1
time_last_level_update = t1
# update asteroid position
if t1 - time_last_asteroid_update > asteroid_delay:
if asteroid_y < N_Y-1:
asteroid_y += 1
else:
asteroid_x = random.randint(0,N_X-1)
asteroid_y = 0
time_last_asteroid_update = t1
# update player (button presses)
if button_a.get_presses() and player_x > 0:
player_x -= 1
elif button_b.get_presses() and player_x < N_X-1:
player_x += 1
# collision check
if asteroid_y == N_Y-1 and asteroid_x == player_x:
return level
# update display
display.clear()
display.set_pixel(player_x,N_Y-1,PLAYER_BRIGHTNESS)
display.set_pixel(asteroid_x,asteroid_y,ASTEROID_BRIGHTNESS)
# short sleep
sleep(SLEEP_TIME_MS)
def game_over(level):
display.show(IMAGE_GAME_OVER)
sleep(GAME_OVER_SLEEP)
display.scroll("Level: " + str(level))
display.show(IMAGE_GAME_OVER)
while True: # restart
if button_a.get_presses() or button_b.get_presses():
return
while True:
level = game()
game_over(level)
Lösung v05
from microbit import *
import random
import time
# CONSTANT
N_X = 5 # nr pixels in x direction
N_Y = 5 # nr pixels in x direction
#ASTEROID_DELAY_MAX = 500
#ASTEROID_DELAY_MIN = 100
#ASTEROID_DELAY_DELTA = 50
#TIME_LEVEL_UPDATE = 2000
TIME_ASTEROID_UPDATE = 500
TIME_ASTEROID_SPAWN = 300
ASTEROID_SPAWN_PROBABILITY = 30 # in percent
ASTEROID_BRIGHTNESS = 5
PLAYER_BRIGHTNESS = 9
SLEEP_TIME_MS = 20
class Asteroid:
def __init__(self):
self.x = random.randint(0,N_X-1)
self.y = 0
self.delay = random.randint(300,1000)
self.brightness = ASTEROID_BRIGHTNESS
self.time_update = TIME_ASTEROID_UPDATE
self.time_last_update = time.ticks_ms()
def __del__(self):
print("asteroid destroyed")
def update(self):
t1 = time.ticks_ms()
if t1 - self.time_last_update > self.time_update:
self.y += 1
self.time_last_update = t1
def game():
# VARIABLES
player_x = N_X // 2
t0 = time.ticks_ms()
time_last_asteroid_update = t0
time_last_asteroid_spawn_slot = t0
level = 1
asteroids = [Asteroid()]
while True:
# get current time
t1 = time.ticks_ms()
# create new asteroids
if t1 - time_last_asteroid_spawn_slot > TIME_ASTEROID_SPAWN:
if random.randint(1,100) <= ASTEROID_SPAWN_PROBABILITY:
asteroids.append(Asteroid())
time_last_asteroid_spawn_slot = t1
# update asteroid positions
for asteroid in asteroids:
asteroid.update()
if asteroid.y >= N_Y:
asteroids.remove(asteroid)
# update player (button presses)
if button_a.get_presses() and player_x > 0:
player_x -= 1
elif button_b.get_presses() and player_x < N_X-1:
player_x += 1
# collision check
for asteroid in asteroids:
if asteroid.y == N_Y-1 and asteroid.x == player_x:
return level
# update display
display.clear()
display.set_pixel(player_x,N_Y-1,PLAYER_BRIGHTNESS)
for asteroid in asteroids:
display.set_pixel(asteroid.x,asteroid.y,asteroid.brightness)
# short sleep
sleep(SLEEP_TIME_MS)
def game_over(level):
display.show(Image.ANGRY)
sleep(2000)
display.scroll("Level: " + str(level))
display.show(Image.ANGRY)
while True:
if button_a.get_presses() or button_b.get_presses():
return
while True:
level = game()
game_over(level)
Lösung v06
from microbit import *
import random
import time
# CONSTANT
N_X = 5 # nr pixels in x direction
N_Y = 5 # nr pixels in x direction
TIME_ASTEROID_UPDATE_MIN = 300
TIME_ASTEROID_UPDATE_MAX = 2000
TIME_ASTEROID_SPAWN = 300
TIME_LEVEL = 1000
ASTEROID_SPAWN_PROBABILITY = 30 # in percent
ASTEROID_BRIGHTNESS = 5
PLAYER_BRIGHTNESS = 9
SLEEP_TIME_MS = 11
class Player:
def __init__(self):
self.x = N_X // 2
self.y = N_Y - 1
self.brightness = PLAYER_BRIGHTNESS
def update(self,move):
self.x += move
if self.x < 0:
self.x = 0
elif self.x >= N_X - 1:
self.x = N_X - 1
def display(self):
display.set_pixel(self.x,self.y,self.brightness)
class Asteroid:
def __init__(self):
self.x = random.randint(0,N_X-1)
self.y = 0
self.update_time = random.randint(TIME_ASTEROID_UPDATE_MIN,TIME_ASTEROID_UPDATE_MAX)
self.brightness = ASTEROID_BRIGHTNESS
self.time_last_update = time.ticks_ms()
def update(self):
t1 = time.ticks_ms()
if t1 - self.time_last_update > self.update_time:
self.y += 1
self.time_last_update = t1
def display(self):
display.set_pixel(self.x,self.y,self.brightness)
def game():
# VARIABLES
t0 = time.ticks_ms()
time_last_asteroid_spawn_slot = t0
time_level_last_update = t0
level = 1
player = Player()
asteroids = [Asteroid()]
while True:
# get current time
t1 = time.ticks_ms()
# level
if t1 - time_level_last_update > TIME_LEVEL:
level += 1
time_level_last_update = t1
# create new asteroids
if t1 - time_last_asteroid_spawn_slot > TIME_ASTEROID_SPAWN:
if random.randint(1,100) <= ASTEROID_SPAWN_PROBABILITY:
asteroids.append(Asteroid())
time_last_asteroid_spawn_slot = t1
# update asteroid positions
for asteroid in asteroids:
asteroid.update()
if asteroid.y >= N_Y:
asteroids.remove(asteroid)
# update player (button presses)
player_move = 0
if button_a.get_presses(): player_move = -1
elif button_b.get_presses(): player_move = 1
player.update(player_move)
# collision check
for asteroid in asteroids:
if asteroid.y == N_Y-1 and asteroid.x == player.x:
return level
# update display
display.clear()
for asteroid in asteroids: asteroid.display()
player.display()
# short sleep
sleep(SLEEP_TIME_MS)
def game_over(level):
display.show(Image.ANGRY)
sleep(2000)
display.scroll("Level: " + str(level))
display.show(Image.ANGRY)
while True:
if button_a.get_presses() or button_b.get_presses():
return
while True:
level = game()
game_over(level)
Lösung v07
from microbit import *
import random
import time
import os
PLATFORM = print(os.uname()[4]) #e.g. micro:bit with nRF52833, x86_64
# CONSTANTS
N_X = 5 # nr pixels in x direction
N_Y = 5 # nr pixels in x direction
TIME_ASTEROID_UPDATE_MIN = 300
TIME_ASTEROID_UPDATE_MAX = 2000
TIME_ASTEROID_SPAWN = 300
TIME_LEVEL = 1000
ASTEROID_SPAWN_PROBABILITY = 30 # in percent
GAME_OVER_TIME_DELAY = 2000
ASTEROID_BRIGHTNESS = 5
PLAYER_BRIGHTNESS = 9
SLEEP_TIME_MS = 11
# CLASSES
class Sprite:
def __init__(self,_x,_y,_brightness):
self.x = _x
self.y = _y
self.brightness = _brightness
def display(self):
display.set_pixel(self.x,self.y,self.brightness)
class Player(Sprite):
def __init__(self,_x,_y,_brightness):
super().__init__(_x,_y,_brightness)
def update(self,move):
self.x += move
if self.x < 0:
self.x = 0
elif self.x >= N_X - 1:
self.x = N_X - 1
class Asteroid(Sprite):
def __init__(self,_x,_y,_brightness,_update_time):
super().__init__(_x,_y,_brightness)
self.update_time = _update_time
self.time_last_update = time.ticks_ms()
def update(self):
t1 = time.ticks_ms()
if t1 - self.time_last_update > self.update_time:
self.y += 1
self.time_last_update = t1
# FUNCTIONS
def game():
# VARIABLES
t0 = time.ticks_ms()
time_last_asteroid_spawn_slot = t0
time_level_last_update = t0
level = 1
player = Player(N_X//2,N_X-1,PLAYER_BRIGHTNESS)
asteroids = []
while True:
# get current time
t1 = time.ticks_ms()
# level
if t1 - time_level_last_update > TIME_LEVEL:
level += 1
time_level_last_update = t1
# create new asteroids
if t1 - time_last_asteroid_spawn_slot > TIME_ASTEROID_SPAWN:
if random.randint(1,100) <= ASTEROID_SPAWN_PROBABILITY:
rand_ast_time = random.randint(TIME_ASTEROID_UPDATE_MIN,TIME_ASTEROID_UPDATE_MAX)
asteroids.append(Asteroid(random.randint(0,N_X-1),0,ASTEROID_BRIGHTNESS,rand_ast_time))
time_last_asteroid_spawn_slot = t1
# update asteroid positions
for asteroid in asteroids:
asteroid.update()
if asteroid.y >= N_Y: asteroids.remove(asteroid)
# update player (button presses)
player_move = 0
if button_a.get_presses(): player_move = -1
elif button_b.get_presses(): player_move = 1
player.update(player_move)
# collision check
for asteroid in asteroids:
if asteroid.y == N_Y-1 and asteroid.x == player.x: return level
# update display
display.clear()
for asteroid in asteroids: asteroid.display()
player.display()
# short sleep
sleep(SLEEP_TIME_MS)
def game_over(level):
display.show(Image.ANGRY)
sleep(GAME_OVER_TIME_DELAY)
display.scroll("Level: " + str(level))
display.show(Image.ANGRY)
while True:
if button_a.get_presses() or button_b.get_presses():
return
# MAIN LOOP
while True:
level = game()
game_over(level)
Lösung v07b
from microbit import *
import random
import time
import os
PLATFORM = print(os.uname()[4]) #e.g. micro:bit with nRF52833, x86_64
# CONSTANTS
N_X = 5 # nr pixels in x direction
N_Y = 5 # nr pixels in x direction
TIME_ASTEROID_UPDATE_MIN = 300
TIME_ASTEROID_UPDATE_MAX = 2000
TIME_ASTEROID_SPAWN = 300
TIME_LEVEL = 1000
ASTEROID_SPAWN_PROBABILITY = 30 # in percent
GAME_OVER_TIME_DELAY = 2000
IMAGE_GAME_OVER = Image.ANGRY
ASTEROID_BRIGHTNESS = 5
PLAYER_BRIGHTNESS = 9
SLEEP_TIME_MS = 11
# CLASSES
class Sprite:
def __init__(self,_x,_y,_brightness):
self.x = _x
self.y = _y
self.brightness = _brightness
def display(self):
display.set_pixel(self.x,self.y,self.brightness)
class Player(Sprite):
def __init__(self,_x,_y,_brightness):
super().__init__(_x,_y,_brightness)
def update(self,move):
self.x += move
if self.x < 0:
self.x = 0
elif self.x >= N_X - 1:
self.x = N_X - 1
class Asteroid(Sprite):
def __init__(self,_x,_y,_brightness,_update_time):
super().__init__(_x,_y,_brightness)
self.update_time = _update_time
self.time_last_update = time.ticks_ms()
def update(self):
t1 = time.ticks_ms()
if t1 - self.time_last_update > self.update_time:
self.y += 1
self.time_last_update = t1
class Game:
def __init__(self):
self.new_game()
def new_game(self):
self.asteroids = []
self.player = Player(N_X//2,N_X-1,PLAYER_BRIGHTNESS)
self.t0 = time.ticks_ms()
self.time_last_asteroid_spawn_slot = self.t0
self.time_level_last_update = self.t0
self.level = 1
def add_asteroid(self):
rand_ast_time = random.randint(TIME_ASTEROID_UPDATE_MIN,TIME_ASTEROID_UPDATE_MAX)
self.asteroids.append(Asteroid(random.randint(0,N_X-1),0,ASTEROID_BRIGHTNESS,rand_ast_time))
def game_over(self):
display.show(IMAGE_GAME_OVER)
sleep(GAME_OVER_TIME_DELAY)
display.scroll("Level: " + str(self.level))
display.show(IMAGE_GAME_OVER)
while True:
if button_a.get_presses() or button_b.get_presses():
return
def run(self):
self.new_game()
print(self.asteroids)
while True:
# get current time
t1 = time.ticks_ms()
# level
if t1 - self.time_level_last_update > TIME_LEVEL:
self.level += 1
self.time_level_last_update = t1
# create new asteroids
if t1 - self.time_last_asteroid_spawn_slot > TIME_ASTEROID_SPAWN:
if random.randint(1,100) <= ASTEROID_SPAWN_PROBABILITY:
self.add_asteroid()
self.time_last_asteroid_spawn_slot = t1
# update asteroid positions
for asteroid in self.asteroids:
asteroid.update()
if asteroid.y >= N_Y: self.asteroids.remove(asteroid)
# update player (button presses)
player_move = 0
if button_a.get_presses(): player_move = -1
elif button_b.get_presses(): player_move = 1
self.player.update(player_move)
# collision check
for asteroid in self.asteroids:
if asteroid.y == N_Y-1 and asteroid.x == self.player.x: return
# update display
display.clear()
for asteroid in self.asteroids: asteroid.display()
self.player.display()
# short sleep
sleep(SLEEP_TIME_MS)
# MAIN LOOP
game = Game()
while True:
game.run()
game.game_over()
Demo für OOP
from microbit import *
import random
import time
import os
class Asteroid:
def __init__(self,_x,_y,_delay):
self.x = _x
self.y = _y
self.delay = _delay
self.active = True
self.time_last_update = time.ticks_ms()
def update(self):
t = time.ticks_ms()
if t - self.time_last_update > self.delay:
self.y += 1
self.time_last_update = t
if self.y > 4:
self.active = False
def display(self):
display.set_pixel(self.x,self.y,9)
asteroids = []
TIME_SPAWN = 400
SPAWN_PROBABILITY = 60
t_last_spawn = time.ticks_ms()
while True:
t = time.ticks_ms()
# update asteroids
for asteroid in asteroids:
asteroid.update()
for asteroid in asteroids:
if not asteroid.active:
asteroids.remove(asteroid)
# spawn
if t - t_last_spawn > TIME_SPAWN:
r = random.randint(1,100)
if r <= SPAWN_PROBABILITY:
asteroids.append(Asteroid(random.randint(0,4),0,random.randint(300,1000)))
t_last_spawn = t
# show
display.clear()
for asteroid in asteroids:
asteroid.display()
sleep(20)