def read_controls(canvas): """Read keys pressed and returns tuple witl controls state.""" row_speed = 0 column_speed = 0 rows_direction = columns_direction = 0 space_pressed = False pressed_key_code = canvas.getch() if pressed_key_code == -1: return rows_direction, columns_direction, space_pressed if pressed_key_code == UP_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, -1, 0) elif pressed_key_code == DOWN_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, 1, 0) elif pressed_key_code == RIGHT_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, 0, 1) elif pressed_key_code == LEFT_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, 0, -1) elif pressed_key_code == SPACE_KEY_CODE: space_pressed = True return row_speed, column_speed, space_pressed
async def run_spaceship(canvas): rows_number, columns_number = canvas.getmaxyx() row_speed = column_speed = 0 row = rows_number - (SPACESHIP_ANIMATIONS_ROWS * 2) column = columns_number // 2 while True: rows_direction, columns_direction, spase_pressed = read_controls( canvas) if spase_pressed and game_time_line.year >= YAMATO_GUN_AVAILABLE_SINCE_YEAR: coroutines.append(animate_yamato_cannon(canvas, row, column)) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) if (1 < row + row_speed < rows_number - SPACESHIP_ANIMATIONS_ROWS and 1 < column + column_speed < columns_number - SPACESHIP_ANIMATIONS_COLUMNS): row += row_speed column += column_speed draw_frame(canvas, row, column, spaceship_frame) await asyncio.sleep(0) draw_frame(canvas, row, column, previous_spaceship_frame, True) for obstacle in obstacles: if obstacle.has_collision(row, column): coroutines.append(animate_game_over(canvas)) return
async def animate_spaceship(canvas, row, column, frames): row_speed = column_speed = 0 screen_rows, screen_columns = canvas.getmaxyx() max_row, max_column = screen_rows - OFFSET_FROM_EDGE_OF_SCREEN, screen_columns - OFFSET_FROM_EDGE_OF_SCREEN for frame in cycle(frames): frame_rows, frame_columns = get_frame_size(frame) for _ in range(2): rows_direction, columns_direction, space_pressed = read_controls(canvas) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) row += row_speed column += column_speed row = max( OFFSET_FROM_EDGE_OF_SCREEN, min(row + rows_direction, max_row - frame_rows) ) column = max( OFFSET_FROM_EDGE_OF_SCREEN, min(column + columns_direction, max_column - frame_columns) ) draw_frame(canvas, row, column, frame, color=[1, 2]) await asyncio.sleep(0) draw_frame(canvas, row, column, frame, negative=True) if space_pressed and year >= YEAR_OF_GUN_AVAILABILITY: coroutines.append( fire(canvas, row, column + round(frame_columns / 2), -3) ) for obstacle in obstacles: if not obstacle.has_collision(row, column, frame_rows, frame_columns): continue coroutines.append(show_gameover(canvas)) return
async def run_spaceship(canvas, start_row, start_col): row, column = start_row, start_col row_speed, column_speed = 0, 0 min_row, min_column = FRAME_BORDER_SIZE, FRAME_BORDER_SIZE max_row, max_column = get_correct_window_dimensions(canvas) while True: temp_spaceship_frame = spaceship_frame # frame_size = get_frame_size(temp_spaceship_frame) rows, columns = get_frame_size(temp_spaceship_frame) move_row, move_column, space_pressed = read_controls(canvas) row_speed, column_speed = update_speed( row_speed, column_speed, move_row, move_column) row, column = row + row_speed, column + column_speed column = min(max(min_column, column), max_column - columns - FRAME_BORDER_SIZE) row = min(max(min_row, row), max_row - rows - FRAME_BORDER_SIZE) collisions = [obstacle for obstacle in obstacles if obstacle.has_collision(row, column, rows, columns)] if collisions: await show_gameover(canvas, start_row, start_col) if space_pressed and year >= PLASMA_GUN_ERA: coroutines.append( fire(canvas, row, column + columns // 2)) draw_frame(canvas, row, column, temp_spaceship_frame) await sleep() draw_frame(canvas, row, column, temp_spaceship_frame, negative=True)
def handle_control_commands(canvas, frame, row_pozition, column_pozition, limits, row_speed, column_speed): """Handle keyboard commands and change rocket coordinates.""" row_direction, column_direction, space_pressed = \ utils.read_controls(canvas) row_speed, column_speed = update_speed(row_speed, column_speed, row_direction, column_direction) utils.draw_frame(canvas, row_pozition, column_pozition, frame, negative=True) row_pozition += row_speed column_pozition += column_speed row_pozition = min(max(row_pozition, limits['min_row']), limits['max_row']) column_pozition = min(max(column_pozition, limits['min_column']), limits['max_column']) if year > 2020 and space_pressed: fire_row = row_pozition fire_column = column_pozition + utils.get_frame_size(frame)[1] // 2 coroutines.append(fire(canvas, fire_row, fire_column, rows_speed=-2)) utils.draw_frame(canvas, row_pozition, column_pozition, frame) return row_pozition, column_pozition, row_speed, column_speed
async def run_spaceship(canvas, canvas_vertical_center, canvas_horizontal_center, frames): row, column = canvas_vertical_center, canvas_horizontal_center frame_rows, frame_columns = get_frame_size(frames[0]) canvas_rows, canvas_column = canvas.getmaxyx() row_speed, column_speed = 0, 0 while True: rows_direction, columns_direction, space_pressed = read_controls(canvas) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) row = max(1, min(row + row_speed, canvas_rows - frame_rows - 1)) column = max(1, min(column + column_speed, canvas_column - frame_columns - 1)) previous_spaceship_frame = spaceship_frame draw_frame(canvas, row, column, spaceship_frame, negative=False) plasma_gun_activation_year = 2020 if year > plasma_gun_activation_year and space_pressed: coroutines.append(fire(canvas, row, column + 2)) await asyncio.sleep(0) draw_frame(canvas, row, column, previous_spaceship_frame, negative=True) for index, obstacle in enumerate(obstacles.copy()): # add show_gameover coroutine if spaceship meet garbage if obstacle.has_collision(row, column): coroutines.append( show_gameover(canvas, canvas_vertical_center, canvas_horizontal_center) ) return
async def run_spaceship(canvas, spaceship_frame, coroutines, obstacles, obstacles_collisions, years, timeout, row, column): assert all(i >= 0 for i in (row, column, timeout)), AssertionError( "row, column and timeout have to be non-negative") assert bool(years), AssertionError( "Years has to be initiated with int value.") height, width = canvas.getmaxyx() row_speed = 0 column_speed = 0 # "spinlock" waiting for updating spaceship_frame while not spaceship_frame: await asyncio.sleep(0) frame, rocket_height, rocket_width = spaceship_frame draw_frame(canvas, row, column, frame) while True: collisions = set( filter(lambda o: o.has_collision(row, column), obstacles)) if collisions: obstacles_collisions.update(collisions) draw_frame(canvas, row, column, frame, negative=True) await explode(canvas, row, column) coroutines.append(get_game_over(canvas)) spaceship_frame[0] = None return # handle a user control row_shift, col_shift, space = read_controls(canvas) draw_frame(canvas, row, column, frame, negative=True) row_speed, column_speed = update_speed(row_speed, column_speed, row_shift, col_shift) # keep rocket in borders row = calc_location(row + row_speed, height - rocket_height - 1) column = calc_location(column + column_speed, width - rocket_width - 1) # shoot if space and years[0] >= 2020: coroutines.append( fire(canvas, obstacles, obstacles_collisions, row - 1, column + 2, -2)) frame, rocket_height, rocket_width = spaceship_frame draw_frame(canvas, row, column, frame) await asyncio.sleep(0)
async def run_spaceship(canvas, window_rows, window_columns, frame_rows, frame_columns): global starship_row, starship_column, obstacles # вычисляем правую и нижнию границу один раз при условии что размеры окна не меняются во время работы max_allowed_row = window_rows - frame_rows - 1 max_allowed_column = window_columns - frame_columns - 1 row_speed = column_speed = 0 while True: rows_direction, columns_direction, space_pressed = read_controls( canvas) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) new_row = starship_row + row_speed * SPEED new_column = starship_column + column_speed * SPEED starship_row = median([1, new_row, max_allowed_row]) starship_column = median([1, new_column, max_allowed_column]) if space_pressed and YEAR >= 2020: coroutine = fire(canvas, starship_row, starship_column + frame_columns // 2) # середина корабля coroutines.append(coroutine) for obstacle in obstacles: if obstacle.has_collision(starship_row, starship_column, frame_rows, frame_columns): coroutines.append( show_gameover(canvas, window_rows, window_columns)) return await asyncio.sleep(0)
async def run_spaceship(canvas): global spaceship_frame global coroutines global year row, column = 5, 8 row_speed = column_speed = 0 while True: last_spaceship_frame = spaceship_frame row_control, col_control, space_control = read_controls(canvas) row_size, column_size = get_frame_size(last_spaceship_frame) if space_control and year > 2020: coroutines.append(fire(canvas, row, column + column_size // 2)) row_speed, column_speed = update_speed(row_speed, column_speed, row_control, col_control) row += row_speed column += column_speed for obstacle in obstacles: if obstacle.has_collision(row, column, row_size, column_size): coroutines.append(show_gameover(canvas)) return draw_frame(canvas, row, column, last_spaceship_frame) await sleep() draw_frame(canvas, row, column, last_spaceship_frame, True)
async def run_spaceship(canvas, frames): height, width = get_frame_size(frames[0]) row_max, col_max = get_canvas_max_coords(canvas) row = row_max - height // 2 col = col_max // 2 - width // 2 row_speed = col_speed = 0 cur_frame = None while True: for obstacle in obstacles: if obstacle.has_collision(row, col): draw_frame(canvas, row, col, cur_frame, negative=True) await show_gameover(canvas) row_change, col_change, shot_made = read_controls(canvas) if shot_made and year >= YEAR_GUN_ON: fire = animate_fire(canvas, row, col + width // 2) coroutines.append(fire) row_speed, col_speed = update_speed(row_speed, col_speed, row_change, col_change) row += row_speed col += col_speed row = min(row, row_max - height) col = min(col, col_max - width) row = max(row, BORDER) col = max(col, BORDER) draw_frame(canvas, row, col, spaceship_frame) cur_frame = spaceship_frame await sleep() draw_frame(canvas, row, col, cur_frame, negative=True)
async def run_spaceship(canvas, row, column): """ Анимация ракеты с поддержкой перемещения""" global year row_speed = column_speed = 0 MAX_Y, MAX_X = canvas.getmaxyx() while True: current_frame, current_row, current_column = spaceship_frame, row, column draw_frame(canvas, row, column, spaceship_frame) row_acceleration, column_acceleration, space_pressed = read_controls( canvas) row_speed, column_speed = update_speed(row_speed, column_speed, row_acceleration, column_acceleration) for obstacle in obstacles: if obstacle.has_collision(row, column): await show_gameover(canvas) return if (BORDER < row + row_speed < MAX_Y - FRAME_HEIGHT - BORDER): row += row_speed if (BORDER < column + column_speed < MAX_X - FRAME_WIDTH - BORDER): column += column_speed if space_pressed and year >= 2020: coroutines.append( fire(canvas, row, column + FRAME_WIDTH / 2, obstacles, obstacles_in_last_collisions)) await sleep(0.1) draw_frame(canvas, current_row, current_column, current_frame, True) draw_frame(canvas, row, column, spaceship_frame)
async def run_spaceship(canvas, row, column): """ controls location of spaceship and draws it on the screen""" row_speed = column_speed = 0 global spaceship_frame global coroutines global year spaceship_collision = False while not spaceship_collision: maxx, maxy = canvas.getmaxyx() rows_direction, columns_direction, space_pressed = read_controls( canvas) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) frame_rows, frame_columns = get_frame_size(spaceship_frame) row, column = speed_reduction_near_border(row, column, frame_rows, frame_columns, maxx, maxy, row_speed, column_speed) draw_frame(canvas, row, column, spaceship_frame) last_frame = spaceship_frame frame_rows, frame_columns = get_frame_size(spaceship_frame) await sleep(1) if space_pressed and (year >= 2020): coroutines.append(fire(canvas, row, column + 2)) draw_frame(canvas, row, column, last_frame, negative=True) if if_collision_append_collision_list(row, column, frame_rows, frame_columns): spaceship_collision = True coroutines.append( explode(canvas, row + frame_rows // 2, column + frame_columns // 2)) coroutines.append(show_gameover(canvas))
def get_ship_control(canvas, start_row, start_column, row_speed, column_speed, frame): """Function read keyboard and return space ship coordinates for space ship animation function""" frame_y, frame_x = get_frame_size(frame) #ship should not intersect window border #increase frame size frame_offset = 1 frame_y += frame_offset frame_x += frame_offset y_max, x_max = canvas.getmaxyx() row, column, space = read_controls(canvas) #read keyboard row_speed, column_speed = update_speed(row_speed, column_speed, row, column) start_row += row_speed start_column += column_speed #check field border if start_row >= y_max - frame_y: start_row = y_max - frame_y elif start_row < 1: start_row = 1 if start_column >= x_max - frame_x: start_column = x_max - frame_x elif start_column < 1: start_column = 1 return (start_row, start_column, row_speed, column_speed, space)
async def run_spaceship(canvas, row, column): global spaceship_frame, year row_speed = column_speed = 0 max_row, max_column = get_canvas_maxyx(canvas) frame_rows, frame_columns = ctools.get_frame_size(spaceship_frame) while True: row_d, column_d, space_pressed = ctools.read_controls(canvas) row_speed, column_speed = update_speed(row_speed, column_speed, row_d, column_d) row = min(max(row + row_speed, 0), max_row - frame_rows) column = min(max(column + column_speed, 0), max_column - frame_columns) sh_frame = spaceship_frame ctools.draw_frame(canvas, row, column, sh_frame) await sleep(1) ctools.draw_frame(canvas, row, column, sh_frame, True) if space_pressed and year > 2020: event_loop.create_task(fire(canvas, row - 1, column + frame_columns // 2)) for obstacle in obstacles: if obstacle.has_collision(row, column, frame_rows, frame_columns): await show_gameover(canvas) return
async def run_spaceship(canvas): row_speed = column_speed = 0 old_frame = '' global coros, obstacles, year old_row, old_col = row, column = 15, 35 while True: for obstacle in obstacles: is_collision = obstacle.has_collision(row, column) if is_collision: obstacles_in_last_collisions.append(obstacle) draw_frame(canvas, old_row, old_col, old_frame, negative=True) await show_gameover(canvas) return None else: keyboard_row, keyboard_column, space_pressed = read_controls( canvas) row_speed, column_speed = update_speed(row_speed, column_speed, keyboard_row, keyboard_column) row += row_speed column += column_speed row, column = control_screen_borders(canvas, row, column) if space_pressed and year > 1970: coros.append(fire(canvas, row - 1, column + 2)) draw_frame(canvas, old_row, old_col, old_frame, negative=True) draw_frame(canvas, row, column, FRAME) old_frame = FRAME old_row, old_col = row, column await asyncio.sleep(0)
async def run_spaceship(canvas, row, column): """Determine the position of the spaceship and display it. Params: * canvas: window object from curses * row: number of row * column: number of column """ # Define height and width of the canvas canvas_height, canvas_width = canvas.getmaxyx() global spaceship_frame, row_speed, column_speed, year while True: # Define height and width of the frame frame_height, frame_width = get_frame_size(spaceship_frame) rows_direction, columns_direction, space_pressed = read_controls( canvas) row_speed, column_speed = update_speed( row_speed, column_speed, rows_direction, columns_direction, ) # Subtract 1 so as not to erase the borders row_number = min( row + row_speed, canvas_height - frame_height - 1, ) column_number = min( column + column_speed, canvas_width - frame_width - 1, ) # Set 1 so as not to erase the borders row = max(row_number, 1) column = max(column_number, 1) # Make a gun shot if the user presses a space # and a year 2020 or more if space_pressed and year >= YEAR_CREATION_LASER_GUN: fire_coroutine = fire(canvas, row, column, rows_speed=-2) coroutines.append(fire_coroutine) draw_frame(canvas, row, column, spaceship_frame) # Stores the last frame of the animation that was drawn, # and which you want to erase later last_frame = spaceship_frame await sleep() draw_frame(canvas, row, column, last_frame, negative=True) for obstacle in obstacles: if obstacle.has_collision(row, column, frame_height, frame_width): gameover_coroutine = show_gameover(canvas) coroutines.append(gameover_coroutine) return
async def run_spaceship( canvas, start_row, start_column, gun_activation_year=2020): row, column = start_row, start_column row_speed = column_speed = 0 canvas_height, canvas_width = canvas.getmaxyx() while True: current_frame = spaceship_frame rows_direction, columns_direction, space_pressed = read_controls( canvas=canvas, ) row_speed, column_speed = update_speed( row_speed=row_speed, column_speed=column_speed, rows_direction=rows_direction, columns_direction=columns_direction, ) row += row_speed column += column_speed frame_height, frame_width = get_frame_size(current_frame) row = limit( value=row, min_value=1, max_value=canvas_height - frame_height - 1, ) column = limit( value=column, min_value=1, max_value=canvas_width - frame_width - 1, ) draw_frame(canvas, row, column, current_frame) if space_pressed and row > 1 and year >= gun_activation_year: coroutines.append( animate_gun_shot( canvas=canvas, start_row=row - 1, start_column=column + 2, ) ) await sleep() draw_frame(canvas, row, column, current_frame, negative=True) for obstacle in obstacles: if obstacle.has_collision( obj_corner_row=row, obj_corner_column=column): coroutines.append( show_gameover(canvas=canvas), ) return
async def animate_spaceship(canvas, row, column, frames, row_speed, column_speed, spaceship_obstacle): row_speed, column_speed = row_speed, column_speed for frame in itertools.cycle(frames): # getmaxyx() - возвращает ширину и высоту окна, которые всегда на единицу больше чем координаты крайних ячеек max_rows, max_columns = canvas.getmaxyx() rows_direction, columns_direction, space_pressed = ct.read_controls( canvas=canvas) row_speed, column_speed = update_speed( row_speed=row_speed, column_speed=column_speed, rows_direction=rows_direction, columns_direction=columns_direction) row += row_speed column += column_speed ct.draw_frame(canvas=canvas, start_row=row, start_column=column, text=frame) await sleep(1) # стираем предыдущий кадр, прежде чем рисовать новый ct.draw_frame(canvas=canvas, start_row=row, start_column=column, text=frame, negative=True) if space_pressed and YEAR > 2020: COROUTINES.append(fire(canvas, row - 1, column + 2)) frame_rows, frame_columns = ct.get_frame_size(text=frame) # frame_rows и BORDER_WIDTH - учитываем размер модели и рамку на нижней рамке row = min(max_rows - frame_rows - BORDER_WIDTH, row) # frame_columns и BORDER_WIDTH - учитываем размер модели и рамку на правой рамке column = min(max_columns - frame_columns - BORDER_WIDTH, column) row = max( row, BORDER_WIDTH ) # BORDER_WIDTH отвечает за контроль от перехода выше верхней рамки column = max( column, BORDER_WIDTH ) # BORDER_WIDTH отвечает за контроль от перехода левее левой рамки spaceship_obstacle.row = row spaceship_obstacle.column = column if life_points <= 0: await explode(canvas, spaceship_obstacle.row, spaceship_obstacle.column) OBSTACLES.remove(spaceship_obstacle) await show_game_over(canvas=canvas, row=row, column=column) return None
async def run_spaceship(canvas, coros, start_row, start_column, frame_container, level, start_year): height, width = canvas.getmaxyx() border_size = 1 frame_size_y, frame_size_x = get_frame_size(frame_container[0]) frame_pos_x = round(start_column) - round(frame_size_x / 2) frame_pos_y = round(start_row) - round(frame_size_y / 2) row_speed, column_speed = 0, 0 while True: direction_y, direction_x, spacebar = read_controls(canvas) current_year = start_year + level[0] if spacebar and current_year >= 2020: shot_pos_x = frame_pos_x + round(frame_size_x / 2) shot_pos_y = frame_pos_y - 0 shot_coro = fire(canvas, shot_pos_y, shot_pos_x) coros.append(shot_coro) row_speed, column_speed = update_speed(row_speed, column_speed, direction_y, direction_x) frame_pos_x += column_speed frame_pos_y += row_speed frame_x_max = frame_pos_x + frame_size_x frame_y_max = frame_pos_y + frame_size_y field_x_max = width - border_size field_y_max = height - border_size frame_pos_x = min(frame_x_max, field_x_max) - frame_size_x frame_pos_y = min(frame_y_max, field_y_max) - frame_size_y frame_pos_x = max(frame_pos_x, border_size) frame_pos_y = max(frame_pos_y, border_size) current_frame = frame_container[0] draw_frame(canvas, frame_pos_y, frame_pos_x, current_frame) await asyncio.sleep(0) draw_frame(canvas, frame_pos_y, frame_pos_x, current_frame, negative=True) for obstacle in obstacles_actual: if obstacle.has_collision(frame_pos_y, frame_pos_x): game_over_coro = show_gameover( canvas, height, width, load_frame_from_file('game_over/game_over.txt')) coros.append(game_over_coro) return
async def run_spaceship(canvas, start_row, start_column): """Spaceship behavoir: control with arrow keys, animate frames, check for collisions with garbage.""" global spaceship_frame, spaceship_flame_frame, coroutines, obstacles row = start_row column = start_column # Get canvas limits and spaceship dimentions. row_max, column_max = canvas.getmaxyx() spaceship_height, spaceship_width = get_frame_size(spaceship_frame) row_limits = (0, row_max - spaceship_height) column_limits = (0, column_max - spaceship_width) row_speed = column_speed = 0 previous_spaceship_flame_frame = '' previous_spaceship_frame = '' while True: rows_direction, columns_direction, space_pressed = read_controls(canvas) # Calculate new speed and new coordinates. row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) if row >= max(row_limits) and row_speed >= 0 or row <= min(row_limits) and row_speed <= 0: row_speed = 0 row = row + row_speed if column >= max(column_limits) and column_speed >= 0 or column <= min(column_limits) and column_speed <= 0: column_speed = 0 column = column + column_speed # Power-on the plasma gun. if space_pressed and year > YEAR_PLASMA_GUN_INVENTED: coroutines.append(animate_fire(canvas, row, column +2, rows_speed=-0.6, columns_speed=0)) # Animate frames. draw_frame(canvas, row, column, spaceship_frame) draw_frame(canvas, row, column, spaceship_flame_frame, color='yellow') await asyncio.sleep(0) draw_frame(canvas, row, column, previous_spaceship_frame, negative=True) draw_frame(canvas, row, column, previous_spaceship_flame_frame, negative=True) previous_spaceship_frame = spaceship_frame previous_spaceship_flame_frame = spaceship_flame_frame # Check for collisions with garbage. for obstacle in obstacles: if obstacle.has_collision(row, column): obstacles.remove(obstacle) await explode(canvas, row, column) await show_gameover(canvas) return
def run(self, canvas): canvas.nodelay(True) curses.curs_set(False) self.canvas = canvas stars = self.generate_stars() for star_coords, attributes in stars.items(): x, y = star_coords symbol, delay = attributes self.coroutines.append(star_blink(canvas, y, x, delay, symbol)) self.space_coords = self.canvas_center_coords self.coroutines.append(self.space_animation()) self.coroutines.append(self.fill_orbit_with_garbage()) self.coroutines.append(self.add_fire()) self.coroutines.append(self.show_game_over()) self.coroutines.append(self.show_year_label()) snap_index = 0 while True: if not self.is_space_died: y_direction, x_direction, is_shot = read_controls(canvas) self.is_shot = is_shot and self.current_year > 2019 x, y = self.space_coords v_x, v_y = self.space_x_speed, self.space_y_speed v_y, v_x = update_speed(v_y, v_x, y_direction, x_direction) x += v_x y += v_y self.space_x_speed, self.space_y_speed = v_x, v_y self.space_coords = self.get_space_corrected_coords(x, y) for coroutine in self.coroutines.copy(): try: coroutine.send(None) except StopIteration: self.coroutines.remove(coroutine) if len(self.coroutines) == 0: break canvas.refresh() canvas.border() time.sleep(ANIMATION_DELAY) if not snap_index % ( ONE_YEAR_DURATION_IN_SECONDS / ANIMATION_DELAY): self.current_year += 1 snap_index += 1
async def drive_spaceship(canvas, start_row, start_column, animation_frame_1, animation_frame_2): row, column = start_row, start_column row_speed = column_speed = 0 rows_number, columns_number = canvas.getmaxyx() frame_rows, frame_columns = get_frame_size(animation_frame_1) while True: rows_direction, columns_direction, space_pressed = read_controls( canvas) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) row += row_speed upper_border = BORDER if row < upper_border: row = upper_border bottom_border = rows_number - frame_rows - BORDER if row > bottom_border: row = bottom_border column += column_speed left_border = BORDER if column < left_border: column = left_border right_border = columns_number - frame_columns - BORDER if column > right_border: column = right_border if space_pressed: spaceship_head_column = column + (frame_columns / 2) coroutines.append( fire(canvas, start_row=row, start_column=spaceship_head_column, rows_speed=ROWS_SPEED, columns_speed=COLUMNS_SPEED)) for obstacle in obstacles: if obstacle.has_collision(row, column): coroutines.append(show_gameover(canvas, game_over_frame)) return None await animate_spaceship(animation_frame_1) await run_spaceship(canvas, row, column) await animate_spaceship(animation_frame_2) await run_spaceship(canvas, row, column)
async def run_spaceship(canvas, coroutines, frames_container, border_size): main_window_height, main_window_width = canvas.getmaxyx() start_ship_row = main_window_height - border_size start_ship_column = main_window_width / 2 frame_size_y, frame_size_x = get_frame_size(frames_container[0]) frame_pos_x = round(start_ship_row) - round(frame_size_x / 2) frame_pos_y = round(start_ship_column) row_speed, column_speed = 0, 0 while True: direction_y, direction_x, spacepressed = read_controls(canvas) if spacepressed: shot_pos_x = frame_pos_x + round(frame_size_x / 2) shot_pos_y = frame_pos_y shot_coroutine = fire(canvas, shot_pos_y, shot_pos_x) coroutines.append(shot_coroutine) row_speed, column_speed = update_speed(row_speed, column_speed, direction_y, direction_x) frame_pos_x += column_speed frame_pos_y += row_speed frame_pos_x_max = frame_pos_x + frame_size_x frame_pos_y_max = frame_pos_y + frame_size_y game_field_x_max = main_window_width - border_size game_field_y_max = main_window_height - border_size frame_pos_x = min(frame_pos_x_max, game_field_x_max) - frame_size_x frame_pos_y = min(frame_pos_y_max, game_field_y_max) - frame_size_y frame_pos_x = max(frame_pos_x, border_size) frame_pos_y = max(frame_pos_y, border_size) frame = frames_container[0] draw_frame(canvas, frame_pos_y, frame_pos_x, frame) await asyncio.sleep(0) draw_frame(canvas, frame_pos_y, frame_pos_x, frame, negative=True) gameover_frame = load_frame_from_file(GAME_OVER_FRAME_PATH) for obstacle in obstacles: if obstacle.has_collision(frame_pos_y, frame_pos_x): gameover_coroutine = show_gameover(canvas, gameover_frame) coroutines.append(gameover_coroutine) return
async def run_spaceship(canvas): global year global spaceship_frame global coroutines global obstacles global spaceship_frame max_available_row, max_available_column = get_terminal_size() row, column = max_available_row - 10, max_available_column / 2 row_speed = column_speed = 0 while True: current_year = year.get('current_year') frame_rows_number, frame_columns_number = get_frame_size( spaceship_frame) prev_sprite_row, prev_sprite_column = row, column prev_spaceship_frame = spaceship_frame row_pos, column_pos, space = read_controls(canvas) row_speed, column_speed = update_speed(row_speed, column_speed, row_pos, column_pos) row += row_pos + row_speed column += column_pos + column_speed if space and current_year >= 2020: # for gun position in the center of the spaceship column_for_fire = column + 2 fire_animation = fire(canvas, row, column_for_fire, rows_speed=FIRE_SPEED) coroutines.append(fire_animation) row = correct_row(max_available_row, row, frame_rows_number) column = correct_column(max_available_column, column, frame_columns_number) for obstacle in obstacles: if obstacle.has_collision(row, column): draw_frame(canvas, prev_sprite_row, prev_sprite_column, prev_spaceship_frame, negative=True) coroutines.append(show_gameover(canvas)) return await asyncio.sleep(0) draw_frame(canvas, prev_sprite_row, prev_sprite_column, prev_spaceship_frame, negative=True) draw_frame(canvas, row, column, spaceship_frame, negative=False)
async def run_spaceship(canvas, start_row, start_column): """Display animation of a spaceship.""" spaceship_frame_files = [ os.path.join(SPACESHIP_FRAMES_FOLDER, file) for file in os.listdir(SPACESHIP_FRAMES_FOLDER) ] spaceship_frames = read_frames(spaceship_frame_files) tics_between_animations = 2 max_rows, max_columns = (max_coordinate - BORDER_LENGTH for max_coordinate in canvas.getmaxyx()) min_rows = min_columns = BORDER_LENGTH row, column = start_row, start_column row_speed = column_speed = 0 spaceship_animations_cycle = itertools.chain.from_iterable( [[frame] * tics_between_animations for frame in spaceship_frames]) for spaceship_frame in itertools.cycle(spaceship_animations_cycle): rows_direction, columns_direction, fire_button_pressed = read_controls( canvas) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction) row = row + row_speed column = column + column_speed spaceship_size_rows, spaceship_size_columns = get_frame_size( spaceship_frame) row = max(row, min_rows) row = min(row, max_rows - spaceship_size_rows) column = max(column, min_columns) column = min(column, max_columns - spaceship_size_columns) if fire_button_pressed and year >= GUN_AVAILABLE_YEAR: spaceship_center_column = column + spaceship_size_columns // 2 coroutines.append( draw_fire(canvas, start_row=row, start_column=spaceship_center_column)) draw_frame(canvas, row, column, spaceship_frame) await sleep() draw_frame(canvas, row, column, spaceship_frame, negative=True) for obstacle in obstacles: if obstacle.has_collision(row, column, spaceship_size_rows, spaceship_size_columns): obstacles_in_last_collisions.append(obstacle) coroutines.append(show_gameover(canvas)) return
def read_controls(canvas): """Read keys pressed and returns tuple witl controls state.""" rows_direction = columns_direction = 0 space_pressed = False row_speed = column_speed = 0 while True: pressed_key_code = canvas.getch() if pressed_key_code == -1: # https://docs.python.org/3/library/curses.html#curses.window.getch break if pressed_key_code == UP_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, -1, 0) if pressed_key_code == DOWN_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, 1, 0) if pressed_key_code == RIGHT_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, 0, 1) if pressed_key_code == LEFT_KEY_CODE: row_speed, column_speed = update_speed(row_speed, column_speed, 0, -1) if pressed_key_code == SPACE_KEY_CODE: space_pressed = True rows_direction += row_speed columns_direction += column_speed return rows_direction, columns_direction, space_pressed
async def animate_spaceship(canvas, row, column, frames): """Spaceship animation with keyboard control and limitts""" # get max size of the canvas rows, columns = canvas.getmaxyx() max_row, max_column = rows - 1, columns - 1 row_speed = column_speed = 0 while True: for frame in frames: # read keyboard and move ship or fire rows_direction, columns_direction, space = read_controls(canvas, 1) row_speed, column_speed = update_speed(row_speed, column_speed, rows_direction, columns_direction, RAW_SPACE_SPEED, COLUMN_SPACE_SPEED) row += row_speed column += column_speed # calculate max coordinates for ship frame_row, frame_column = get_frame_size(frame) row = min(row, max_row - frame_row) row = max(1, row) column = min(column, max_column - frame_column) column = max(1, column) if space: coroutines.append( fire(canvas, row, column + round(frame_column / 2), FIRE_SPEED)) # draw frame for 0.2 second draw_frame(canvas, row, column, frame, negative=False) # check collision for obs_id, obs in obstacles.items(): if obs.has_collision((row, column)): obstacles_to_stop.append(obs_id) coroutines.append(show_gameover(canvas)) draw_frame(canvas, row, column, frame, negative=True) return # check collision await sleep(2) # erase frame draw_frame(canvas, row, column, frame, negative=True)
async def run_spaceship(canvas): spaceship_frames = get_frames_from_file(*SPACESHIP_FRAMES) frame_size_x, frame_size_y = get_frame_size(spaceship_frames[0]) rows_number, columns_number = canvas.getmaxyx() spaceship_pos_row = (rows_number - frame_size_y) // 2 spaceship_pos_column = (columns_number - frame_size_x) // 2 speed_row = speed_column = 0 while True: for spaceship_frame in cycle(spaceship_frames): rows_direction, columns_direction, \ space_direction = read_controls(canvas) speed_row, speed_column = update_speed(speed_row, speed_column, rows_direction, columns_direction) position_max_row = rows_number - frame_size_x - BORDER_SIZE position_min_row = spaceship_pos_row + speed_row position_max_column = columns_number - frame_size_y - BORDER_SIZE position_min_column = spaceship_pos_column + speed_column spaceship_pos_row = min(position_max_row, max(BORDER_SIZE, position_min_row)) spaceship_pos_column = min(position_max_column, max(BORDER_SIZE, position_min_column)) if space_direction and globals_vars.year >= SHOOTING_YEAR: make_fire(canvas, spaceship_pos_row, spaceship_pos_column) draw_frame(canvas, spaceship_pos_row, spaceship_pos_column, spaceship_frame) await asyncio.sleep(0) draw_frame(canvas, spaceship_pos_row, spaceship_pos_column, spaceship_frame, negative=True) for obstacle in globals_vars.obstacles: if obstacle.has_collision(spaceship_pos_row, spaceship_pos_column, frame_size_x, frame_size_y): globals_vars.coroutines.append(show_game_over(canvas)) return False
async def run_spaceship(canvas, start_row, start_column): row_number, column_number = canvas.getmaxyx() max_row = row_number - BORDER_SIZE max_column = column_number - BORDER_SIZE row_speed = column_speed = 0 while True: row_direction, column_direction, pressed_space = read_controls(canvas) row_speed, column_speed = update_speed( row_speed, column_speed, row_direction / 10, column_direction / 10 ) new_row = start_row + row_speed new_column = start_column + column_speed ship_height, ship_width = get_frame_size(spaceship_frame) frame_max_row = new_row + ship_height frame_max_column = new_column + ship_width new_row = min(frame_max_row, max_row) - ship_height new_column = min(frame_max_column, max_column) - ship_width new_row = max(new_row, BORDER_SIZE) new_column = max(new_column, BORDER_SIZE) start_row, start_column = new_row, new_column draw_frame(canvas, start_row, start_column, spaceship_frame) drawn_frame = spaceship_frame if pressed_space and year >= GUN_YEAR: fire_column = start_column + OFFSET_TO_SPACESHIP_EDGE coroutines.append(fire(canvas, start_row, fire_column)) await sleep() draw_frame(canvas, start_row, start_column, drawn_frame, negative=True) ship_collided = False for obstacle in obstacles: ship_collided = ship_collided or obstacle.has_collision( start_row, start_column, obj_size_rows=ship_height, obj_size_columns=ship_width ) if ship_collided: break await show_gameover(canvas)
def update_speed(self, multiplier): key_list = p.key.get_pressed() throttle = False brake = False if key_list[UP] == 1: throttle = True else: engine_sound.stop() if key_list[DOWN] == 1: brake = True self.speed = physics.update_speed(self.speed, throttle, brake, self.terrain, multiplier)