Example #1
0
    def _handle_global_keybinds(self):
        if inputs.get_instance().was_pressed(const.TOGGLE_MUTE):
            is_muted = (gs.get_instance().get_settings().get(
                gs.Settings.MUTE_MUSIC)
                        and gs.get_instance().get_settings().get(
                            gs.Settings.EFFECTS_VOLUME))
            print(f"INFO: {'unmuting' if is_muted else 'muting'} audio")
            gs.get_instance().get_settings().set(gs.Settings.MUTE_MUSIC,
                                                 not is_muted)
            gs.get_instance().get_settings().set(gs.Settings.MUTE_EFFECTS,
                                                 not is_muted)

        if inputs.get_instance().was_pressed(const.TOGGLE_SHOW_CAPTION_INFO):
            win = window.get_instance()
            print(
                f"INFO: toggling caption info to {not win.is_showing_caption_info()}"
            )
            win.set_show_caption_info(not win.is_showing_caption_info())

        if inputs.get_instance().was_pressed(const.TOGGLE_COMPAT_MODE):
            win = window.get_instance()

            if win.is_fullscreen():
                win.set_fullscreen(False)

            print(f"INFO: setting compat mode to {win.is_opengl_mode()}")
            win.set_opengl_mode(not win.is_opengl_mode())
Example #2
0
 def handle_debug_commands(self):
     if inputs.get_instance().was_pressed(keybinds.get_instance().get_keys(
             const.TOGGLE_PLAYER_TYPE)):
         self._do_debug_player_type_toggle()
     if inputs.get_instance().was_pressed(keybinds.get_instance().get_keys(
             const.TOGGLE_SHOW_LIGHTING)):
         showing = gs.get_instance().get_settings().get(
             gs.Settings.SHOW_LIGHTING)
         gs.get_instance().get_settings().set(gs.Settings.SHOW_LIGHTING,
                                              not showing)
Example #3
0
    def update(self):
        if self._ui is not None:
            if inputs.get_instance().mouse_in_window() and inputs.get_instance(
            ).mouse_was_pressed(button=1):
                mouse_xy = inputs.get_instance().mouse_pos()
                self._ui.send_click_to_self_and_kids(mouse_xy,
                                                     absolute=True,
                                                     button=1)

            self._ui.update_self_and_kids()

        if self._ui is not None and self._ui.current_dialog is None:
            self._ui = None
Example #4
0
    def _handle_inputs(self):
        edits = inputs.get_instance().all_pressed_ascii_keys()

        text = self.text
        cursor_pos = self.cursor_pos

        jump_cursor = inputs.get_instance().was_pressed_two_way(
            pygame.K_HOME, pygame.K_END)
        if jump_cursor < 0:
            cursor_pos = 0
        elif jump_cursor > 0:
            cursor_pos = len(text)

        move_cursor = 0
        if inputs.get_instance().was_pressed_or_held_and_repeated(
                pygame.K_LEFT) and not inputs.get_instance().is_held(
                    pygame.K_RIGHT):
            move_cursor = -1
        if inputs.get_instance().was_pressed_or_held_and_repeated(
                pygame.K_RIGHT) and not inputs.get_instance().is_held(
                    pygame.K_LEFT):
            move_cursor = 1
        if move_cursor != 0:
            cursor_pos = util.bound(cursor_pos + move_cursor, 0, len(text))

        if inputs.get_instance().was_pressed_or_held_and_repeated(
                pygame.K_DELETE):
            text, cursor_pos = util.apply_ascii_edits_to_text(
                text, ["~delete~"], cursor_pos=cursor_pos)

        if not inputs.get_instance().was_pressed(
                pygame.K_BACKSPACE) and inputs.get_instance(
                ).was_pressed_or_held_and_repeated(pygame.K_BACKSPACE):
            # backspace is an ascii character, so if it was pressed this frame it'll be in edits
            text, cursor_pos = util.apply_ascii_edits_to_text(
                text, ["\b"], cursor_pos=cursor_pos)

        # TODO can't hold regular keys to make them repeat

        if len(edits) > 0:
            text, cursor_pos = util.apply_ascii_edits_to_text(
                text,
                edits,
                cursor_pos=cursor_pos,
                max_len=self.char_limit,
                allowlist=self.allowed_chars)
        self.text = text
        self.cursor_pos = cursor_pos
