Ejemplo n.º 1
0
def main():

    sm = SceneManager()
    sm.instantiate(sm)

    snd_mngr = SoundManager()
    snd_mngr.instantiate(snd_mngr)

    pl = Player('player.png', 400)
    pl.event.register_listener(snd_mngr.event_listener)
    pl.instantiate(pl, pygame.math.Vector2(0, 0), 0)

    item = Item()
    item.event.register_listener(pl.event_listener)
    item.instantiate(item)

    while (True):
        display.screen.fill((0, 50, 0))
        gb.updateAll()

        event = pygame.event.poll()
        if event.type == pygame.QUIT:
            break

        #text = text_field.create_text("Hello, World", ["comicsansms"], 72, (0, 128, 0))

        #display.screen.blit(text,
        #(320 - text.get_width() // 2, 240 - text.get_height() // 2))

        pygame.display.flip()
        utils.clock.tick(60)
Ejemplo n.º 2
0
    def __init__(self, resolution, level):
        super().__init__()
        self.sound = SoundManager()
        self.resolution = resolution
        self.state = res.STATE_RUNNING
        self.life = 3
        self.level = level
        self.standard_shader = StandardShaderProgram()
        self.delta = 0.00001
        self.light_setup = res.LightSetup(
            global_ambient=glm.vec3(0.3, 0.3, 0.3))
        self.controls = res.GameControlState()
        self.model_registry = res.ModelRegistry()
        self.camera_id = 0
        self.view_matrix = glm.mat4(1.0)
        self.maze_width = 30
        self.maze_length = 30
        self.maze = _setup_maze(self,
                                self.maze_width,
                                self.maze_length,
                                depth=1.5)

        self._setup_systems()
        self._setup_entities()
        self._setup_level_objects()
        self.update_resolution(resolution)
Ejemplo n.º 3
0
    def load(self):
        self.sprite_group = Group()

        self.label_font = self.res.font64
        self.button_play = Button(
            self.res, ((WIDTH - self.res.image_button.get_width()) / 2, 240),
            'Играть', self.sprite_group)
        self.button_drift = Button(
            self.res, ((WIDTH - self.res.image_button.get_width()) / 2, 300),
            'Дрифт', self.sprite_group)
        self.button_shop = Button(
            self.res, ((WIDTH - self.res.image_button.get_width()) / 2, 360),
            'Магазин', self.sprite_group)
        self.button_exit = Button(
            self.res, ((WIDTH - self.res.image_button.get_width()) / 2, 420),
            'Выход', self.sprite_group)

        self.dollars = Dollars(self.res, self.sprite_group)
        self.sm = SoundManager(None, None)
        self.sm.set_background(self.res.music_bg_menu, 0.3)

        # Задний фон для меню
        self.world = b2World()
        self.world.gravity = 0, 0
        self.contact_listener = ContactListener()
        self.world.contactListener = self.contact_listener
        self.obj_args = self.world, self.contact_listener, self.res
        self.animation_background = pygame.Surface((500, 300)).convert_alpha()
        self.animation_background.fill((0, 0, 0, 0))
        self.background_group = Group()
        self.spawn_random_car()
        self.spawn_timer = 0
        self.spawn_timeout = 1.5
        self.spawn_counter = 0
        self.background_camera = Camera(self.background_group)
Ejemplo n.º 4
0
    def __init__(self):
        pg.init()
        pg.font.init()
        pg.display.set_caption("TETRIS")

        self.sound_manager = SoundManager()
        pg.mixer.music.load("Sounds/Music.mp3")
        pg.mixer.music.set_volume(0.3)
        pg.mixer.music.play(-1)

        self.main_surface = pg.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        self.playground_surf = pg.Surface(
            (GRID_SIZE[0] * CELL_SIZE * UI_SCALE,
             GRID_SIZE[1] * CELL_SIZE * UI_SCALE))
        self.next_surf = pg.Surface((220 * UI_SCALE, 220 * UI_SCALE))

        self.font = pg.font.Font("Fonts/ARCADECLASSIC.TTF",
                                 int(FONT_SIZE * UI_SCALE))

        if "top.scr" in os.listdir():
            with open("top.scr") as file:
                self.top = int(file.read())
        else:
            self.top = 0

        self.score = 0
        self.lines = 0

        self.colors = np.zeros(GRID_SIZE, dtype=object)
        self.grid_colliders = np.zeros(GRID_SIZE)

        self.cur_shape = Shape(self, 5, -1)
        self.next_shape = Shape(self, 5, -1)

        self.game_over = False
Ejemplo n.º 5
0
class LevelState(GameState):
    def load(self):
        self.levels = Level.levels
        self.level = self.levels[self.asm.main.completed_levels]
        self.is_over = False
        self.saved = False
        self.over_timer = 0
        self.over_timeout = 1
        self.text = self.level[1]

        super().load()

        self.button = Button(self.res, (WIDTH - 120, HEIGHT - 70), 'Меню',
                             self.sprite_group)
        self.minimap = Minimap(300, 240, self.sprite_group)
        self.conversation = Conversation(self.res, self.sprite_group)
        self.police_effect = PoliceEffect(self.sprite_group)
        self.energy_line = EnergyLine(self.res, self.sprite_group)
        self.dollars = Dollars(self.res, self.sprite_group, level=True)

        self.sm = SoundManager(self.conversation, self.car, self.sprite_group)
        self.load_map(self.level[0])
        self.sm.player_car = self.car
        self.sm.set_background(self.res.music_bg_game, 0.1)

    def update(self, dt, events):
        self.dollars.value = self.car.dollars
        self.dollars.set_darkness_value(self.darkness.value)

        if self.is_over:
            self.over_timer += dt
        if self.over_timer >= self.over_timeout and not self.saved:
            self.saved = True
            if self.car.looted:
                self.asm.main.dollars += self.car.dollars
                self.asm.main.completed_levels = min(
                    self.asm.main.completed_levels + 1,
                    len(self.levels) - 1)
                self.asm.main.write_save()
                self.conversation.show(
                    ['Esc - выход, Space - следующий уровень'],
                    event_listener=self.end_event_listener)
            else:
                self.conversation.show(['Esc - выход, Space - начать заново'],
                                       event_listener=self.end_event_listener)

        if super().update(dt, events) is False:
            return
        self.energy_line.set_energy(self.car.energy)

        if not self.is_over and self.car.looted and not self.conversation.is_showing:
            self.conversation.show(['Вы победили'],
                                   lambda: self.__setattr__('is_over', True))

        if not self.is_over and not self.car.energy and not self.conversation.is_showing:
            self.sm.set_background(self.res.sound_lose, 1)
            self.conversation.show(['Вы потеряли энергию, игра окончена'],
                                   lambda: self.__setattr__('is_over', True))
            self.car.break_down()
Ejemplo n.º 6
0
def run_game():
    # Initialize game, settings, and create a screen object.
    pygame.init()
    settings = Settings.getInstance()
    screen = pygame.display.set_mode(
        (settings.screen_width, settings.screen_height))
    pygame.display.set_caption(settings.window_caption)

    # Make the Play button.
    play_button = Button(screen, "Play")

    # Make Groupmanager
    em = EntityManager.getInstance()

    # Make ship
    ship = Ship(screen)
    em.add_single("ship", ship)

    # Make a group to store bullets in.
    em.add_group("bullets")

    # Make a group to store aliens in
    em.add_group("aliens")

    # Create statistics and scoreboard
    stats = GameStats()
    sb = Scoreboard(settings, screen, stats)

    # Load background.
    bg = BackGround()

    # Create explosions group
    em.add_group("explosions")

    # Start background music
    SoundManager.getInstance().play_music()

    # Make power up group
    em.add_group("power_ups")

    # Start the main loop for the game.
    while True:

        # Watch for keyboard and mouse events.
        gf.check_events(screen, stats, sb, play_button)

        if stats.game_active:
            em.update_singles()
            gf.update_bullets(screen, stats, sb)
            gf.update_aliens(screen, stats, sb)
            gf.update_explosions()
            gf.update_power_ups()

        gf.update_screen(screen, bg, stats, sb, play_button)
Ejemplo n.º 7
0
 def __init__(self, root):
     self.root = root
     self.canvas = Canvas(master=self.root.root, width=448, height=448)
     self.canvas.pack(side=TOP)
     self.canvas.bind('<Motion>', self.motion)
     #self.canvas.bind('<MouseWheel>', self.zoom)
     self.canvas.bind('<Button-1>', self.click)
     self.canvas.bind('<B1-Motion>', self.click)
     self.has_image = False
     self.zoom_level = 0
     self.sound = SoundManager()
Ejemplo n.º 8
0
def create_explosion(screen, x, y):
    """ Creates an explosion """
    # Generate indices in climbing order
    cols = settings.explosion_cols
    rows = settings.explosion_rows
    indices = []
    for i in range(cols * rows):
        indices.append(i)
    # play explosion sound
    SoundManager.getInstance().explosion.play()
    # Return the explosion
    return Explosion(screen, x, y, (indices))
Ejemplo n.º 9
0
def check_keydown_events(event, screen):
    """Respond to keypresses."""
    ship = ent_man.get_single("ship")

    if event.key == pygame.K_RIGHT:
        ship.moving_right = True
    elif event.key == pygame.K_LEFT:
        ship.moving_left = True
    elif event.key == pygame.K_SPACE:
        fire_bullet(screen)
        SoundManager.getInstance().laser.play()
    elif event.key == pygame.K_q:
        sys.exit(0)
