async def show_game_progress(canvas, x, y): game = Game() while True: text = f"{game.year} {game.text}" draw_frame(canvas, x, y, text) await Sleep(1) draw_frame(canvas, x, y, text, True)
async def animate_garbage(canvas, garbage, velocity=0.6): """Animate garbage, flying from top to bottom. Сolumn position will stay same, as specified on start.""" window_height, window_width = canvas.getmaxyx() x = min(max(garbage.x, 0), window_width - 1) y = garbage.y obstacle_manager.add_object(garbage) frame = garbage.frame while y < window_height: # terminate garbage object if garbage.term: GameLoop().add_coroutine( animate_explosion(canvas, garbage.get_center_pos())) obstacle_manager.remove_object(garbage.uid) return # draw moving garbage draw_frame(canvas, x, y, frame) await Sleep(1) draw_frame(canvas, x, y, frame, negative=True) y += velocity garbage.y = y # garbage flew away obstacle_manager.remove_object(garbage.uid)
async def run_spaceship(canvas, x, y): """ Spaceship coroutine that handles player's input and draws frames. Works every step of event loop. """ # getmaxyx() return height and width of the window. height, width = canvas.getmaxyx() # we want to stop the spaceship right before the border line max_x = width - FRAME_WIDTH - 1 max_y = height - FRAME_HEIGHT - 1 prev_frame = None game_loop = GameLoop() game = Game() vel_x, vel_y = 0, 0 while True: # get current frame frame = spaceship.frame # read controls dy, dx, space = read_controls(canvas) if space and game.is_gun_available(): # TODO add fire cooldown game_loop.add_coroutine( animate_gunshot(canvas=canvas, pos=(x + SPACESHIP_X_HALF, y - 1))) vel_x, vel_y = update_velocity( x_direction=dx, y_direction=dy, velocity_vec=(vel_x, vel_y), velocity_limit_vec=(SPACESHIP_MAX_X_SPEED, SPACESHIP_MAX_Y_SPEED)) # count next coordinates # check borders intersection # choose closest point to the border x1 = max(1, min(x + vel_x, max_x)) y1 = max(1, min(y + vel_y, max_y)) # clean prev frame at old pos and draw current frame at new pos clean_draw(canvas, (x, y), (x1, y1), prev_frame, frame) x, y = x1, y1 # check collisions with obstacles for obstacle in obstacle_manager.get_front_objects(x, x + FRAME_WIDTH): # GAME OVER if obstacle.has_collision(obj_pos=(x, y), obj_size=(FRAME_WIDTH, FRAME_HEIGHT)): game.over() # clear last spaceship frame draw_frame(canvas, x, y, frame, True) spaceship_center_pos = (x + SPACESHIP_X_HALF, y + SPACESHIP_Y_HALF) game_loop.add_coroutine( animate_explosion(canvas=canvas, center_pos=spaceship_center_pos)) game_loop.add_coroutine(show_gameover(canvas)) return # sleep for 1 Game Tic or 1 Event Loop iteration await Sleep(1) prev_frame = frame
async def animate_explosion(canvas, center_pos: Coordinate): width, height = get_frame_size(EXPLOSION_FRAMES[0][1]) corner_x = center_pos[0] - width // 2 corner_y = center_pos[1] - height // 2 curses.beep() for tics, frame in EXPLOSION_FRAMES: draw_frame(canvas, corner_x, corner_y, frame) await Sleep(tics) draw_frame(canvas, corner_x, corner_y, frame, negative=True) await Sleep(tics)
async def show_gameover(canvas): '''Show game over in the center of the screen''' centet_y, center_x = map(lambda v: v // 2, canvas.getmaxyx()) w, h = get_frame_size(game_over_frame) start_x = center_x - w // 2 start_y = centet_y - h // 2 # small pause await Sleep(10) while True: draw_frame(canvas, start_x, start_y, game_over_frame) await Sleep(1)
async def show_obstacles(canvas): """Display bounding boxes of every obstacle in a list""" while True: boxes = [] for obstacle in obstacle_manager: boxes.append(obstacle.get_bounding_box()) for x, y, frame in boxes: draw_frame(canvas, x, y, frame) await Sleep(1) for x, y, frame in boxes: draw_frame(canvas, x, y, frame, negative=True)