async def fly_garbage(canvas, column, garbage_frame, speed=0.5): row_max, column_max = get_max_coords(canvas) column = min(max(column, 0), column_max) row = 0 height, width = get_frame_size(garbage_frame) global obstacles_list, obstacles_in_last_collisions uid = uuid.uuid4() obstacle = Obstacle(row, column, height, width, uid) obstacles_list.append(obstacle) while obstacle.row < row_max: draw_frame(canvas, obstacle.row, column, garbage_frame) await asyncio.sleep(0) draw_frame(canvas, obstacle.row, column, garbage_frame, negative=True) if obstacle in obstacles_in_last_collisions: obstacles_in_last_collisions.remove(obstacle) obstacles_list.remove(obstacle) row = obstacle.row + obstacle.rows_size / 2 column = obstacle.column + obstacle.columns_size / 2 await explode(canvas, round(row), round(column)) return obstacle.row += speed obstacles_list.remove(obstacle)
async def fire(canvas, start_row, start_column, rows_speed=-0.3, columns_speed=0): row, column = start_row, start_column canvas.addstr(round(row), round(column), "*") await asyncio.sleep(0) canvas.addstr(round(row), round(column), "O") await asyncio.sleep(0) canvas.addstr(round(row), round(column), " ") row += rows_speed column += columns_speed symbol = "-" if columns_speed else "|" max_row, max_column = get_max_coords(canvas) curses.beep() global obstacles_list, obstacles_in_last_collisions while 0 < row < max_row and 0 < column < max_column: for obstacle in obstacles_list: if obstacle.has_collision(round(row), round(column)): obstacles_in_last_collisions.append(obstacle) return canvas.addstr(round(row), round(column), symbol) await asyncio.sleep(0) canvas.addstr(round(row), round(column), " ") row += rows_speed column += columns_speed
async def game_over(canvas): sign = load_frames("game")[0] sign_height, sign_width = get_frame_size(sign) row_max, column_max = get_max_coords(canvas) row = row_max // 2 - sign_height // 2 column = column_max // 2 - sign_width // 2 while True: draw_frame(canvas, row, column, sign) await asyncio.sleep(0)
def draw(canvas): curses.curs_set(0) canvas.nodelay(True) time_elapsed = 0 row_max, column_max = get_max_coords(canvas) stars = [ blink( canvas, randrange(row_max), randrange(column_max), choice(STARS_SYMBOLS), ) for _ in range(STARS_COUNT) ] global coroutines, year coroutines.extend(stars) coroutines.append(run_spaceship(canvas)) coroutines.append(fill_orbit_with_garbage(canvas, column_max)) exhausted = set() while True: for coroutine in coroutines: try: coroutine.send(None) except StopIteration: exhausted.add(coroutine) coroutines = [coro for coro in coroutines if coro not in exhausted] exhausted.clear() legend = canvas.derwin(row_max - 1, 2) inscription = f"{year} {PHRASES.get(year, '')}" legend.addstr(0, 0, inscription) canvas.border() canvas.refresh() time.sleep(TIC_TIMEOUT) time_elapsed += TIC_TIMEOUT if round(time_elapsed % 1.5, 1) == 0: year += 1 time_elapsed = 0 legend.erase()
async def run_spaceship(canvas): spaceship_frames = animate_spaceship() height, width = get_frame_size(next(spaceship_frames)) row_max, column_max = get_max_coords(canvas) row = row_max // 2 - height // 2 column = column_max // 2 - width // 2 field_max_y = row_max - height field_max_x = column_max - width row_speed = column_speed = 0 for frame in spaceship_frames: row_dir, column_dir, space_pressed = read_controls(canvas) row_speed, column_speed = update_speed( row_speed, column_speed, row_dir, column_dir ) row += row_speed column += column_speed row = max(min(row, field_max_y), 0) column = max(min(column, field_max_x), 0) global coroutines, obstacles_list, year if space_pressed and year >= 2020: coroutines.append(fire(canvas, row, column + width // 2, rows_speed=-1)) draw_frame(canvas, row, column, frame) await asyncio.sleep(0) draw_frame(canvas, row, column, frame, negative=True) for obstacle in obstacles_list: if obstacle.has_collision(row, column, height, width): obstacles_in_last_collisions.append(obstacle) await explode(canvas, row, column) await game_over(canvas)