Ejemplo n.º 10
0
class LevelTransition:
    """Displays a level transition"""
    TRANSITION_CHANNEL = 4

    def __init__(self, screen, score_controller, transition_time=5000):
        self.screen = screen
        self.score_controller = score_controller
        self.sound = SoundManager(['GetLoud.wav'],
                                  keys=['transition'],
                                  channel=LevelTransition.TRANSITION_CHANNEL,
                                  volume=0.6)
        self.font = pygame.font.Font('fonts/LuckiestGuy-Regular.ttf', 32)
        self.ready_msg = self.font.render('Get Ready!', True,
                                          ScoreBoard.SCORE_WHITE)
        self.ready_msg_rect = self.ready_msg.get_rect()
        ready_pos = screen.get_width() // 2, int(screen.get_height() * 0.65)
        self.ready_msg_rect.centerx, self.ready_msg_rect.centery = ready_pos
        self.level_msg = None
        self.level_msg_rect = None
        self.transition_time = transition_time  # total time to wait until the transition ends
        self.transition_begin = None
        self.transition_show = False

    def prep_level_msg(self):
        """Prepare a message for the current level number"""
        text = 'level ' + str(self.score_controller.level)
        self.level_msg = self.font.render(text, True, ScoreBoard.SCORE_WHITE)
        self.level_msg_rect = self.level_msg.get_rect()
        level_pos = self.screen.get_width() // 2, self.screen.get_height() // 2
        self.level_msg_rect.centerx, self.level_msg_rect.centery = level_pos

    def set_show_transition(self):
        """Begin the sequence for displaying the transition"""
        self.prep_level_msg()
        self.transition_begin = pygame.time.get_ticks()
        self.transition_show = True
        self.sound.play('transition')

    def draw(self):
        """Display the level transition to the screen"""
        if abs(self.transition_begin -
               pygame.time.get_ticks()) > self.transition_time:
            self.transition_show = False
        else:
            self.screen.fill((0, 0, 0))
            self.screen.blit(self.level_msg, self.level_msg_rect)
            if abs(self.transition_begin -
                   pygame.time.get_ticks()) >= self.transition_time // 2:
                self.screen.blit(self.ready_msg, self.ready_msg_rect)
Ejemplo n.º 11
0
 def __init__(self, screen, user, maze):
     self.screen = screen
     self.maze = maze
     self.user = user
     self.sound_manager = SoundManager(
         sound_files=['portal-open.wav', 'portal-travel.wav'],
         keys=['open', 'travel'],
         channel=PortalController.PORTAL_AUDIO_CHANNEL)
     self.blue_portal = pygame.sprite.GroupSingle(
     )  # portals as GroupSingle, which only allows one per group
     self.blue_projectile = None
     self.orange_portal = pygame.sprite.GroupSingle()
     self.orange_projectile = None
     # converter for projectile direction to portal direction
     self.portal_directions = {'l': 'r', 'r': 'l', 'u': 'd', 'd': 'u'}
Ejemplo n.º 12
0
 def __create_game(self, gender, name, loadLast):
     self.started = True
     self.__clock = pygame.time.Clock()
     self.__sound_manager = SoundManager()
     app_loader = AppLoader(gender, name)
     bars_loader = app_loader.get_status_bars_loader()
     self.__game_man = app_loader.get_game_manager()
     if loadLast: self.load_game()
     # windows_controller asociado al screen
     self.windows_controller = SaludameWindowsController(
         self.__screen, self.__game_man)
     self.windows_controller.create_windows_and_activate_main(
         app_loader, self.__clock, bars_loader)
     #self.hotkeys_handler = HotKeyHandler()
     self.__game_man.start(self.windows_controller)
Ejemplo n.º 13
0
 def __init__(self, screen, score_controller, transition_time=5000):
     self.screen = screen
     self.score_controller = score_controller
     self.sound = SoundManager(['pacman-beginning.wav'], keys=['transition'],
                               channel=LevelTransition.TRANSITION_CHANNEL, volume=0.6)
     self.font = pygame.font.Font('fonts/LuckiestGuy-Regular.ttf', 32)
     self.ready_msg = self.font.render('Get Ready!', True, ScoreBoard.SCORE_WHITE)
     self.ready_msg_rect = self.ready_msg.get_rect()
     ready_pos = screen.get_width() // 2, int(screen.get_height() * 0.65)
     self.ready_msg_rect.centerx, self.ready_msg_rect.centery = ready_pos
     self.level_msg = None
     self.level_msg_rect = None
     self.transition_time = transition_time     # total time to wait until the transition ends
     self.transition_begin = None
     self.transition_show = False
Ejemplo n.º 14
0
    def load(self):
        super().load()

        self.button = Button(self.res, (WIDTH - 120, HEIGHT - 70), 'Меню',
                             self.sprite_group)
        self.minimap = Minimap(300, 240, self.sprite_group)
        self.conversation = Conversation(self.res, self.sprite_group)
        self.police_effect = PoliceEffect(self.sprite_group)

        self.sm = SoundManager(self.conversation, self.car, self.sprite_group)
        self.load_map(self.res.drift_map_path)
        self.sm.player_car = self.car
        self.sm.set_background(self.res.music_bg_menu, 0.1)

        self.car.queue_lines.extend(['Свободный режим'])
Ejemplo n.º 15
0
 def __init__(self):
     pygame.init()
     pygame.mixer.music.load('sounds/IDKMAN.wav')
     self.screen = pygame.display.set_mode(
         (800, 600)
     )
     pygame.display.set_caption('PacMan Portal')
     self.clock = pygame.time.Clock()
     self.score_keeper = ScoreController(screen=self.screen,
                                         sb_pos=((self.screen.get_width() // 5),
                                                 (self.screen.get_height() * 0.965)),
                                         items_image='cherry.png',
                                         itc_pos=(int(self.screen.get_width() * 0.6),
                                                  self.screen.get_height() * 0.965))
     self.maze = Maze(screen=self.screen, maze_map_file='maze_map.txt')
     self.life_counter = PacManCounter(screen=self.screen, ct_pos=((self.screen.get_width() // 3),
                                                                   (self.screen.get_height() * 0.965)),
                                       images_size=(self.maze.block_size, self.maze.block_size))
     self.level_transition = LevelTransition(screen=self.screen, score_controller=self.score_keeper)
     self.game_over = True
     self.pause = False
     self.player = PacMan(screen=self.screen, maze=self.maze)
     self.ghosts = pygame.sprite.Group()
     self.ghost_sound_manager = SoundManager(sound_files=['RunForestRun.wav', 'Eaten3.wav', 'babySharkPacman.wav'],
                                             keys=['blue', 'eaten', 'std'],
                                             channel=Ghost.GHOST_AUDIO_CHANNEL)
     self.ghost_active_interval = 2500
     self.ghosts_to_activate = None
     self.first_ghost = None
     self.other_ghosts = []
     self.spawn_ghosts()
     self.actions = {PacManPortalGame.START_EVENT: self.init_ghosts,
                     PacManPortalGame.REBUILD_EVENT: self.rebuild_maze,
                     PacManPortalGame.LEVEL_TRANSITION_EVENT: self.next_level}
Ejemplo n.º 16
0
    def __init__(self, screen, maze):
        super().__init__()
        self.screen = screen
        self.radius = maze.block_size // 5
        self.maze = maze
        self.sound_manager = SoundManager(sound_files=['pacman-pellet-eat.wav', 'pacman-fruit-eat.wav',
                                                       'pacman-killed.wav', 'pacman-portal.wav'],
                                          keys=['eat', 'fruit', 'dead', 'portal'],
                                          channel=PacMan.PAC_AUDIO_CHANNEL)
        self.horizontal_images = ImageManager('pacman-horiz.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                           (32, 0, 32, 32),
                                                                                           (0, 32, 32, 32),
                                                                                           (32, 32, 32, 32),
                                                                                           (0, 64, 32, 32)],
                                              resize=(self.maze.block_size, self.maze.block_size),
                                              reversible=True)
        self.vertical_images = ImageManager('pacman-vert.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                        (32, 0, 32, 32),
                                                                                        (0, 32, 32, 32),
                                                                                        (32, 32, 32, 32),
                                                                                        (0, 64, 32, 32)],
                                            resize=(self.maze.block_size, self.maze.block_size),
                                            reversible=True)
        self.death_images = ImageManager('pacman-death.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                      (32, 0, 32, 32),
                                                                                      (0, 32, 32, 32),
                                                                                      (32, 32, 32, 32),
                                                                                      (0, 64, 32, 32),
                                                                                      (32, 64, 32, 32)],
                                         resize=(self.maze.block_size, self.maze.block_size),
                                         animation_delay=150, repeat=False)
        self.flip_status = {'use_horiz': True, 'h_flip': False, 'v_flip': False}
        self.spawn_info = self.maze.player_spawn[1]
        self.tile = self.maze.player_spawn[0]
        self.direction = None
        self.moving = False
        self.speed = maze.block_size // 7
        self.image, self.rect = self.horizontal_images.get_image()
        self.rect.centerx, self.rect.centery = self.spawn_info   # screen coordinates for spawn
        self.dead = False
        self.portal_controller = PortalController(screen, self, maze)   # controller object for portal

        # Keyboard related events/actions/releases
        self.event_map = {pygame.KEYDOWN: self.perform_action, pygame.KEYUP: self.reset_direction}
        self.action_map = {pygame.K_UP: self.set_move_up, pygame.K_LEFT: self.set_move_left,
                           pygame.K_DOWN: self.set_move_down, pygame.K_RIGHT: self.set_move_right,
                           pygame.K_q: self.blue_portal, pygame.K_w: self.orange_portal}