Example #5
0
    def update(self):
        if self._next_scene is not None:
            if self._next_scene_delay <= 0:
                self._active_scene.about_to_become_inactive()
                self._active_scene = self._next_scene
                self._next_scene.became_active()
                self._next_scene = None
                self._next_scene_delay = 0
            else:
                self._next_scene_delay -= 1

        self._active_scene.update()
        self._active_scene.update_sprites()

        if self._active_scene.should_do_cursor_updates(
        ) and inputs.get_instance().mouse_in_window():
            mouse_xy = inputs.get_instance().mouse_pos()
            cursor_key = self._active_scene.get_cursor_id_at(mouse_xy)
            cursors.set_cursor(cursor_key)
Example #6
0
    def _handle_debug_inputs(self):
        zoom_change = 0
        if inputs.get_instance().was_pressed(pygame.K_MINUS):
            zoom_change -= 1
        if inputs.get_instance().was_pressed(pygame.K_EQUALS):
            zoom_change += 1
        if zoom_change != 0:
            self.adjust_base_zoom(zoom_change)

        if inputs.get_instance().was_pressed(pygame.K_f):
            self._free_camera = not self._free_camera
            print("INFO: toggled free camera to: {}".format(self._free_camera))

        if inputs.get_instance().was_pressed(pygame.K_g):
            self._show_grid = not self._show_grid
            print("INFO: toggled grid to: {}".format(self._show_grid))

        if inputs.get_instance().was_pressed(pygame.K_h):
            gs.get_instance().debug_render = not gs.get_instance().debug_render
            print("INFO: toggled debug sprites to: {}".format(
                gs.get_instance().debug_render))
Example #7
0
    def update(self):
        if not self._has_played_sound:
            self._has_played_sound = True
            sound_to_play = self.current_dialog.get_sound()
            sounds.play_sound(sound_to_play)

        if self._was_clicked_this_frame or inputs.get_instance().was_pressed(
            (const.ACTION, const.MENU_ACCEPT, const.MENU_CANCEL)):
            self.handle_dialog_interact()

            if self.current_dialog is None:
                sounds.play_sound(soundref.DIALOG_EXIT)

        self._was_clicked_this_frame = False
        self.current_dialog_ticks += 1
Example #8
0
    def update(self):
        if len(self.options) == 0:
            return  # probably not initialized yet

        if self.is_focused():
            if inputs.get_instance().was_pressed(
                    keybinds.get_instance().get_keys(const.MENU_UP)):
                self.set_selected_idx(
                    (self.selected_idx - 1) % len(self.options))
            if inputs.get_instance().was_pressed(
                    keybinds.get_instance().get_keys(const.MENU_DOWN)):
                self.set_selected_idx(
                    (self.selected_idx + 1) % len(self.options))

            opt_idx_at_mouse_xy = None
            if inputs.get_instance().mouse_in_window():
                mouse_xy = inputs.get_instance().mouse_pos()
                opt_idx_at_mouse_xy = self.get_option_idx_at(mouse_xy,
                                                             absolute=True)

            if opt_idx_at_mouse_xy is not None and (
                    inputs.get_instance().mouse_moved()
                    or self.ticks_alive <= 1):
                self.set_selected_idx(opt_idx_at_mouse_xy)

            did_activation = False

            if inputs.get_instance().was_pressed(
                    keybinds.get_instance().get_keys(const.MENU_CANCEL)):
                if self._esc_option is not None:
                    did_activation = self._try_to_activate_option(
                        self._esc_option)

            if inputs.get_instance().was_pressed(
                    keybinds.get_instance().get_keys(const.MENU_ACCEPT)):
                if not did_activation and 0 <= self.selected_idx < len(
                        self.options):
                    did_activation = self._try_to_activate_option(
                        self.options[self.selected_idx])

            if inputs.get_instance().mouse_was_pressed(button=1):
                if not did_activation and opt_idx_at_mouse_xy is not None and self.ticks_alive >= 5:
                    did_activation = self._try_to_activate_option(
                        self.options[opt_idx_at_mouse_xy])

        self.update_sprites()
