async def fly_garbage(canvas, column, garbage_frame, speed=0.5): """Animate garbage, flying from top to bottom. Сolumn position will stay same, as specified on start.""" rows_number, columns_number = canvas.getmaxyx() column = max(column, 0) column = min(column, columns_number - 1) row = 0 rows_size, columns_size = get_frame_size(garbage_frame) obstacle = Obstacle(row, column, rows_size, columns_size) obstacles.append(obstacle) try: while row < rows_number: draw_frame(canvas, row, column, garbage_frame) await asyncio.sleep(0) draw_frame(canvas, row, column, garbage_frame, negative=True) row += speed obstacle.row = row # Remove obstacle if hit if obstacle in obstacles_damaged: obstacles_damaged.remove(obstacle) scores['points'] += 1 await explode(canvas, row, column) return finally: obstacles.remove(obstacle)
async def show_game_over(canvas): text = get_animations('game_over')[0] rows_size, column_size = get_frame_size(text) row_center, column_center = map(lambda x: x // 2, canvas.getmaxyx()) row = row_center - rows_size // 2 column = column_center - column_size // 2 while True: draw_frame(canvas, row, column, text) await asyncio.sleep(0)
async def show_game_year(canvas): _, max_column = canvas.getmaxyx() row = 1 column = 5 while True: draw_frame(canvas, row, column, f'Current year - {global_variables.year}') last_year = global_variables.year await asyncio.sleep(0) draw_frame(canvas, row, column, f'Current year - {last_year}', True)
async def show_gameover(canvas, frames): """Display GAMEOVER frames animation.""" center_row, center_column = get_center(canvas, frames) while True: for frame in frames: draw_frame(canvas, center_row, center_column, frame) await sleep(0.5 / TIC_TIMEOUT) draw_frame(canvas, center_row, center_column, frame, negative=True) await sleep(0.1 / TIC_TIMEOUT)
async def explode(canvas, center_row, center_column): # rows, columns = get_frame_size(EXPLOSION_FRAMES[0]) # corner_row = center_row - rows / 2 # corner_column = center_column - columns / 2 curses.beep() for frame in EXPLOSION_FRAMES: draw_frame(canvas, center_row, center_column, frame) await asyncio.sleep(0) draw_frame(canvas, center_row, center_column, frame, negative=True) await asyncio.sleep(0)
async def explode(self, canvas): rows, columns = get_frame_size(self.states[0]) self.corner_row = self.center_row - rows / 2 self.corner_column = self.center_column - columns / 2 curses.beep() for state in self.states: draw_frame(canvas, self.corner_row, self.corner_column, state) await asyncio.sleep(0) draw_frame(canvas, self.corner_row, self.corner_column, state, True) await asyncio.sleep(0)
async def run_spaceship(canvas, row, column, coroutines): """Control of spaceship.""" row_max, column_max = canvas.getmaxyx() frame_row, frame_column = get_frame_size(SPACESHIP_FRAMES[0]) row_speed = column_speed = 0 while True: # Set position(coordinates/speed) of spaceship rows_direction, columns_direction, space = read_controls(canvas) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) row += row_speed column += column_speed # Up and Down restrict and teleportation screen_border = 2 if row < screen_border - frame_row: row = row_max - screen_border elif row > row_max - screen_border: row = screen_border - frame_row # Right and Left restrict and teleportation if column > column_max - screen_border: column = screen_border - frame_column elif column < screen_border - frame_column: column = column_max - screen_border if space and space_data['YEAR'] >= 2020: coroutines.append(fire(canvas, row, column + 2)) # Game over if collision for obstacle in obstacles: if obstacle.has_collision(row, column): obstacles_damaged.append(obstacle) coroutines.append(show_gameover(canvas, GAMEOVER_FRAMES)) return # Ship distance calculation ship_data['covered_distance'] += fabs(row_speed) + fabs(column_speed) # Show advanced information (coordinates and distance) coordinates = f"{str(round(row))}, {str(round(column))}" covered_distance = int(ship_data['covered_distance']) covered_distance_str = f"{covered_distance} km" draw_text_offset(canvas, 1, coordinates, text_max_len=12) draw_text_offset(canvas, 2, covered_distance_str) # Draw spaceship animation draw_frame(canvas, row, column, ship_data['spaceship_frame']) old_frame = ship_data['spaceship_frame'] await asyncio.sleep(0) draw_frame(canvas, row, column, old_frame, negative=True)
async def show_gameover(canvas): ''' Отрисовать game over в центре экрана. :param canvas: [description] :type canvas: [type] ''' y_max, x_max = canvas.getmaxyx() length, width = get_frame_size(game_оver) row = y_max // 2 - length column = x_max // 2 - width while True: draw_frame(canvas, row, column, game_оver) await asyncio.sleep(0)
async def draw_year(canvas): ''' Отрисовать текущий год и достижение (если было). :param canvas: [description] :type canvas: [type] ''' global space_globals y_max, x_max = canvas.getmaxyx() row = y_max - 2 column = x_max // 2 while True: year_frame = space_globals.year_frame draw_frame(canvas, row, column, year_frame) await asyncio.sleep(0) draw_frame(canvas, row, column, year_frame, negative=True)
async def show_obstacles(canvas, obstacles): """Display bounding boxes of every obstacle in a list""" while True: boxes = [] for obstacle in obstacles: boxes.append(obstacle.dump_bounding_box()) for row, column, frame in boxes: draw_frame(canvas, row, column, frame) await asyncio.sleep(0) for row, column, frame in boxes: draw_frame(canvas, row, column, frame, negative=True)
async def animate_spaceship(canvas): canvas.nodelay(True) row_max, column_max = canvas.getmaxyx() frame_height, frame_width = get_frame_size(SPACESHIP_FRAMES[0]) border_size = 1 row_speed, column_speed = 0, 0 cur_row, cur_column = row_max // 2 - frame_height // 2, column_max // 2 - frame_width // 2 for frame in cycle(SPACESHIP_FRAMES): draw_frame(canvas, cur_row, cur_column, frame) await asyncio.sleep(0) row_offset, column_offset, space_pressed = read_controls(canvas) draw_frame(canvas, cur_row, cur_column, frame, negative=True) row_speed, column_speed = update_speed(row_speed, column_speed, row_offset, column_offset) cur_row = min(cur_row + row_speed, row_max - frame_height - border_size) if row_speed >= 0 \ else max(cur_row + row_speed, border_size) cur_column = min(cur_column + column_speed, column_max - frame_width - border_size) if column_speed > 0 else \ max(cur_column + column_speed, border_size)
async def show_game_events(canvas): description_of_last_event = str() _, max_column = canvas.getmaxyx() row = 1 column = None padding_right = 6 while True: if global_variables.year in PHRASES: if description_of_last_event: draw_frame(canvas, row, column, description_of_last_event, True) year_of_last_event = global_variables.year description_of_last_event = \ f'Last space event: {PHRASES[year_of_last_event]}' _, columns_size = get_frame_size(description_of_last_event) column = max_column - columns_size - padding_right draw_frame(canvas, row, column, description_of_last_event) await asyncio.sleep(0)
async def fly_garbage(self, canvas, speed=0.5): """Animate garbage, flying from top to bottom. Сolumn position will stay same, as specified on start.""" rows_number, columns_number = canvas.getmaxyx() self.column = max(self.column, 0) self.column = min(self.column, columns_number - 1) self.row = 0 rows_size, columns_size = get_frame_size(self.frame) obstacle = Obstacle(self.row, self.column, rows_size, columns_size) global_variables.obstacles.append(obstacle) while self.row < rows_number: draw_frame(canvas, self.row, self.column, self.frame) if obstacle in global_variables.obstacles_in_last_collisions: draw_frame(canvas, self.row, self.column, self.frame, negative=True) global_variables.obstacles.remove(obstacle) explosion = Explosion(self.row + rows_size / 2, self.column + columns_size / 2) await explosion.explode(canvas) return await asyncio.sleep(0) draw_frame(canvas, self.row, self.column, self.frame, negative=True) self.row += speed obstacle.row += speed global_variables.obstacles.remove(obstacle)
async def run_spaceship(canvas, coroutines): ''' Анимация корабля.''' global spaceship_frame global space_globals _, len1, width1 = get_frame_with_info( 'space_objects/rocket/frames/frame_1.txt') _, len2, width2 = get_frame_with_info( 'space_objects/rocket/frames/frame_2.txt') frame_length = max([len1, len2]) frame_width = max([width1, width2]) y_max, x_max = canvas.getmaxyx() row = y_max // 2 column = x_max // 2 row_speed = 0 column_speed = 0 while True: draw_frame(canvas, row, column, spaceship_frame) current_frame = spaceship_frame await asyncio.sleep(0) draw_frame(canvas, row, column, current_frame, negative=True) row_dir, column_dir, space_pressed = read_controls(canvas) if space_pressed and space_globals.plasma_gun: coroutines.append(fire(canvas, row, column + 2)) row_speed, column_speed = update_speed(row_speed, column_speed, row_dir, column_dir) row = row + row_speed if row + row_dir + frame_length > y_max: row = y_max - frame_length elif row + row_dir < 1: row = 1 column = column + column_speed if column + row_dir + frame_width > x_max - 2: column = x_max - frame_width - 2 elif column + column_dir < 1: column = 1 for obstacle in obstacles: if obstacle.has_collision(row, column): draw_frame(canvas, row, column, current_frame, negative=True) await explode(canvas, row, column) coroutines.append(show_gameover(canvas)) return
async def run(self, canvas): while True: draw_frame(canvas, self.row, self.column, self.state) previous_spaceship_state = self.state await asyncio.sleep(0) row_direction, column_direction, space = read_controls(canvas) if space and (global_variables.year >= 2020): # -1: shift the animation to see explosion during a shot # 2: shift the animation to a shot was out of the gun new_bullet = Bullet(self.row - 1, self.column + 2) global_variables.coroutines.append(new_bullet.fly(canvas)) curses.beep() self.row_speed, self.column_speed = update_speed( self.row_speed, self.column_speed, row_direction, column_direction) for obstacle in global_variables.obstacles: is_collision = has_collision( (obstacle.row, obstacle.column), (obstacle.rows_size, obstacle.columns_size), (self.row, self.column)) if is_collision: draw_frame(canvas, self.row, self.column, previous_spaceship_state, True) rows_size, columns_size = get_frame_size(self.state) explosion = Explosion(self.row + rows_size / 2, self.column + rows_size / 2) await explosion.explode(canvas) global_variables.coroutines.append(show_game_over(canvas)) return draw_frame(canvas, self.row, self.column, previous_spaceship_state, True) self.row, self.column = get_possible_coordinates( canvas, self.row + self.row_speed, self.column + self.column_speed, self.state)
async def fly_garbage(canvas, column, speed=0.5): '''Animate garbage, flying from top to bottom. Сolumn position will stay same, as specified on start.''' global obstacles rows_number, columns_number = canvas.getmaxyx() column = max(column, 0) column = min(column, columns_number - 1) row = 0 frame, length, width = get_frame_with_info(get_random_garbage_frame()) obstacle_marker = Obstacle(row, column, length, width) obstacles.append(obstacle_marker) while row < rows_number: draw_frame(canvas, row, column, frame) await asyncio.sleep(0) draw_frame(canvas, row, column, frame, negative=True) row += speed obstacle_marker.row = row if obstacle_marker in obstacles_last_collision: obstacles.remove(obstacle_marker) obstacles_last_collision.remove(obstacle_marker) draw_frame(canvas, row, column, frame, negative=True) await explode(canvas, obstacle_marker.row, obstacle_marker.column) return