Ejemplo n.º 17
0
class LevelTransition:
    TRANSITION_CHANNEL = 4

    def __init__(self, screen, score_controller, transition_time=5000):
        self.screen = screen
        self.score_controller = score_controller
        self.sound = SoundManager(['pacman-beginning.wav'],
                                  keys=['transition'],
                                  channel=LevelTransition.TRANSITION_CHANNEL,
                                  volume=0.6)
        self.font = pygame.font.Font('fonts/LuckiestGuy-Regular.ttf', 32)
        self.ready_msg = self.font.render('Get Ready!', True, ScoreBoard.WHITE)
        self.ready_msg_rect = self.ready_msg.get_rect()
        ready_pos = screen.get_width() // 2, int(screen.get_height() * 0.65)
        self.ready_msg_rect.centerx, self.ready_msg_rect.centery = ready_pos
        self.level_msg = None
        self.level_msg_rect = None
        self.transition_time = transition_time
        self.transition_begin = None
        self.transition_show = False

    def prep_level_msg(self):
        text = 'level ' + str(self.score_controller.level)
        self.level_msg = self.font.render(text, True, ScoreBoard.WHITE)
        self.level_msg_rect = self.level_msg.get_rect()
        level_pos = self.screen.get_width() // 2, self.screen.get_height() // 2
        self.level_msg_rect.centerx, self.level_msg_rect.centery = level_pos

    def set_show_transition(self):
        self.prep_level_msg()
        self.transition_begin = pygame.time.get_ticks()
        self.transition_show = True
        self.sound.play('transition')

    def draw(self):
        if abs(self.transition_begin -
               pygame.time.get_ticks()) > self.transition_time:
            self.transition_show = False
        else:
            self.screen.fill((0, 0, 0))
            self.screen.blit(self.level_msg, self.level_msg_rect)
            if abs(self.transition_begin -
                   pygame.time.get_ticks()) >= self.transition_time // 2:
                self.screen.blit(self.ready_msg, self.ready_msg_rect)
Ejemplo n.º 18
0
def main():
    GameData(SCREEN_TITLE)
    # SpriteCache()
    GameData.data['player_level'] = 1
    GameData.data['player_xp'] = 0
    window = arcade.Window(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_TITLE)
    sound_manager = SoundManager(window)
    loading_view = menu_views.LoadingMenuView(window, sound_manager)
    window.show_view(loading_view)
    arcade.run()
Ejemplo n.º 19
0
    def load(self):
        self.levels = Level.levels
        self.level = self.levels[self.asm.main.completed_levels]
        self.is_over = False
        self.saved = False
        self.over_timer = 0
        self.over_timeout = 1
        self.text = self.level[1]

        super().load()

        self.button = Button(self.res, (WIDTH - 120, HEIGHT - 70), 'Меню',
                             self.sprite_group)
        self.minimap = Minimap(300, 240, self.sprite_group)
        self.conversation = Conversation(self.res, self.sprite_group)
        self.police_effect = PoliceEffect(self.sprite_group)
        self.energy_line = EnergyLine(self.res, self.sprite_group)
        self.dollars = Dollars(self.res, self.sprite_group, level=True)

        self.sm = SoundManager(self.conversation, self.car, self.sprite_group)
        self.load_map(self.level[0])
        self.sm.player_car = self.car
        self.sm.set_background(self.res.music_bg_game, 0.1)
Ejemplo n.º 20
0
    def __init__(self, config, level_name):
        self.config = config
        self.physics_manager = PhysicsManager()
        self.material_manager = MaterialManager(config["material_file"])
        self.transmutation_manager = TransmutationManager(self.material_manager)
        self.transmutation_manager.blow_key = "stone"
        self.level = Level("{0}/{1}.lvl".format(config["levels_dir"], level_name), self.physics_manager, self.material_manager)

        self.main_char = Player.genMainCharacter()
        self.main_char.physical.position = [25, 10]
        self.level.actors.append(self.main_char)

        self.viewport = Viewport(config["width"], config["height"], self.main_char, self.level, 100)
        self.picking_handler = PickingHandler(self.viewport, self.transmutation_manager, self.physics_manager)

        self.ui_overlay = UIOverlay(config["font_file"])
        self.ui_overlay.text_elements["score"] = TextElement((20, 20), 20, (0, 0, 0), "0 pts")

        self.physics_manager.add_actor(self.main_char)
        self._highlight_actors = False

        self.sound_manager = SoundManager()
        self.sound_manager.actors.append(self.main_char)
Ejemplo n.º 21
0
    def start(self):
        #spawn initial GameObjects here like so:
        self._game.instantiate(
            Background(self._game, "Background", "background.png", 0, 0))
        self._game.instantiate(
            SoundManager(self._game, "SoundManager", "unknown.png", -1, -1))
        self._game.instantiate(
            UIManager(self._game, "UIManager", "unknown.png", -1, -1))
        self.soundManager = self._game.getGameObjectByName("SoundManager")
        self.uiManager = self._game.getGameObjectByName("UIManager")

        #Music is here but I've disabled it for now
        #self.soundManager.play_music("background.wav")

        self._game.instantiate(
            Player(self._game, "Player", "player.png", 100, 500))
        self.player = self._game.getGameObjectByName("Player")

        for i in range(0, 9):
            self._game.instantiate(
                Enemy(self._game, "Enemy", "enemy.png", 80 * i, 50))

        self.scoreFont = pygame.font.Font('freesansbold.ttf', 16)
        self.gameOverFont = pygame.font.Font('freesansbold.ttf', 64)