Example #9
0
    def run(self):
        running = True

        ignore_resize_events_next_tick = False

        while running:
            # processing user input events
            all_resize_events = []

            input_state = inputs.get_instance()
            input_state.pre_update()

            for py_event in pygame.event.get():
                if py_event.type == pygame.QUIT:
                    running = False
                    continue
                elif py_event.type == pygame.KEYDOWN:
                    input_state.set_key(py_event.key,
                                        True,
                                        ascii_val=py_event.unicode)
                    keybinds.get_instance().do_global_action_if_necessary(
                        py_event.key)

                elif py_event.type == pygame.KEYUP:
                    input_state.set_key(py_event.key, False)

                elif py_event.type in (pygame.MOUSEMOTION,
                                       pygame.MOUSEBUTTONDOWN,
                                       pygame.MOUSEBUTTONUP):
                    scr_pos = window.get_instance().window_to_screen_pos(
                        py_event.pos)
                    game_pos = util.round_vec(
                        util.mult(
                            scr_pos,
                            1 / renderengine.get_instance().get_pixel_scale()))
                    input_state.set_mouse_pos(game_pos)

                    if py_event.type == pygame.MOUSEBUTTONDOWN:
                        input_state.set_mouse_down(True,
                                                   button=py_event.button)
                    elif py_event.type == pygame.MOUSEBUTTONUP:
                        input_state.set_mouse_down(False,
                                                   button=py_event.button)

                elif py_event.type == pygame.VIDEORESIZE:
                    all_resize_events.append(py_event)

                if not pygame.mouse.get_focused():
                    input_state.set_mouse_pos(None)

            ignore_resize_events_this_tick = ignore_resize_events_next_tick
            ignore_resize_events_next_tick = False

            if self._requested_fullscreen_toggle_this_tick:
                # TODO I have no idea if this **** is still necessary in pygame 2+
                win = window.get_instance()
                win.set_fullscreen(not win.is_fullscreen())

                new_size = win.get_display_size()
                new_pixel_scale = window.calc_pixel_scale(new_size)
                if new_pixel_scale != renderengine.get_instance(
                ).get_pixel_scale():
                    renderengine.get_instance().set_pixel_scale(
                        new_pixel_scale)
                renderengine.get_instance().resize(new_size[0],
                                                   new_size[1],
                                                   px_scale=new_pixel_scale)

                # when it goes from fullscreen to windowed mode, pygame sends a VIDEORESIZE event
                # on the next frame that claims the window has been resized to the maximum resolution.
                # this is annoying so we ignore it. we want the window to remain the same size it was
                # before the fullscreen happened.
                ignore_resize_events_next_tick = True

            self._requested_fullscreen_toggle_this_tick = False

            if not ignore_resize_events_this_tick and len(
                    all_resize_events) > 0:
                last_resize_event = all_resize_events[-1]
                window.get_instance().set_window_size(last_resize_event.w,
                                                      last_resize_event.h)

                display_w, display_h = window.get_instance().get_display_size()
                new_pixel_scale = window.calc_pixel_scale(
                    (last_resize_event.w, last_resize_event.h))

                renderengine.get_instance().resize(display_w,
                                                   display_h,
                                                   px_scale=new_pixel_scale)

            input_state.update()
            sounds.update()

            # updates the actual game state
            still_running = self._game.update()

            if still_running is False:
                running = False

            # draws the actual game state
            for spr in self._game.all_sprites():
                if spr is not None:
                    renderengine.get_instance().update(spr)

            renderengine.get_instance().set_clear_color(
                self._game.get_clear_color())
            renderengine.get_instance().render_layers()

            pygame.display.flip()

            slo_mo_mode = configs.is_dev and input_state.is_held(pygame.K_TAB)
            target_fps = configs.target_fps if not slo_mo_mode else configs.target_fps // 4

            self._wait_until_next_frame(target_fps)

            globaltimer.inc_tick_count()

            if globaltimer.get_show_fps():
                if globaltimer.tick_count() % 20 == 0:
                    window.get_instance().set_caption_info(
                        "FPS", "{:.1f}".format(globaltimer.get_fps()))
            elif globaltimer.tick_count() % configs.target_fps == 0:
                if globaltimer.get_fps(
                ) < 0.9 * configs.target_fps and configs.is_dev and not slo_mo_mode:
                    print("WARN: fps drop: {} ({} sprites)".format(
                        round(globaltimer.get_fps() * 10) / 10.0,
                        renderengine.get_instance().count_sprites()))
            if slo_mo_mode:
                self._slo_mo_timer += 1
            elif self._slo_mo_timer > 0:
                # useful for timing things in the game
                print("INFO: slow-mo mode ended after {} tick(s)".format(
                    self._slo_mo_timer))
                self._slo_mo_timer = 0

        self._game.cleanup()

        print("INFO: quitting game")
        pygame.quit()
