def register_afv(afv_surface: pygame.Surface, entities_manager: ecs.EntitiesManager, afv: ecs.Entity) -> None: afv["GraphicComponent"] = ecs.GraphicComponent(afv_surface, AFV_INITIAL_POSITION[0], AFV_INITIAL_POSITION[1]) afv["HorizontalOrientationComponent"] = ecs.HorizontalOrientationComponent(afv_surface, pygame.transform.flip(afv_surface, True, False)) afv["VelocityComponent"] = ecs.VelocityComponent(AFV_VELOCITY[0], AFV_VELOCITY[1]) entities_manager.register_entity(afv)
def shot_at_aliens_handler(shot: ecs.Entity, aliens: List[ecs.Entity], collision_indices: List[int], entities_manager: ecs.EntitiesManager) -> None: killed_alien = aliens[collision_indices[0]] killed_alien_rect = killed_alien["GraphicComponent"].rect explosions_factory(killed_alien_rect.center[0], killed_alien_rect.center[1]) curr_score[0] += alien_hit_reward ecs.rewrite_text_system(screen, background, dirty_rects, score, "Score: {}".format(curr_score[0])) entities_manager.unregister_and_discharge_entity_from_all_groups(killed_alien) entities_manager.unregister_and_discharge_entity_from_all_groups(shot)
def register_and_enlist_alien(images: List[pygame.Surface], entities_manager: ecs.EntitiesManager) -> None: alien = dict() alien["GraphicComponent"] = ecs.GraphicComponent(images[ImgsIndices.alien1], ALIEN_INITIAL_POSITION[0], ALIEN_INITIAL_POSITION[1]) alien["AnimationCycleComponent"] = ecs.AnimationCycleComponent((images[ImgsIndices.alien1], images[ImgsIndices.alien2], images[ImgsIndices.alien3]), ALIEN_ANIMATION_INTERVAL_LENGTH) alien["VelocityComponent"] = ecs.VelocityComponent(ALIEN_VELOCITY[0], ALIEN_VELOCITY[1]) entities_manager.register_and_enlist_entity(alien, "aliens")
def afv_collision_handler(collided_entities: List[ecs.Entity], collided_entity_idx: int, entities_manager: ecs.EntitiesManager) -> None: curr_life[0] -= life_penalty ecs.rewrite_text_system(screen, background, dirty_rects, lives, "Lives: {}".format(curr_life[0])) explosion_factory(afv_rect.center[0], afv_rect.center[1]) collided_entity_groups = entities_manager.get_entity_groups(collided_entities[collided_entity_idx]) if "aliens" in collided_entity_groups: alien_rect = collided_entities[collided_entity_idx]["GraphicComponent"].rect explosion_factory(alien_rect.center[0], alien_rect.center[1])
def game_loop(screen: pygame.Surface, background: pygame.Surface, images: List[pygame.Surface], sounds: List[pygame.mixer.Sound], entities_manager: ecs.EntitiesManager, afv: ecs.Entity, lives: ecs.Entity, score: ecs.Entity) -> None: alien_factory = get_aliens_factory(images[ImgsIndices.alien1], (images[ImgsIndices.alien1], images[ImgsIndices.alien2], images[ImgsIndices.alien3]), entities_manager) bomb_factory = get_bomb_factory(images[ImgsIndices.bomb], entities_manager) shot_factory = get_shot_factory(images[ImgsIndices.shot], sounds[SoundIndices.shot], entities_manager) explosion_factory = get_explosion_factory(images[ImgsIndices.explosion], sounds[SoundIndices.explosion], entities_manager) right_edge = background.get_width() bomb_bottom_edge = background.get_height() - images[ImgsIndices.explosion].get_height() + BOMB_EDGE_OFFSET afv_rect = afv["GraphicComponent"].rect afv_tpl = (afv,) afv_off_bounds_handler = get_afv_off_bounds_handler(right_edge) aliens_off_bounds_handler = get_aliens_off_bounds_handler(right_edge) shots_off_bounds_handler = get_shots_off_bounds_handler(entities_manager) bombs_off_bounds_handler = get_bombs_off_bounds_handler(entities_manager, bomb_bottom_edge, explosion_factory) is_player_reloading = False curr_life = [INITIAL_PLAYER_LIFE] curr_score = [INITIAL_PLAYER_SCORE] dirty_rects = list() handle_afv_collision = get_afv_collision_handler(afv_rect, lives, curr_life, LIFE_PENALTY, explosion_factory, screen, background, dirty_rects) shot_at_aliens_handler = get_shot_at_aliens_handler(explosion_factory, curr_score, ALIEN_HIT_REWARD, score, screen, background, dirty_rects) screen.blit(background, (0, 0)) pygame.display.flip() sounds[SoundIndices.background_music].play(REPEAT_INDEFINITELY) clock = pygame.time.Clock() while curr_life[0] > 0: pygame.event.pump() keys_state = pygame.key.get_pressed() if keys_state[pygame.K_ESCAPE] or pygame.event.peek(pygame.QUIT): break ecs.erase_system(screen, background, entities_manager.get_all_instances_of_component_class("GraphicComponent"), dirty_rects) explosions_list = list(entities_manager.get_all_entities_of_group("explosions")) explosions_lifetime_handler = Thread(target=ecs.decrease_lifetime_system, args=(explosions_list, entities_manager)) explosions_lifetime_handler.start() if random() < ALIEN_INSTANTIATION_PROBABILITY: alien_factory(ALIEN_INITIAL_POSITION[0], ALIEN_INITIAL_POSITION[1]) aliens_list = list(entities_manager.get_all_entities_of_group("aliens")) if aliens_list and random() < BOMB_INSTANTIATION_PROBABILITY: last_alien_rect = aliens_list[-1]["GraphicComponent"].rect if 0 < last_alien_rect.left and last_alien_rect.right < right_edge: bomb_initial_x, bomb_initial_y = last_alien_rect.move(BOMB_OFFSET[0], BOMB_OFFSET[1]).midbottom bomb_factory(bomb_initial_x, bomb_initial_y) bombs_list = list(entities_manager.get_all_entities_of_group("bombs")) shots_list = list(entities_manager.get_all_entities_of_group("shots")) if keys_state[pygame.K_SPACE] and not is_player_reloading and len(shots_list) < MAX_SHOTS_ON_SCREEN: newest_shot = shot_factory(afv_rect.centerx, afv_rect.top - SHOT_OFFSET) shots_list.append(newest_shot) is_player_reloading = keys_state[pygame.K_SPACE] shots_mover = Thread(target=ecs.move_system, args=(shots_list, shots_off_bounds_handler)) shots_mover.start() aliens_mover = Thread(target=ecs.move_system, args=(aliens_list, aliens_off_bounds_handler)) aliens_mover.start() aliens_colors_changer = Thread(target=ecs.rotate_animation_cycle_system, args=(aliens_list,)) aliens_colors_changer.start() bombs_mover = Thread(target=ecs.move_system, args=(bombs_list, bombs_off_bounds_handler)) bombs_mover.start() x_direction = keys_state[pygame.K_RIGHT] - keys_state[pygame.K_LEFT] if x_direction != NO_MOVEMENT: ecs.move_system(afv_tpl, afv_off_bounds_handler, x_direction) shots_mover.join() aliens_mover.join() aliens_colors_changer.join() bombs_mover.join() aliens_collisions_handler = Thread(target=ecs.lists_collision_detection_with_handling_system, args=(shots_list, aliens_list, entities_manager, shot_at_aliens_handler)) aliens_collisions_handler.start() afv_collision_handler = Thread(target=ecs.collision_detection_with_handling_system, args=(afv, bombs_list + aliens_list, entities_manager, handle_afv_collision)) afv_collision_handler.start() aliens_collisions_handler.join() afv_collision_handler.join() explosions_lifetime_handler.join() ecs.draw_system(screen, entities_manager.get_all_instances_of_component_class("GraphicComponent"), dirty_rects) pygame.display.update(dirty_rects) dirty_rects.clear() clock.tick(FRAMES_PER_SECOND) pygame.mixer.fadeout(FADEOUT_TIME) pygame.time.wait(FADEOUT_TIME)
def register_score(entities_manager: ecs.EntitiesManager, score: ecs.Entity) -> None: score["TextComponent"] = ecs.TextComponent("Score: {}".format(INITIAL_PLAYER_SCORE), SCORE_TEXT_SIZE, SCORE_TEXT_COLOR) score_surface = score["TextComponent"].font.render(score["TextComponent"].text, False, score["TextComponent"].color) score["GraphicComponent"] = ecs.GraphicComponent(score_surface, SCORE_POSITION[0], SCORE_POSITION[1]) entities_manager.register_entity(score)
def register_lives(entities_manager: ecs.EntitiesManager, lives: ecs.Entity) -> None: lives["TextComponent"] = ecs.TextComponent("Lives: {}".format(INITIAL_PLAYER_LIFE), LIVES_TEXT_SIZE, LIVES_TEXT_COLOR) lives_surface = lives["TextComponent"].font.render(lives["TextComponent"].text, False, lives["TextComponent"].color) lives["GraphicComponent"] = ecs.GraphicComponent(lives_surface, LIVES_POSITION[0], LIVES_POSITION[1]) entities_manager.register_entity(lives)
def add_explosions_group(entities_manager: ecs.EntitiesManager) -> None: entities_manager.add_group("explosions")
def add_shots_group(entities_manager: ecs.EntitiesManager) -> None: entities_manager.add_group("shots")
def add_bombs_group(entities_manager: ecs.EntitiesManager) -> None: entities_manager.add_group("bombs")