Ejemplo n.º 22
0
class World(esper.World):
    def __init__(self, resolution, level):
        super().__init__()
        self.sound = SoundManager()
        self.resolution = resolution
        self.state = res.STATE_RUNNING
        self.life = 3
        self.level = level
        self.standard_shader = StandardShaderProgram()
        self.delta = 0.00001
        self.light_setup = res.LightSetup(
            global_ambient=glm.vec3(0.3, 0.3, 0.3))
        self.controls = res.GameControlState()
        self.model_registry = res.ModelRegistry()
        self.camera_id = 0
        self.view_matrix = glm.mat4(1.0)
        self.maze_width = 30
        self.maze_length = 30
        self.maze = _setup_maze(self,
                                self.maze_width,
                                self.maze_length,
                                depth=1.5)

        self._setup_systems()
        self._setup_entities()
        self._setup_level_objects()
        self.update_resolution(resolution)

    def cleanup(self):
        """
        cleanup... cleanup so what's the story behind this cleanup method why wouldn't I just use `__del__`?
        Well let me tell you the stupidest thing I've found in Python so far... Do you think that
        `del object` calls `object.__del__`? Well you would be kind of right because it does... but not right away.
        YES yes trust me. It queues the `__del__` call. This is usually fine but not here do you want to guess why?
        Well the `__del__` of the VBOs get called after the destruction of PyOpenGL. Now HOW, tell me HOW should I
        destruct a VBO if the OpenGL bindings are unavailable????

        Now calm down and be happy that you've solved this bug after 4 total hours of debugging......
        ~ xFrednet
        """
        for _entity, vbo in self.get_component(StandardShaderVertexArray):
            vbo.cleanup()

        self.model_registry.cleanup()
        self.standard_shader.cleanup()

        print("World: Cleanup complete")

    def _setup_systems(self):
        #
        # Physics
        #
        consys.add_systems_1_to_world(self)
        psys.add_physics_systems_to_world(self)

        #
        # Rendering
        #
        # Prepare
        consys.add_systems_2_to_world(self)
        self.add_processor(rsys.PrepareFrameSystem())
        rsys3d.add_systems_to_world(self)
        self.add_processor(rsys.FinishFrameSystem())

    def _setup_entities(self):
        # Crappy mixed entity, OOP is a thing... well actually an object...
        # WTF. I'm always amazed by the comments I leave in my code. ~xFrednet 2020.09.23
        position = glm.vec3(2.0, 2.0, 1.0)
        rotation = glm.vec3(0.0, 0.0, 0.0)
        self.player_object = self.create_entity(
            com.Model3D(
                self.model_registry.get_model_id(res.ModelRegistry.CUBE)),
            com.Transformation(position=position, rotation=rotation),
            com.TransformationMatrix(),
            com.ObjectMaterial(diffuse=glm.vec3(1.0, 0.3, 0.3)),
            com.Velocity(along_world_axis=False), com.Home(position, rotation),
            com.BoundingBox(com.Rectangle3D(1, 1, 1)),
            com.CollisionComponent(), com.PhysicsObject(),
            com.Light(attenuation=glm.vec3(0.1, 0.0, 1.0)),
            com.LightAnimation(base_color=glm.vec3(0.5, 0.2, 1.1),
                               add_color=glm.vec3(0.1, 0.1, 0.1),
                               delta_factor=0.5))

        self.player_cam = self.create_entity(
            com.ThirdPersonCamera(self.player_object, distance=4.0,
                                  pitch=-0.5), com.CameraOrientation(),
            com.Transformation())

        position = glm.vec3(-5.0, -5.0, 20.0)
        rotation = glm.vec3(0.9, -0.5, 0.0)
        self.free_cam = self.create_entity(
            com.Transformation(position=position, rotation=rotation),
            com.Velocity(along_world_axis=False, allow_paused=True),
            com.FreeCamera(), com.CameraOrientation(),
            com.Home(position, rotation))

        self.camera_id = self.player_cam

    def _setup_level_objects(self):
        # Central light
        self.create_entity(
            com.Transformation(position=glm.vec3(self.maze.center.x,
                                                 self.maze.center.y, 20.0)),
            com.Light(color=glm.vec3(0.5, 0.4, 0.4)))

        # ghost
        ghost_light_count = self.light_setup.MAX_LIGHT_COUNT - 2 - 1
        min_val = min(self.maze_width, self.maze_length)
        ghosts = self.level * min_val * 0.2
        # fallback
        if ghosts < 5:
            ghosts = 5
        for i in range(int(ghosts)):
            coord = random.randint(0, len(self.maze.empty_areas_loc) - 1)
            r = random.random()
            g = random.random()
            b = random.random()
            x, y = self.maze.empty_areas_loc[coord]
            position = glm.vec3(x, y, 2.0)
            self.ghost = self.create_entity(
                com.Model3D(
                    self.model_registry.get_model_id(res.ModelRegistry.GHOST)),
                com.Ghost(),
                com.Transformation(position=position,
                                   scale=glm.vec3(0.7, 0.7, 0.8)),
                com.TransformationMatrix(),
                com.ObjectMaterial(diffuse=glm.vec3(r, g, b)),
                com.Velocity(random.uniform(-1, 1),
                             random.uniform(-1, 1),
                             0,
                             along_world_axis=True),
                com.BoundingBox(com.Rectangle3D(1.4, 1.4, 3.0)),
                com.CollisionReport(), com.CollisionComponent(),
                com.PhysicsObject(), com.Home(position=position),
                com.Light(attenuation=glm.vec3(0.1, 0.0, 1.0),
                          enabled=(i < ghost_light_count)),
                com.LightAnimation(base_color=glm.vec3(),
                                   add_color=glm.vec3(r, g, b),
                                   delta_factor=random.uniform(0.8, 1.4)))

        self.win_object = self.create_entity(
            com.Transformation(position=glm.vec3(self.maze.center.x,
                                                 self.maze.center.y, 1.0)),
            com.Win(), com.Velocity(),
            com.BoundingBox(com.Rectangle3D(1.0, 1.0, 1.0)),
            com.CollisionReport(),
            com.Light(attenuation=glm.vec3(0.35, -0.36, 0.1)),
            com.LightAnimation(base_color=glm.vec3(1.0, 0.8, 0.0),
                               add_color=glm.vec3(0.1, 0.1, 0.1)))

    def damage_player(self):
        self.sound.pause_music()
        self.sound.play_sound('damage')
        self.life -= 1
        self.component_for_entity(self.player_object,
                                  com.ObjectMaterial).diffuse *= 0.7
        self.sound.unpause_music()
        if self.life > 1:
            print(f'You have {self.life} lives left!')
            self.home_entities()
        elif self.life == 1:
            print(f'You have {self.life} life left!')
            self.home_entities()
        else:
            print('Game Over!')
            self.sound.stop_music()
            self.end_game()

    def won_game(self):
        self.sound.stop_music()
        self.sound.play_sound('win')
        print('You winted!')
        self.end_game(False)

    def end_game(self, lost=True):
        if lost:  # to differentiate the sounds  win/lost
            self.sound.play_sound('game_over')
        # Clear collisions
        for _id, collision in self.get_component(com.CollisionReport):
            collision.failed.clear()

        # Setup top-down camera
        transform = self.component_for_entity(self.free_cam,
                                              com.Transformation)
        transform.position.x = self.maze.center.x
        transform.position.y = self.maze.center.y
        transform.position.z = 50.0
        transform.rotation = glm.vec3(0.0, -1.4, 0.0)
        self.controls.allow_camera_swap = False
        if self.controls.control_mode == res.GameControlState.PLAYER_MODE:
            self._swap_camera()

        # Animation
        self.component_for_entity(self.win_object,
                                  com.LightAnimation).enabled = False
        self.component_for_entity(self.win_object, com.Win).game_over = True

    def _swap_camera(self):
        controls: res.GameControlState = self.controls
        if controls.control_mode == res.GameControlState.PLAYER_MODE:
            self.camera_id = self.free_cam
            controls.control_mode = res.GameControlState.FREE_CAM_MODE
            self.state = res.STATE_PAUSED
        else:
            self.camera_id = self.player_cam
            controls.control_mode = res.GameControlState.PLAYER_MODE
            self.state = res.STATE_RUNNING

    def home_entities(self):
        for _id, (home, transformation,
                  velocity) in self.get_components(com.Home,
                                                   com.Transformation,
                                                   com.Velocity):
            transformation.position = home.position
            transformation.rotation = home.rotation
            velocity.value = glm.vec3()

    def update_resolution(self, resolution):
        self.resolution = resolution
        self.standard_shader.update_projection_matrix(resolution)
Ejemplo n.º 23
0
class Main(GObject.Object):
    def __init__(self, target_size=(800, 600)):

        GObject.Object.__init__(self)

        self.__target_size = target_size

        self.gender = "boy"
        self.name = ""

        self.__screen = None
        self.__clock = None
        self.__game_over_callback = None
        self.__game_man = None
        self.__sound_manager = None
        self.__running = True

        self.started = False

    def set_game_over_callback(self, callback):
        self.__game_over_callback = callback

    def main(self, size, loadLast):
        if self.started:
            self.__game_man.reset_game(self.gender)
        else:
            self.__init(size)
            self.__create_game(self.gender, self.name, loadLast)
            self.__run()

    def __init(self, size):
        self.__target_size = size
        pygame.mixer.pre_init(22050, -16, 1, 512)
        pygame.mixer.init()
        pygame.mixer.music.set_endevent(pygame.USEREVENT)
        pygame.init()
        pygame.display.set_mode(self.__target_size, pygame.DOUBLEBUF, 0)
        self.__screen = pygame.display.get_surface()
        self.__screen.blit(
            pygame.image.load(
                os.path.join(
                    BASEPATH,
                    "assets/slides/screen_loading.jpg")).convert_alpha(),
            (0, 0))
        pygame.display.flip()

    def __create_game(self, gender, name, loadLast):
        self.started = True
        self.__clock = pygame.time.Clock()
        self.__sound_manager = SoundManager()
        app_loader = AppLoader(gender, name)
        bars_loader = app_loader.get_status_bars_loader()
        self.__game_man = app_loader.get_game_manager()
        if loadLast: self.load_game()
        # windows_controller asociado al screen
        self.windows_controller = SaludameWindowsController(
            self.__screen, self.__game_man)
        self.windows_controller.create_windows_and_activate_main(
            app_loader, self.__clock, bars_loader)
        #self.hotkeys_handler = HotKeyHandler()
        self.__game_man.start(self.windows_controller)

    def __run(self):
        frames = 0
        pygame.display.update()
        while self.__running:
            while Gtk.events_pending():
                Gtk.main_iteration()

            self.__clock.tick(
                MAX_FPS)  # waits if the game is running faster than MAX_FPS

            for event in pygame.event.get():
                if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE:
                    # Gdk.KEY_Escape
                    print "FIXME:", pygame.KEYUP, pygame.K_ESCAPE
                    self.__running = False
                    self.save_game()
                elif event.type == pygame.MOUSEBUTTONDOWN:
                    self.windows_controller.handle_mouse_down(
                        pygame.mouse.get_pos())
                elif event.type == pygame.MOUSEBUTTONUP:
                    self.windows_controller.handle_mouse_up(event.pos)
                elif event.type == pygame.MOUSEMOTION:
                    self.windows_controller.handle_mouse_motion(event.pos)
                elif event.type == pygame.VIDEOEXPOSE:
                    self.windows_controller.reload_main = True
                elif event.type == pygame.USEREVENT and event.code == 0:  # Music ended
                    self.__sound_manager.start_playing()
            if self.__game_man.game_over:
                if self.__game_over_callback:
                    self.__game_over_callback()
                else:
                    self.__running = False
            else:
                self.windows_controller.update(frames)
                frames += 1
                self.__game_man.signal()

            pygame.event.clear()
            pygame.display.update()

        print "FIXME: Se cuelga todo"
        pygame.quit()

    def save_game(self, path=INSTANCE_FILE_PATH):
        data = self.__game_man.serialize()
        try:
            f = open(path, 'w')
            f.write(data)
        finally:
            f.close()

    def load_game(self, path=INSTANCE_FILE_PATH):
        try:
            f = open(path)
            data = f.read()
            if self.__game_man: self.__game_man.parse_game(data)
            f.close()
        except:
            print "Error al cargar la partida"

    def volume_changed(self, range):
        value = range.get_value()
        if value >= 0 and value <= 10:
            value = float(value) / 10
            self.__sound_manager.set_volume(value)
Ejemplo n.º 24
0
from constants import *
from camera import Camera
from player import Player
from level import Level
from lava import Lava
from configuration import Configuration
from sound_manager import SoundManager

pygame.init()
timer = pygame.time.Clock()

surface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_icon(pygame.image.load('assets/gameicon.png'))
pygame.display.set_caption('Speluncraft without craft')

sound_manager = SoundManager()
conf = Configuration()