Example #10
0
    def update(self):
        if len(self.entity_sprites) == 0:
            self.entity_sprites.append(
                sprites.ImageSprite.new_sprite(DemoGame.ENTITY_LAYER,
                                               scale=1))  # player
            self.entity_sprites.append(
                sprites.ImageSprite.new_sprite(DemoGame.ENTITY_LAYER,
                                               scale=1))  # tv

        if len(self.wall_sprites) == 0:
            for pos in self.wall_positions:
                new_sprite = sprites.ImageSprite(
                    DemoGame.demo_sheet.wall_model,
                    pos[0] * DemoGame.cell_size,
                    pos[1] * DemoGame.cell_size,
                    DemoGame.WALL_LAYER,
                    scale=2)
                self.wall_sprites.append(new_sprite)

        if len(self.floor_sprites) == 0:
            for pos in self.floor_positions:
                new_sprite = sprites.ImageSprite(
                    DemoGame.demo_sheet.floor_model,
                    pos[0] * DemoGame.cell_size,
                    pos[1] * DemoGame.cell_size,
                    DemoGame.FLOOR_LAYER,
                    scale=2)
                self.floor_sprites.append(new_sprite)

        if len(self.shadow_sprites) == 0:
            for _ in self.entity_sprites:
                self.shadow_sprites.append(
                    sprites.ImageSprite(DemoGame.demo_sheet.shadow_model,
                                        0,
                                        0,
                                        DemoGame.SHADOW_LAYER,
                                        scale=1))

        if self.triangle_sprite is None:
            self.triangle_sprite = sprites.TriangleSprite(
                DemoGame.POLYGON_LAYER, color=(0, 0, 0))

        while len(self.cube_line_sprites) < 12:
            self.cube_line_sprites.append(
                sprites.LineSprite(DemoGame.POLYGON_LAYER,
                                   thickness=self.cube_line_thickness))

        anim_tick = globaltimer.tick_count() // 16

        speed = 2
        dx = 0
        new_xflip = None
        if inputs.get_instance().is_held([pygame.K_a, pygame.K_LEFT]):
            dx -= speed
            new_xflip = False
        elif inputs.get_instance().is_held([pygame.K_d, pygame.K_RIGHT]):
            dx += speed
            new_xflip = True

        dy = 0
        if inputs.get_instance().is_held([pygame.K_w, pygame.K_UP]):
            dy -= speed
        elif inputs.get_instance().is_held([pygame.K_s, pygame.K_DOWN]):
            dy += speed

        player_x = self.entity_positions[0][0] + dx
        new_y = self.entity_positions[0][1] + dy
        player_y = max(new_y,
                       int(1.1 * DemoGame.cell_size))  # collision with walls~

        self.entity_positions[0] = (player_x, player_y)
        new_model = DemoGame.demo_sheet.player_models[anim_tick % len(
            DemoGame.demo_sheet.player_models)]
        player_sprite = self.entity_sprites[0]
        player_scale = player_sprite.scale()
        self.entity_sprites[0] = player_sprite.update(
            new_model=new_model,
            new_x=player_x - new_model.width() * player_scale // 2,
            new_y=player_y - new_model.height() * player_scale,
            new_xflip=new_xflip,
            new_depth=-player_y)

        tv_model = DemoGame.demo_sheet.tv_models[(anim_tick // 2) % len(
            DemoGame.demo_sheet.tv_models)]
        tv_x = self.entity_positions[1][0]
        tv_y = self.entity_positions[1][1]
        tv_xflip = player_x > tv_x  # turn to face player
        tv_sprite = self.entity_sprites[1]
        tv_scale = tv_sprite.scale()

        self.entity_sprites[1] = tv_sprite.update(
            new_model=tv_model,
            new_x=tv_x - tv_model.width() * tv_scale // 2,
            new_y=tv_y - tv_model.height() * tv_scale,
            new_xflip=tv_xflip,
            new_depth=-tv_y)

        for i in range(0, len(self.entity_positions)):
            xy = self.entity_positions[i]
            shadow_sprite = self.shadow_sprites[i]
            shadow_model = self.demo_sheet.shadow_model
            shadow_x = xy[0] - shadow_sprite.scale() * shadow_model.width() // 2
            shadow_y = xy[1] - shadow_sprite.scale() * shadow_model.height(
            ) // 2
            self.shadow_sprites[i] = shadow_sprite.update(
                new_model=shadow_model, new_x=shadow_x, new_y=shadow_y)

        min_rot_speed = 0.3
        max_rot_speed = 4

        if self.triangle_sprite is not None:
            tri_center = self.triangle_center
            tri_angle = self.triangle_angle * 2 * 3.141529 / 360
            tri_length = self.triangle_length

            p1 = Utils.add(tri_center, Utils.rotate((tri_length, 0),
                                                    tri_angle))
            p2 = Utils.add(
                tri_center,
                Utils.rotate((tri_length, 0), tri_angle + 3.141529 * 2 / 3))
            p3 = Utils.add(
                tri_center,
                Utils.rotate((tri_length, 0), tri_angle + 3.141529 * 4 / 3))

            self.triangle_sprite = self.triangle_sprite.update(new_points=(p1,
                                                                           p2,
                                                                           p3))

            player_dist = Utils.dist(self.entity_positions[0], tri_center)
            if player_dist > 100:
                rot_speed = min_rot_speed
            else:
                rot_speed = Utils.linear_interp(min_rot_speed, max_rot_speed,
                                                (100 - player_dist) / 100)

            self.triangle_angle += rot_speed

        text_inset = 4

        title_text = "Demo Scene"
        if self.title_text_sprite is None:
            self.title_text_sprite = sprites.TextSprite(
                DemoGame.UI_FG_LAYER, 0, text_inset, title_text)

        title_text_width = self.title_text_sprite.get_size()[0]
        title_text_x = renderengine.get_instance().get_game_size(
        )[0] - title_text_width - text_inset
        self.title_text_sprite = self.title_text_sprite.update(
            new_x=title_text_x)

        if self.fps_text_sprite is None:
            self.fps_text_sprite = sprites.TextSprite(DemoGame.UI_FG_LAYER,
                                                      text_inset, text_inset,
                                                      "FPS: 0")
        fps_text = "FPS: {}".format(int(globaltimer.get_fps()))
        self.fps_text_sprite = self.fps_text_sprite.update(new_x=text_inset,
                                                           new_y=text_inset,
                                                           new_text=fps_text)

        player_to_tv_dist = Utils.dist(self.entity_positions[0],
                                       self.entity_positions[1])
        info_text = "There's something wrong with the TV. Maybe it's better this way." if player_to_tv_dist < 32 else None
        info_text_w = 400 - 32
        info_text_h = 48
        info_text_rect = [
            renderengine.get_instance().get_game_size()[0] // 2 -
            info_text_w // 2,
            renderengine.get_instance().get_game_size()[1] - info_text_h - 16,
            info_text_w, info_text_h
        ]
        if info_text is None:
            self.text_box_text_sprite = None
            self.text_box_sprite = None
        else:
            wrapped_text = "\n".join(
                sprites.TextSprite.wrap_text_to_fit(info_text,
                                                    info_text_rect[2]))
            if self.text_box_text_sprite is None:
                self.text_box_text_sprite = sprites.TextSprite(
                    DemoGame.UI_FG_LAYER, 0, 0, wrapped_text)
            self.text_box_text_sprite = self.text_box_text_sprite.update(
                new_x=info_text_rect[0],
                new_y=info_text_rect[1],
                new_text=wrapped_text)
            if self.text_box_sprite is None:
                self.text_box_sprite = sprites.BorderBoxSprite(
                    DemoGame.UI_BG_LAYER,
                    info_text_rect,
                    all_borders=DemoGame.demo_sheet.border_models)
            self.text_box_sprite = self.text_box_sprite.update(
                new_rect=info_text_rect, new_scale=2)

        if len(self.cube_line_sprites) == 12:
            cube_center = self.cube_center
            cube_angle = self.cube_angle * 2 * 3.141529 / 360
            cube_length = self.cube_length
            cube_color = self.cube_color

            cube_top_pts = []
            cube_btm_pts = []

            for i in range(0, 4):
                dx = cube_length / 2 * math.cos(cube_angle + i * 3.141529 / 2)
                dy = cube_length / 2 * math.sin(
                    cube_angle +
                    i * 3.141529 / 2) / 2  # foreshortened in the y-axis
                cube_btm_pts.append(Utils.add(cube_center, (dx, dy)))
                cube_top_pts.append(
                    Utils.add(cube_center, (dx, dy - cube_length)))

            for i in range(0, 12):
                if i < 4:  # bottom lines
                    p1 = cube_btm_pts[i % 4]
                    p2 = cube_btm_pts[(i + 1) % 4]
                elif i < 8:  # top lines
                    p1 = cube_top_pts[i % 4]
                    p2 = cube_top_pts[(i + 1) % 4]
                else:  # bottom to top lines
                    p1 = cube_btm_pts[i % 4]
                    p2 = cube_top_pts[i % 4]

                self.cube_line_sprites[i].update(new_p1=p1,
                                                 new_p2=p2,
                                                 new_color=cube_color)

            player_dist = Utils.dist(self.entity_positions[0], cube_center)
            if player_dist > 100:
                rotation_speed = min_rot_speed
            else:
                rotation_speed = Utils.linear_interp(min_rot_speed,
                                                     max_rot_speed,
                                                     (100 - player_dist) / 100)

            self.cube_angle += rotation_speed

        # setting layer positions
        camera_x = player_x - renderengine.get_instance().get_game_size(
        )[0] // 2
        camera_y = player_y - renderengine.get_instance().get_game_size(
        )[1] // 2
        for layer_id in DemoGame.world_layer_ids:
            renderengine.get_instance().set_layer_offset(
                layer_id, camera_x, camera_y)