level = Level(CELL_SIZE, LEVEL_INITIAL_ROWS, LEVEL_INITIAL_COLS)
player = Player(level, 0, PLAYER_SPAWN_POSITION_COL * CELL_SIZE, (SURFACE_LEVEL - 1 )* CELL_SIZE)
lava = Lava()
camera = Camera()

font = pygame.font.SysFont("Verdana", 30)
font_instructions = pygame.font.SysFont("Verdana", 16)

mousex = 0
mousey = 0

player_score = 0
Ejemplo n.º 25
0
class GameInstance(object):

    def __init__(self, config, level_name):
        self.config = config
        self.physics_manager = PhysicsManager()
        self.material_manager = MaterialManager(config["material_file"])
        self.transmutation_manager = TransmutationManager(self.material_manager)
        self.transmutation_manager.blow_key = "stone"
        self.level = Level("{0}/{1}.lvl".format(config["levels_dir"], level_name), self.physics_manager, self.material_manager)

        self.main_char = Player.genMainCharacter()
        self.main_char.physical.position = [25, 10]
        self.level.actors.append(self.main_char)

        self.viewport = Viewport(config["width"], config["height"], self.main_char, self.level, 100)
        self.picking_handler = PickingHandler(self.viewport, self.transmutation_manager, self.physics_manager)

        self.ui_overlay = UIOverlay(config["font_file"])
        self.ui_overlay.text_elements["score"] = TextElement((20, 20), 20, (0, 0, 0), "0 pts")

        self.physics_manager.add_actor(self.main_char)
        self._highlight_actors = False

        self.sound_manager = SoundManager()
        self.sound_manager.actors.append(self.main_char)

    """
    Internally sets and returns the tilesize required to display on the given screen
    """
    def _recalc_tilesize(self, screen):
        self.tile_size = screen.get_width() / self.config["width_tiles"]
        return self.tile_size

    """
    Clears the event queue and performs associated actions for the existing events
    """
    def _handle_events(self, events):
        for event in events:

            event_name = event if isinstance(event, int) else event[0]

            if event_name == Actions.START_USER_LEFT:
                self.main_char.physical.velocity[0] -= self.config["user_motion_speed"]
            elif event_name == Actions.START_USER_RIGHT:
                self.main_char.physical.velocity[0] += self.config["user_motion_speed"]
            elif event_name == Actions.START_USER_UP:
                if self.main_char.physical.velocity[1] == 0:
                    self.main_char.physical.velocity[1] -= self.config["user_jump_speed"]
            elif event_name == Actions.STOP_USER_LEFT:
                self.main_char.physical.velocity[0] += self.config["user_motion_speed"]
            elif event_name == Actions.STOP_USER_RIGHT:
                self.main_char.physical.velocity[0] -= self.config["user_motion_speed"]
            elif event_name == Actions.USER_SUCK:
                [self.transmutation_manager.suck(actor) for actor in self.level.actors if self.picking_handler.is_picked(actor, event[1])]
            elif event_name == Actions.USER_BLOW:
                (new_actor, tile_pos, weight) = self.transmutation_manager.blow(event[1], self.tile_size)
                new_actor.physical.position = tile_pos
                self.level.actors.append(new_actor)
                self.physics_manager.add_actor(new_actor)
            elif event_name == Actions.START_BLOW_SELECTION:
                self.picking_handler.start_user_selection(event[1], self.tile_size)
            elif event_name == Actions.STOP_BLOW_SELECTION:
                self.picking_handler.stop_user_selection()
            elif event_name == Actions.START_DISSOLVE_SELECTION:
                self._highlight_actors = True
            elif event_name == Actions.STOP_DISSOLVE_SELECTION:
                self._highlight_actors = False
            elif event_name == Actions.CHOOSE_MATERIAL:
                self.transmutation_manager.blow_key = event[1]
            elif event_name == Actions.MUTE:
                self.sound_manager.mute()
            elif event_name == Actions.UNMUTE:
                self.sound_manager.unmute()

    """
    Updates all game objects and manager systems based on the frame time delta
    """
    def _handle_updates(self, delta):
        self.sound_manager.update(delta)
        self.physics_manager.update(delta, self.tile_size)
        self.picking_handler.update(delta, self.tile_size)
        self.transmutation_manager.update(delta)
        self.ui_overlay.text_elements["score"].value = "{0} pts".format(self.transmutation_manager.current_points)
        self.ui_overlay.update(delta)

        self.level.update(delta, self.tile_size)
        self.viewport.update(delta)

    """
    Renders all game objects to the screen
    """
    def _render(self, screen):
        additional_drawables = []

        mouse_position = pygame.mouse.get_pos()
        for actor in self.level.actors:
            if self._highlight_actors and self.picking_handler.is_picked(actor, mouse_position) and actor.dissolvable:
                picker = (pygame.Surface(actor.surface.get_size()), actor.position, True)
                picker[0].set_colorkey((0,0,0))
                pygame.draw.rect(picker[0], tuple(self.config["picking_color"]), picker[0].get_rect(), 2)
                additional_drawables.append(picker)

        additional_drawables.append((self.picking_handler.surface, self.picking_handler.position, True))

        additional_drawables += self.ui_overlay.get_drawables()

        screen.blit(self.viewport.render(additional_drawables), (0,0))

    """
    Handle events, update game state, and render to the given screen
    """
    def doFrame(self, screen, delta, events):
        self._recalc_tilesize(screen)
        self._handle_events(events)
        self._handle_updates(delta)

        if self.level.is_player_at_goal(self.main_char):
            pygame.event.post(pygame.event.Event(CustomEvents.USERWINS))

        self._render(screen)
Ejemplo n.º 26
0
 def play_sound(self):
     """Play sound."""
     SoundManager.play_audio(self.sound_path)
Ejemplo n.º 27
0
 def __init__(self):
     self.twitter_feed = TwitterFeed()
     self.io = IOHandler()
     self.sound_manager = SoundManager()
Ejemplo n.º 28
0
class GameState:
    def __init__(self):
        self.twitter_feed = TwitterFeed()
        self.io = IOHandler()
        self.sound_manager = SoundManager()

    def update(self):
        if not self.io.active:
            self.io.was_active = False
            self.twitter_feed.reset()
            return

        if not self.io.was_active:
            self.io.was_active = True
            self.display_help()

        option = self.io.read()
        if option == '*':
            self.sound_manager.play('*')
            self.sound_manager.enqueue('load_more')
            self.twitter_feed.load_more()
        elif option == '#':
            self.display_help()
            return
        elif option != None:
            self.sound_manager.play(str(option))
            self.sound_manager.enqueue('tweets/{0}'.format(self.twitter_feed.get_tweet(int(option))))

        self.sound_manager.update()

    def display_help(self):
        self.sound_manager.play('intro')