Example #11
0
def run():
    clock = pygame.time.Clock()
    running = True

    ignore_resize_events_next_tick = False

    while running:
        # processing user input events
        all_resize_events = []
        toggled_fullscreen = False

        input_state = inputs.get_instance()
        for py_event in pygame.event.get():
            if py_event.type == pygame.QUIT:
                running = False
                continue
            elif py_event.type == pygame.KEYDOWN:
                input_state.set_key(py_event.key, True)
            elif py_event.type == pygame.KEYUP:
                input_state.set_key(py_event.key, False)

            elif py_event.type in (pygame.MOUSEMOTION, pygame.MOUSEBUTTONDOWN,
                                   pygame.MOUSEBUTTONUP):
                scr_pos = window.get_instance().window_to_screen_pos(
                    py_event.pos)
                game_pos = Utils.round(
                    Utils.mult(
                        scr_pos,
                        1 / renderengine.get_instance().get_pixel_scale()))
                input_state.set_mouse_pos(game_pos)

                if py_event.type == pygame.MOUSEBUTTONDOWN:
                    input_state.set_mouse_down(True, button=py_event.button)
                elif py_event.type == pygame.MOUSEBUTTONUP:
                    input_state.set_mouse_down(False, button=py_event.button)

            elif py_event.type == pygame.VIDEORESIZE:
                all_resize_events.append(py_event)

            if py_event.type == pygame.KEYDOWN and py_event.key == pygame.K_F4:
                toggled_fullscreen = True

            if not pygame.mouse.get_focused():
                input_state.set_mouse_pos(None)

        ignore_resize_events_this_tick = ignore_resize_events_next_tick
        ignore_resize_events_next_tick = False

        if toggled_fullscreen:
            # print("INFO {}: toggled fullscreen".format(gs.get_instance().tick_counter))
            win = window.get_instance()
            win.set_fullscreen(not win.is_fullscreen())

            new_size = win.get_display_size()
            new_pixel_scale = _calc_pixel_scale(new_size)
            if new_pixel_scale != renderengine.get_instance().get_pixel_scale(
            ):
                renderengine.get_instance().set_pixel_scale(new_pixel_scale)
            renderengine.get_instance().resize(new_size[0],
                                               new_size[1],
                                               px_scale=new_pixel_scale)

            # when it goes from fullscreen to windowed mode, pygame sends a VIDEORESIZE event
            # on the next frame that claims the window has been resized to the maximum resolution.
            # this is annoying so we ignore it. we want the window to remain the same size it was
            # before the fullscreen happened.
            ignore_resize_events_next_tick = True

        if not ignore_resize_events_this_tick and len(all_resize_events) > 0:
            last_resize_event = all_resize_events[-1]

            print("INFO: resizing to {}, {}".format(last_resize_event.w,
                                                    last_resize_event.h))

            window.get_instance().set_window_size(last_resize_event.w,
                                                  last_resize_event.h)

            display_w, display_h = window.get_instance().get_display_size()
            new_pixel_scale = _calc_pixel_scale(
                (last_resize_event.w, last_resize_event.h))

            renderengine.get_instance().resize(display_w,
                                               display_h,
                                               px_scale=new_pixel_scale)

        input_state.update(gs.get_instance().tick_count)
        sounds.update()

        if gs.get_instance().is_dev() and input_state.was_pressed(pygame.K_F1):
            # used to help find performance bottlenecks
            import src.utils.profiling as profiling
            profiling.get_instance().toggle()

        if input_state.was_pressed(pygame.K_F5):
            current_scale = gs.get_instance().px_scale
            options = gs.get_instance().px_scale_options
            if current_scale in options:
                new_scale = (options.index(current_scale) + 1) % len(options)
            else:
                print("WARN: illegal pixel scale={}, reverting to default".
                      format(current_scale))
                new_scale = options[0]
            gs.get_instance().px_scale = new_scale

            display_size = window.get_instance().get_display_size()
            new_pixel_scale = _calc_pixel_scale(display_size,
                                                px_scale_opt=new_scale)
            renderengine.get_instance().set_pixel_scale(new_pixel_scale)

        if input_state.was_pressed(pygame.K_r):
            print("INFO: restarting game")
            renderengine.get_instance().clear_all_sprites()  # full nuke
            gs.get_instance().set_game_state(gamestate.GameState())

        renderengine.get_instance().set_clear_color((0, 0, 0))

        gs.get_instance().update_all()

        renderengine.get_instance().render_layers()
        pygame.display.flip()

        slo_mo_mode = gs.get_instance().is_dev() and input_state.is_held(
            pygame.K_TAB)
        if slo_mo_mode:
            clock.tick(15)
        else:
            clock.tick(60)

        gs.get_instance().tick_count += 1

        if gs.get_instance().tick_count % 60 == 0:
            if clock.get_fps() < 55 and gs.get_instance().is_dev(
            ) and not slo_mo_mode:
                print("WARN: fps drop: {} ({} sprites)".format(
                    round(clock.get_fps() * 10) / 10.0,
                    renderengine.get_instance().count_sprites()))

    print("INFO: quitting game")
    pygame.quit()
Example #12
0
    def run(self):
        running = True

        ignore_resize_events_next_tick = False

        while running:
            # processing user input events
            all_resize_events = []

            input_state = inputs.get_instance()
            for py_event in pygame.event.get():
                if py_event.type == pygame.QUIT:
                    running = False
                    continue
                elif py_event.type == pygame.KEYDOWN:
                    input_state.set_key(py_event.key, True)
                elif py_event.type == pygame.KEYUP:
                    input_state.set_key(py_event.key, False)

                elif py_event.type in (pygame.MOUSEMOTION,
                                       pygame.MOUSEBUTTONDOWN,
                                       pygame.MOUSEBUTTONUP):
                    scr_pos = window.get_instance().window_to_screen_pos(
                        py_event.pos)
                    game_pos = Utils.round(
                        Utils.mult(
                            scr_pos,
                            1 / renderengine.get_instance().get_pixel_scale()))
                    input_state.set_mouse_pos(game_pos)

                    if py_event.type == pygame.MOUSEBUTTONDOWN:
                        input_state.set_mouse_down(True,
                                                   button=py_event.button)
                    elif py_event.type == pygame.MOUSEBUTTONUP:
                        input_state.set_mouse_down(False,
                                                   button=py_event.button)

                elif py_event.type == pygame.VIDEORESIZE:
                    all_resize_events.append(py_event)

                if not pygame.mouse.get_focused():
                    input_state.set_mouse_pos(None)

            ignore_resize_events_this_tick = ignore_resize_events_next_tick
            ignore_resize_events_next_tick = False

            if input_state.was_pressed(
                    pygame.K_F4) and configs.allow_fullscreen:
                win = window.get_instance()
                win.set_fullscreen(not win.is_fullscreen())

                new_size = win.get_display_size()
                new_pixel_scale = self._calc_pixel_scale(new_size)
                if new_pixel_scale != renderengine.get_instance(
                ).get_pixel_scale():
                    renderengine.get_instance().set_pixel_scale(
                        new_pixel_scale)
                renderengine.get_instance().resize(new_size[0],
                                                   new_size[1],
                                                   px_scale=new_pixel_scale)

                # when it goes from fullscreen to windowed mode, pygame sends a VIDEORESIZE event
                # on the next frame that claims the window has been resized to the maximum resolution.
                # this is annoying so we ignore it. we want the window to remain the same size it was
                # before the fullscreen happened.
                ignore_resize_events_next_tick = True

            if not ignore_resize_events_this_tick and len(
                    all_resize_events) > 0:
                last_resize_event = all_resize_events[-1]

                window.get_instance().set_window_size(last_resize_event.w,
                                                      last_resize_event.h)

                display_w, display_h = window.get_instance().get_display_size()
                new_pixel_scale = self._calc_pixel_scale(
                    (last_resize_event.w, last_resize_event.h))

                renderengine.get_instance().resize(display_w,
                                                   display_h,
                                                   px_scale=new_pixel_scale)

            if configs.is_dev and input_state.was_pressed(pygame.K_F1):
                # used to help find performance bottlenecks
                import src.utils.profiling as profiling
                profiling.get_instance().toggle()

            input_state.update()
            sounds.update()

            # updates the actual game state
            self._game.update()

            # draws the actual game state
            for spr in self._game.all_sprites():
                if spr is not None:
                    renderengine.get_instance().update(spr)

            renderengine.get_instance().set_clear_color(configs.clear_color)
            renderengine.get_instance().render_layers()

            pygame.display.flip()

            slo_mo_mode = configs.is_dev and input_state.is_held(pygame.K_TAB)
            target_fps = configs.target_fps if not slo_mo_mode else configs.target_fps // 4

            self._wait_until_next_frame(target_fps)

            globaltimer.inc_tick_count()

            if globaltimer.tick_count() % configs.target_fps == 0:
                if globaltimer.get_fps(
                ) < 0.9 * configs.target_fps and configs.is_dev and not slo_mo_mode:
                    print("WARN: fps drop: {} ({} sprites)".format(
                        round(globaltimer.get_fps() * 10) / 10.0,
                        renderengine.get_instance().count_sprites()))

        print("INFO: quitting game")
        pygame.quit()