Ejemplo n.º 29
0
class PortalController:
    """Manages portals and their related functionality within the game"""
    PORTAL_AUDIO_CHANNEL = 3

    def __init__(self, screen, user, maze):
        self.screen = screen
        self.maze = maze
        self.user = user
        self.sound_manager = SoundManager(
            sound_files=['portal-open.wav', 'portal-travel.wav'],
            keys=['open', 'travel'],
            channel=PortalController.PORTAL_AUDIO_CHANNEL)
        self.blue_portal = pygame.sprite.GroupSingle(
        )  # portals as GroupSingle, which only allows one per group
        self.blue_projectile = None
        self.orange_portal = pygame.sprite.GroupSingle()
        self.orange_projectile = None
        # converter for projectile direction to portal direction
        self.portal_directions = {'l': 'r', 'r': 'l', 'u': 'd', 'd': 'u'}

    def clear_portals(self):
        """Remove all portals and projectiles"""
        self.blue_portal.empty()
        self.orange_portal.empty()
        self.blue_projectile = None
        self.orange_projectile = None

    def fire_b_portal_projectile(self):
        """Create a projectile for generating a blue portal"""
        if self.user.direction is not None:
            self.blue_projectile = PortalProjectile(
                screen=self.screen,
                source=self.user,
                direction=self.user.direction,
                p_type=Portal.P_TYPE_1)

    def fire_o_portal_projectile(self):
        """Create a projectile for generating an orange portal"""
        if self.user.direction is not None:
            self.orange_projectile = PortalProjectile(
                screen=self.screen,
                source=self.user,
                direction=self.user.direction,
                p_type=Portal.P_TYPE_2)

    def create_blue_portal(self, x, y, direction):
        """Create a blue portal, replacing the location it originally took up with a normal maze block"""
        if self.blue_portal:
            old_x, old_y = self.blue_portal.sprite.rect.x, self.blue_portal.sprite.rect.y
            self.maze.maze_blocks.add(
                Block(old_x, old_y, self.maze.block_size, self.maze.block_size,
                      self.maze.block_image))
        self.blue_portal.add(
            Portal(screen=self.screen,
                   x=x,
                   y=y,
                   direction=direction,
                   maze=self.maze,
                   p_type=Portal.P_TYPE_1))

    def create_orange_portal(self, x, y, direction):
        """Create a blue portal, replacing the location it originally took up with a normal maze block"""
        if self.orange_portal:
            old_x, old_y = self.orange_portal.sprite.rect.x, self.orange_portal.sprite.rect.y
            self.maze.maze_blocks.add(
                Block(old_x, old_y, self.maze.block_size, self.maze.block_size,
                      self.maze.block_image))
        self.orange_portal.add(
            Portal(screen=self.screen,
                   x=x,
                   y=y,
                   direction=direction,
                   maze=self.maze,
                   p_type=Portal.P_TYPE_2))

    def update(self):
        """Update the portal controller's display parts and tracking"""
        self.blue_portal.update()
        self.orange_portal.update()
        if self.blue_projectile:
            self.blue_projectile.update()  # update projectile
            # erase projectile if it hits a portal
            if pygame.sprite.spritecollideany(self.blue_projectile, self.blue_portal) or \
                    pygame.sprite.spritecollideany(self.blue_projectile, self.orange_portal):
                self.blue_projectile = None
                return
            collision = pygame.sprite.spritecollideany(self.blue_projectile,
                                                       self.maze.maze_blocks)
            if collision:  # if projectile hits a block, replace it with a blue portal
                x, y = collision.rect.x, collision.rect.y
                collision.kill()  # Replace the block with a portal
                direction = self.portal_directions[
                    self.blue_projectile.direction]
                self.blue_projectile = None  # remove the projectile
                self.create_blue_portal(x, y, direction)
                self.sound_manager.play('open')
            # remove if projectile off screen
            elif self.blue_projectile.is_off_screen():
                self.blue_projectile = None
        if self.orange_projectile:
            self.orange_projectile.update()
            # erase projectile if it hits a portal
            if pygame.sprite.spritecollideany(self.orange_projectile, self.blue_portal) or \
                    pygame.sprite.spritecollideany(self.orange_projectile, self.orange_portal):
                self.orange_projectile = None
                return
            collision = pygame.sprite.spritecollideany(self.orange_projectile,
                                                       self.maze.maze_blocks)
            if collision:  # if projectile hits a block, replace it with an orange portal
                x, y = collision.rect.x, collision.rect.y
                collision.kill()  # Replace the block with a portal
                direction = self.portal_directions[
                    self.orange_projectile.direction]
                self.orange_projectile = None  # remove the projectile
                self.create_orange_portal(x, y, direction)
                self.sound_manager.play('open')
            elif self.orange_projectile.is_off_screen():
                self.orange_projectile = None

    def portables_usable(self):
        """Return True if the portables are usable (i.e. there are two of them)"""
        return self.blue_portal and self.orange_portal

    def collide_portals(self, other):
        """Return True if the sprite is colliding with any portal"""
        return pygame.sprite.spritecollideany(other, self.blue_portal) or \
            pygame.sprite.spritecollideany(other, self.orange_portal)

    def check_portals(self, *args):
        """Check if other sprites have come into contact with the portals, and if so move them"""
        for arg in args:
            if pygame.sprite.spritecollideany(
                    arg, self.blue_portal) and self.orange_portal:
                # get i, j as it relates to the maze map
                i, j = self.orange_portal.sprite.get_nearest_row(
                ), self.orange_portal.sprite.get_nearest_col()
                # move i or j based on portal direction
                if self.orange_portal.sprite.direction == 'l':
                    j -= 1
                elif self.orange_portal.sprite.direction == 'r':
                    j += 1
                elif self.orange_portal.sprite.direction == 'u':
                    i -= 1
                else:
                    i += 1
                # convert i, j to x, y coordinates using same formula as maze class
                x, y = ((self.screen.get_width()) // 5 + (j * self.maze.block_size)), \
                       ((self.screen.get_height()) // 12 + (i * self.maze.block_size))
                arg.rect.x, arg.rect.y = x, y
                self.sound_manager.play('travel')
            elif pygame.sprite.spritecollideany(
                    arg, self.orange_portal) and self.blue_portal:
                # get i, j as it relates to the maze map
                i, j = self.blue_portal.sprite.get_nearest_row(
                ), self.blue_portal.sprite.get_nearest_col()
                # move i or j based on portal direction
                if self.blue_portal.sprite.direction == 'l':
                    j -= 1
                elif self.blue_portal.sprite.direction == 'r':
                    j += 1
                elif self.blue_portal.sprite.direction == 'u':
                    i -= 1
                else:
                    i += 1
                # convert i, j to x, y coordinates using same formula as maze class
                x, y = ((self.screen.get_width() // 5) + (j * self.maze.block_size)), \
                       ((self.screen.get_height() // 12) + (i * self.maze.block_size))
                arg.rect.x, arg.rect.y = x, y
                self.sound_manager.play('travel')

    def blit(self):
        """Blit the portal controller's display components to the screen"""
        if self.blue_projectile:
            self.blue_projectile.blit()
        if self.orange_projectile:
            self.orange_projectile.blit()
        if self.blue_portal:
            self.blue_portal.sprite.blit()
        if self.orange_portal:
            self.orange_portal.sprite.blit()
Ejemplo n.º 30
0
            if closed_counter % fps == 0 and closed_counter > 0:
                if prev_closed_counter < closed_counter:
                    sleep_frames = fps
                    closed_counter = 0
                    open_counter = 0

            closed_counter = max(closed_counter, 0)
            open_counter = max(open_counter, 0)

            # print('[open, closed, ratio] - [%s, %s, %s]' % (open_counter, closed_counter, ratio))

        frame_with_msg = new_frame
        # add a sleeping warning to the frame
        if sleep_frames > 0:
            if sleep_frames == fps:
                SoundManager(sleep_detected=True)
            cv2.putText(new_frame, 'Sleeping', (80, 350),
                        cv2.FONT_HERSHEY_SIMPLEX, 4, (0, 0, 255), 2,
                        cv2.LINE_AA)
            sleep_frames -= 1
        elif yawn_frames > 0:
            if yawn_frames == fps:
                SoundManager(sleep_detected=False)
            cv2.putText(new_frame, 'Drowsing', (80, 350),
                        cv2.FONT_HERSHEY_SIMPLEX, 4, (0, 140, 255), 2,
                        cv2.LINE_AA)
            yawn_frames -= 1

        cv2.imshow('frame', new_frame)

        frames.append(new_frame)
Ejemplo n.º 31
0
MAIN_HERO = None
NOW_LEVEL = None
KOL_LEVELS = 8  # количество уровней

# параметры героев (урон, скорость, здоровье)
hero_parameters = namedtuple('hero_parameters', 'damage speed health')
# name: (damage, speed, health)
HEROES = {
    'Ninja Frog': hero_parameters(15, 6, 100),
    'Pink Man': hero_parameters(20, 5, 120),
    'Virtual Guy': hero_parameters(15, 7, 95),
    'Mask Dude': hero_parameters(15, 6, 100)
}

clock = pygame.time.Clock()
# группы спрайтов
all_sprites = pygame.sprite.Group()
bullets_group = pygame.sprite.Group()
checkpoints = pygame.sprite.Group()
player_group = pygame.sprite.Group()
fruits_group = pygame.sprite.Group()
backpacks_group = pygame.sprite.Group()
enemies_group = pygame.sprite.Group()
potions_group = pygame.sprite.Group()
chameleons = pygame.sprite.Group()
spikes_group = pygame.sprite.Group()
platforms = pygame.sprite.Group()

sound_manager = SoundManager()  # звуковой класс
Ejemplo n.º 32
0
class MainCanvas():
    DEFAULT_SIZE = 448
    INPUT_SIZE = 224

    def __init__(self, root):
        self.root = root
        self.canvas = Canvas(master=self.root.root, width=448, height=448)
        self.canvas.pack(side=TOP)
        self.canvas.bind('<Motion>', self.motion)
        #self.canvas.bind('<MouseWheel>', self.zoom)
        self.canvas.bind('<Button-1>', self.click)
        self.canvas.bind('<B1-Motion>', self.click)
        self.has_image = False
        self.zoom_level = 0
        self.sound = SoundManager()

    def new_image(self, img):
        self.current_image = img
        self.canvas.create_image(0, 0, image=img, anchor=NW)
        self.has_image = True

    def motion(self, event):
        '''
        if self.has_image:
            self.canvas.delete("all")
            self.canvas.create_image(0,0,image=self.current_image,anchor=NW)

            size = MainCanvas.DEFAULT_SIZE * 2**self.zoom_level
            x = event.x - size
            y = event.y - size

            x = max(1, x)
            y = max(1, y)

            if x >= self.canvas.winfo_width() - size*2:
                x = self.canvas.winfo_width() - size*2
            if y >= self.canvas.winfo_height() - size*2:
                y = self.canvas.winfo_height() - size*2

            self.canvas.create_rectangle(x,y,x+size*2,y+size*2, width=3)
            self.current_pos = [x,y]
        '''
        if self.has_image and self.zoom_level >= 0:
            self.canvas.delete("all")
            self.canvas.create_image(0, 0, image=self.current_image, anchor=NW)

            size = MainCanvas.DEFAULT_SIZE / MainCanvas.INPUT_SIZE * (
                2**self.zoom_level)
            x = event.x
            y = event.y
            x0 = round((event.x + 0.0) / size) * size
            y0 = round((event.y + 0.0) / size) * size

            self.canvas.create_rectangle(x0, y0, x0 + size, y0 + size)

    '''
    def zoom(self, event):
        direction = -1 if event.delta > 1 else 1
        self.zoom_level = direction + self.zoom_level 
        if self.zoom_level < -3:
            self.zoom_level = -3
        if self.zoom_level > 1:
            self.zoom_level = 1
        self.motion(event)
    '''

    def click(self, event):
        if self.has_image:
            if self.zoom_level == -1:
                self.root.keras_handler.whole_image()
            else:
                self.motion(event)
                x, y = self.change_coords(event.x, event.y)
                print(x, y, self.target[int(y)][int(x)])
                if self.target[int(y)][int(x)] > 10:
                    frequency = 400 + 14 * self.target[int(y)][int(x)]
                    self.sound.sound_new(frequency=frequency, duration=0.05)

    def new_target_activation(self, activations):
        self.target = activations

    def change_coords(self, x, y):
        x = x / (MainCanvas.DEFAULT_SIZE / MainCanvas.INPUT_SIZE)
        y = y / (MainCanvas.DEFAULT_SIZE / MainCanvas.INPUT_SIZE)
        size = (2**self.zoom_level)
        x0 = round((x + 0.0) / size) * size
        y0 = round((y + 0.0) / size) * size
        return x0 / 2**self.zoom_level, y0 / 2**self.zoom_level
Ejemplo n.º 33
0
 def play_sound(self):
     """Play sound."""
     SoundManager.play_audio(self.sound_path)
Ejemplo n.º 34
0
class PacMan(pygame.sprite.Sprite):
    """Represents the player character 'PacMan' and its related logic/control"""
    PAC_YELLOW = (255, 255, 0)
    PAC_AUDIO_CHANNEL = 0

    def __init__(self, screen, maze):
        super().__init__()
        self.screen = screen
        self.radius = maze.block_size
        self.maze = maze
        self.sound_manager = SoundManager(sound_files=['pacman-pellet-eat.wav', 'Eaten1.wav',
                                                       'Eaten4.wav'],
                                          keys=['eat', 'fruit', 'dead'],
                                          channel=PacMan.PAC_AUDIO_CHANNEL)
        self.horizontal_images = ImageManager('pacman-horiz.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                           (32, 0, 32, 32),
                                                                                           (0, 32, 32, 32),
                                                                                           (32, 32, 32, 32),
                                                                                           (0, 64, 32, 32)],
                                              resize=(self.maze.block_size, self.maze.block_size),
                                              reversible=True)
        self.vertical_images = ImageManager('pacman-vert.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                        (32, 0, 32, 32),
                                                                                        (0, 32, 32, 32),
                                                                                        (32, 32, 32, 32),
                                                                                        (0, 64, 32, 32)],
                                            resize=(self.maze.block_size, self.maze.block_size),
                                            reversible=True)
        self.death_images = ImageManager('pacman-death.png', sheet=True, pos_offsets=[(0, 0, 32, 32),
                                                                                      (32, 0, 32, 32),
                                                                                      (0, 32, 32, 32),
                                                                                      (32, 32, 32, 32),
                                                                                      (0, 64, 32, 32),
                                                                                      (32, 64, 32, 32)],
                                         resize=(self.maze.block_size, self.maze.block_size),
                                         animation_delay=150, repeat=False)
        self.flip_status = {'use_horiz': True, 'h_flip': False, 'v_flip': False}
        self.spawn_info = self.maze.player_spawn[1]
        self.tile = self.maze.player_spawn[0]
        self.direction = None
        self.moving = False
        self.speed = maze.block_size // 7
        self.image, self.rect = self.horizontal_images.get_image()
        self.rect.centerx, self.rect.centery = self.spawn_info   # screen coordinates for spawn
        self.dead = False

        # Keyboard related events/actions/releases
        self.event_map = {pygame.KEYDOWN: self.perform_action, pygame.KEYUP: self.reset_direction}
        self.action_map = {pygame.K_UP: self.set_move_up, pygame.K_LEFT: self.set_move_left,
                           pygame.K_DOWN: self.set_move_down, pygame.K_RIGHT: self.set_move_right,
                           }




    def set_death(self):
        """Set the death flag for PacMan and begin the death animation"""
        self.sound_manager.play('dead')
        self.dead = True
        self.image, _ = self.death_images.get_image()

    def revive(self):
        """Set dead to False and give PacMan a default image"""
        self.dead = False
        self.image, _ = self.horizontal_images.get_image()
        self.death_images.image_index = 0

    def reset_position(self):
        """Reset position back to pre-define spawn location"""
        self.rect.centerx, self.rect.centery = self.spawn_info  # screen coordinates for spawn

    def reset_direction(self, event):
        """Reset the movement direction if key-up on movement keys"""
        if event.key in (pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT):
            self.moving = False

    def perform_action(self, event):
        """Change direction based on the event key"""
        if event.key in self.action_map:
            self.action_map[event.key]()

    def set_move_up(self):
        """Set move direction up"""
        if self.direction != 'u':
            self.direction = 'u'
            if self.flip_status['v_flip']:
                self.vertical_images.flip(False, True)
                self.flip_status['v_flip'] = False
            self.flip_status['use_horiz'] = False
        self.moving = True

    def set_move_left(self):
        """Set move direction left"""
        if self.direction != 'l':
            self.direction = 'l'
            if not self.flip_status['h_flip']:
                self.horizontal_images.flip()
                self.flip_status['h_flip'] = True
            self.flip_status['use_horiz'] = True
        self.moving = True

    def set_move_down(self):
        """Set move direction down"""
        if self.direction != 'd':
            self.direction = 'd'
            if not self.flip_status['v_flip']:
                self.vertical_images.flip(x_bool=False, y_bool=True)
                self.flip_status['v_flip'] = True
            self.flip_status['use_horiz'] = False
        self.moving = True

    def set_move_right(self):
        """Set move direction to right"""
        if self.direction != 'r':
            self.direction = 'r'
            if self.flip_status['h_flip']:
                self.horizontal_images.flip()
                self.flip_status['h_flip'] = False
            self.flip_status['use_horiz'] = True
        self.moving = True

    def get_nearest_col(self):
        """Get the current column location on the maze map"""
        return (self.rect.x - (self.screen.get_width() // 5)) // self.maze.block_size

    def get_nearest_row(self):
        """Get the current row location on the maze map"""
        return (self.rect.y - (self.screen.get_height() // 12)) // self.maze.block_size

    def is_blocked(self):
        """Check if PacMan is blocked by any maze barriers, return True if blocked, False if clear"""
        result = False
        if self.direction is not None and self.moving:
            original_pos = self.rect
            if self.direction == 'u':
                test = self.rect.move((0, -self.speed))
            elif self.direction == 'l':
                test = self.rect.move((-self.speed, 0))
            elif self.direction == 'd':
                test = self.rect.move((0, self.speed))
            else:
                test = self.rect.move((self.speed, 0))
            self.rect = test    # temporarily move self

            # if any collision, result = True
            if pygame.sprite.spritecollideany(self, self.maze.maze_blocks):
                result = True
            elif pygame.sprite.spritecollideany(self, self.maze.shield_blocks):
                result = True
            self.rect = original_pos    # reset position
        return result

    def update(self):
        """Update PacMan's position in the maze if moving, and if not blocked"""
        if not self.dead:
            if self.direction and self.moving:
                if self.flip_status['use_horiz']:
                    self.image = self.horizontal_images.next_image()
                else:
                    self.image = self.vertical_images.next_image()
                if not self.is_blocked():
                    if self.direction == 'u':
                        self.rect.centery -= self.speed
                    elif self.direction == 'l':
                        self.rect.centerx -= self.speed
                    elif self.direction == 'd':
                        self.rect.centery += self.speed
                    elif self.direction == 'r':
                        self.rect.centerx += self.speed
                self.tile = (self.get_nearest_row(), self.get_nearest_col())
        else:
            self.image = self.death_images.next_image()

    def blit(self):
        """Blit the PacMan sprite to the screen"""
        self.screen.blit(self.image, self.rect)

    def eat(self):
        """Eat pellets from the maze and return the score accumulated"""
        score = 0
        fruit_count = 0
        power = None
        collision = pygame.sprite.spritecollideany(self, self.maze.pellets)
        if collision:
            collision.kill()
            score += 10
            self.sound_manager.play('eat')
        collision = pygame.sprite.spritecollideany(self, self.maze.fruits)
        if collision:
            collision.kill()
            score += 20
            fruit_count += 1
            self.sound_manager.play('fruit')
        collision = pygame.sprite.spritecollideany(self, self.maze.power_pellets)
        if collision:
            collision.kill()
            score += 20
            power = True
            self.sound_manager.play('eat')
        return score, fruit_count, power
Ejemplo n.º 35
0
class TetrisGame:
    def __init__(self):
        pg.init()
        pg.font.init()
        pg.display.set_caption("TETRIS")

        self.sound_manager = SoundManager()
        pg.mixer.music.load("Sounds/Music.mp3")
        pg.mixer.music.set_volume(0.3)
        pg.mixer.music.play(-1)

        self.main_surface = pg.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
        self.playground_surf = pg.Surface(
            (GRID_SIZE[0] * CELL_SIZE * UI_SCALE,
             GRID_SIZE[1] * CELL_SIZE * UI_SCALE))
        self.next_surf = pg.Surface((220 * UI_SCALE, 220 * UI_SCALE))

        self.font = pg.font.Font("Fonts/ARCADECLASSIC.TTF",
                                 int(FONT_SIZE * UI_SCALE))

        if "top.scr" in os.listdir():
            with open("top.scr") as file:
                self.top = int(file.read())
        else:
            self.top = 0

        self.score = 0
        self.lines = 0

        self.colors = np.zeros(GRID_SIZE, dtype=object)
        self.grid_colliders = np.zeros(GRID_SIZE)

        self.cur_shape = Shape(self, 5, -1)
        self.next_shape = Shape(self, 5, -1)

        self.game_over = False

    def __del__(self):
        with open("top.scr", "w") as file:
            file.write(str(self.top))

    def check_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                exit()
            if event.type == pg.KEYDOWN:
                if event.key == pg.K_SPACE:
                    self.cur_shape.rotate()
                if event.key == pg.K_d:
                    self.cur_shape.move(1)
                if event.key == pg.K_a:
                    self.cur_shape.move(-1)

    def draw_surfaces(self):
        # Playground
        playground_pos = ((PLAYGROUND_POS[0] + UI_HORIZONTAL_OFFSET) *
                          UI_SCALE,
                          (PLAYGROUND_POS[1] + UI_VERTICAL_OFFSET) * UI_SCALE)
        self.main_surface.blit(self.playground_surf, playground_pos)

        # Next
        next_surf_pos = ((PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE +
                          UI_HORIZONTAL_OFFSET + INFO_OFFSET) * UI_SCALE,
                         (PLAYGROUND_POS[1] + GRID_SIZE[1] * CELL_SIZE - 220 +
                          UI_VERTICAL_OFFSET) * UI_SCALE)
        self.main_surface.blit(self.next_surf, next_surf_pos)

        self.playground_surf.fill(BG_COLOR)
        self.next_surf.fill(BG_COLOR)

    def draw_ui(self):
        # Playground
        play_rect = ((PLAYGROUND_POS[0] + UI_HORIZONTAL_OFFSET) * UI_SCALE,
                     (PLAYGROUND_POS[1] + UI_VERTICAL_OFFSET) * UI_SCALE,
                     GRID_SIZE[0] * CELL_SIZE * UI_SCALE,
                     GRID_SIZE[1] * CELL_SIZE * UI_SCALE)
        pg.draw.rect(self.main_surface, LINE_COLOR, play_rect, 3)

        # Top
        top_headline = self.font.render("TOP", False, TEXT_COLOR)
        top_headline_pos = ((PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE +
                             INFO_OFFSET + UI_HORIZONTAL_OFFSET) * UI_SCALE,
                            (PLAYGROUND_POS[1] + UI_VERTICAL_OFFSET) *
                            UI_SCALE)
        self.main_surface.blit(top_headline, top_headline_pos)
        top = self.font.render(str(self.top).zfill(6), False, TEXT_COLOR)
        top_pos = (
            (PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE + INFO_OFFSET +
             UI_HORIZONTAL_OFFSET) * UI_SCALE,
            (PLAYGROUND_POS[1] + 0.75 * FONT_SIZE + UI_VERTICAL_OFFSET) *
            UI_SCALE)
        self.main_surface.blit(top, top_pos)

        # Score
        score_headline = self.font.render("SCORE", False, TEXT_COLOR)
        score_headline_pos = (
            (PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE + INFO_OFFSET +
             UI_HORIZONTAL_OFFSET) * UI_SCALE,
            (PLAYGROUND_POS[1] + 2.25 * FONT_SIZE + UI_VERTICAL_OFFSET) *
            UI_SCALE)
        self.main_surface.blit(score_headline, score_headline_pos)
        score = self.font.render(str(self.score).zfill(6), False, TEXT_COLOR)
        score_pos = ((PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE +
                      INFO_OFFSET + UI_HORIZONTAL_OFFSET) * UI_SCALE,
                     (PLAYGROUND_POS[1] + 3 * FONT_SIZE + UI_VERTICAL_OFFSET) *
                     UI_SCALE)
        self.main_surface.blit(score, score_pos)

        # Lines
        lines_headline = self.font.render("LINES", False, TEXT_COLOR)
        lines_headline_pos = (
            (PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE + INFO_OFFSET +
             UI_HORIZONTAL_OFFSET) * UI_SCALE,
            (PLAYGROUND_POS[1] + 4.5 * FONT_SIZE + UI_VERTICAL_OFFSET) *
            UI_SCALE)
        self.main_surface.blit(lines_headline, lines_headline_pos)
        lines = self.font.render(str(self.lines).zfill(6), False, TEXT_COLOR)
        lines_pos = (
            (PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE + INFO_OFFSET +
             UI_HORIZONTAL_OFFSET) * UI_SCALE,
            (PLAYGROUND_POS[1] + 5.25 * FONT_SIZE + UI_VERTICAL_OFFSET) *
            UI_SCALE)
        self.main_surface.blit(lines, lines_pos)

        # Next
        next_headline = self.font.render("NEXT", False, TEXT_COLOR)
        next_headline_pos = ((PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE +
                              INFO_OFFSET + UI_HORIZONTAL_OFFSET) * UI_SCALE,
                             (PLAYGROUND_POS[1] + GRID_SIZE[1] * CELL_SIZE -
                              220 - FONT_SIZE + UI_VERTICAL_OFFSET) * UI_SCALE)
        self.main_surface.blit(next_headline, next_headline_pos)
        next_rect = ((PLAYGROUND_POS[0] + GRID_SIZE[0] * CELL_SIZE +
                      UI_HORIZONTAL_OFFSET + INFO_OFFSET) * UI_SCALE,
                     (PLAYGROUND_POS[1] + GRID_SIZE[1] * CELL_SIZE - 220 +
                      UI_VERTICAL_OFFSET) * UI_SCALE, 220 * UI_SCALE,
                     220 * UI_SCALE)
        pg.draw.rect(self.main_surface, LINE_COLOR, next_rect, 3)

    def draw_shapes(self):
        for rect_x, rect_y in self.cur_shape.get_positions():
            self.fill_cell(rect_x, rect_y, self.cur_shape.color)

        for y in range(GRID_SIZE[1]):
            for x in range(GRID_SIZE[0]):
                if self.grid_colliders[x][y]:
                    self.fill_cell(x, y, self.colors[x][y])

        # Grid
        for x in range(1, GRID_SIZE[0]):
            start_pos = x * CELL_SIZE * UI_SCALE, 0
            end_pos = x * CELL_SIZE * UI_SCALE, GRID_SIZE[
                1] * CELL_SIZE * UI_SCALE
            pg.draw.line(self.playground_surf,
                         tuple(map(lambda c: int(c / 2), LINE_COLOR)),
                         start_pos, end_pos)

        for y in range(1, GRID_SIZE[1]):
            start_pos = 0, y * CELL_SIZE * UI_SCALE
            end_pos = GRID_SIZE[
                0] * CELL_SIZE * UI_SCALE, y * CELL_SIZE * UI_SCALE
            pg.draw.line(self.playground_surf,
                         tuple(map(lambda c: int(c / 2), LINE_COLOR)),
                         start_pos, end_pos)

    def draw_next(self):
        offset_y = -0.5 if int(
            self.next_shape.shape[0][0]) != self.next_shape.shape[0][0] else 0
        for pos in self.next_shape.shape:
            center_x, center_y = map(lambda s: s / 2 / CELL_SIZE,
                                     self.next_surf.get_size())
            self.fill_cell(pos[0] + center_x - 0.5,
                           pos[1] + center_y - 0.5 + offset_y,
                           self.next_shape.color, self.next_surf)

    def fill_cell(self, x, y, color, surface=None):
        rect = (x * CELL_SIZE * UI_SCALE, y * CELL_SIZE * UI_SCALE,
                round(CELL_SIZE * UI_SCALE), round(CELL_SIZE * UI_SCALE))

        if not surface:
            pg.draw.rect(self.playground_surf, color, rect)
        else:
            pg.draw.rect(surface, color, rect)

    def check_lines(self):
        lines = []
        for y, *line in enumerate(self.grid_colliders.T):
            if line[0].all():
                lines.append(y)

        if len(lines):
            asyncio.run(self.remove_lines(lines))

    async def remove_lines(self, lines, color=(0, 255, 0)):
        self.sound_manager.play(line_effect)
        half_bright_color = tuple(map(lambda c: int(c / 2), color))
        for i in range(5):
            for y in lines:
                if i % 2:
                    self.colors[:, y] = [color for _ in range(GRID_SIZE[0])]
                else:
                    self.colors[:, y] = [
                        half_bright_color for _ in range(GRID_SIZE[0])
                    ]
                self.render()
            await asyncio.sleep(0.1)

        for y in lines:
            self.grid_colliders = np.delete(self.grid_colliders, y, 1)
            self.grid_colliders = np.insert(self.grid_colliders, 0, 0, 1)
            self.colors = np.delete(self.colors, y, 1)
            self.colors = np.insert(self.colors, 0, 0, 1)

            self.score += 10 * GRID_SIZE[0]
            self.top = self.score if self.score > self.top else self.top
            self.lines += 1
        self.score += (len(lines) - 1) * 25

    def logic(self, time_delta):
        if not self.game_over:
            speed_scale = 10 if pg.key.get_pressed()[pg.K_s] else 1
            self.cur_shape.update(time_delta * speed_scale)
            self.check_lines()
        else:
            self.restart()

    def restart(self):
        pg.mixer.music.rewind()
        self.score = 0
        self.lines = 0

        self.colors = np.zeros(GRID_SIZE, dtype=object)
        self.grid_colliders = np.zeros(GRID_SIZE)

        self.cur_shape = Shape(self, 5, -1)
        self.next_shape = Shape(self, 5, -1)

        self.game_over = False

    def render(self):
        self.main_surface.fill(BG_COLOR)

        self.draw_shapes()
        self.draw_next()
        self.draw_surfaces()
        self.draw_ui()

        pg.display.update()

    def mainloop(self):
        time_delta = 0
        while True:
            start = time()
            self.check_events()
            self.logic(time_delta)
            self.render()
            time_delta = time() - start