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)
def update(self): self._handle_global_keybinds() scenes.get_instance().update() gs.get_instance().update() songsystem.get_instance().update() if globaltimer.tick_count() % 15 == 0: window.get_instance().set_caption_info( "SPRITES", renderengine.get_instance().count_sprites()) window.get_instance().set_caption_info( "NO_GL_MODE", None if window.get_instance().is_opengl_mode() else "True") return not gs.get_instance().should_exit()
def _do_debug_player_type_toggle(self): cur_player = self.get_player() if cur_player is None: return else: ptype = cur_player.get_player_type() all_types = [t for t in playertypes.PlayerTypes.all_types()] if ptype in all_types: idx = all_types.index(ptype) next_type = all_types[(idx + 1) % len(all_types)] else: next_type = all_types[0] gs.get_instance( ).player_type_override = next_type # new levels will get this player type too cur_x, cur_y = cur_player.get_xy() new_player = entities.PlayerEntity( cur_x, cur_y, next_type, align_to_cells=False, controller=cur_player.get_controller()) new_player.set_y(cur_y + cur_player.get_h() - new_player.get_h()) # keep feet position the same self.remove_entity(cur_player) self.add_entity(new_player)
def __init__(self, bp=None): # the canonical place where entities are stored. # tracks them by {type -> set of entities with that type} for efficient type-based lookups. self._type_to_ents = {entities.Entity: set()} self._to_add = set() # set of new entities to add next frame self._to_remove = set() # set of entities to remove next frame self._game_state = None self._sensor_states = {} # sensor_id -> OrderedDict of entities # hashing by id, kept in sync with _type_to_ents at all times. self._ent_id_to_ent = {} # ent_id -> entity # spatial hashing, kept in sync with _type_to_ents at all times. self._entities_to_cells = {} # ent -> set of cells (x, y) it's inside self._cells_to_entities = {} # (x, y) - set of entities inside self._light_sources = util.SpacialHashMap(gs.get_instance().cell_size * 5) self.camera_bounds = { } # idx: int -> (boundary: rect, show_timer: bool) self.active_camera_idx = -1 self.safe_zones = [ ] # list of rects that are safe for actors to be in. if empty, the entire world is safe self._orig_blueprint = bp self._is_being_edited = False self._tick = 0
def _update_grid_line_sprites(self): if self._show_grid: cam_rect = self.get_camera_rect_in_world() cs = gs.get_instance().cell_size n_x_lines = int(cam_rect[2] // cs) n_y_lines = int(cam_rect[3] // cs) util.extend_or_empty_list_to_length( self._grid_line_sprites, n_x_lines + n_y_lines, creator=lambda: sprites.LineSprite(spriteref.POLYGON_LAYER)) for i in range(0, n_x_lines): x_line_sprite = self._grid_line_sprites[i] p1 = (cam_rect[0] - (cam_rect[0] % cs) + cs * (i + 1), cam_rect[1]) p2 = (cam_rect[0] - (cam_rect[0] % cs) + cs * (i + 1), cam_rect[1] + cam_rect[3]) x_line_sprite.update(new_p1=p1, new_p2=p2, new_thickness=1, new_color=colors.PERFECT_VERY_DARK_GRAY, new_depth=500) for i in range(0, n_y_lines): y_line_sprite = self._grid_line_sprites[i + n_x_lines] p1 = (cam_rect[0], (cam_rect[1] - (cam_rect[1] % cs) + cs * (i + 1))) p2 = (cam_rect[0] + cam_rect[2], (cam_rect[1] - (cam_rect[1] % cs) + cs * (i + 1))) y_line_sprite.update(new_p1=p1, new_p2=p2, new_thickness=1, new_color=colors.PERFECT_VERY_DARK_GRAY, new_depth=500) else: self._grid_line_sprites.clear()
def _calc_entities_to_render_this_frame(self, inside_rect=None): buffer_zone = gs.get_instance().cell_size * 4 render_zone = self.get_camera_rect_in_world(integer=True, expansion=buffer_zone) if inside_rect is not None: render_zone = util.get_rect_intersect(render_zone, inside_rect) for ent in self._world.all_entities_in_rect(render_zone): yield ent
def all_cells_in_rect(self, rect): cs = gs.get_instance().cell_size if rect[2] <= 0 or rect[3] <= 0: return [] start_cell = (int(rect[0] / cs), int(rect[1] / cs)) end_cell = (int( (rect[0] + rect[2] - 1) / cs), int((rect[1] + rect[3] - 1) / cs)) for x in range(start_cell[0], end_cell[0] + 1): for y in range(start_cell[1], end_cell[1] + 1): yield (x, y)
def update(self): if self.is_playing() and self._sounds_are_actually_loaded: volume_from_prefs = gs.get_instance().get_settings().music_volume() for i, v in enumerate(self._volumes): if i < len(self._sounds): vol_to_use = v * self._master_volume * self._adjusted_volume * volume_from_prefs self._sounds[i].set_volume(vol_to_use) if len(self._volumes) < len(self._sounds): for i in range(len(self._volumes), len(self._sounds)): self._sounds[i].set_volume(0)
def all_sprites(self): for ent in self._entities_to_render: if gs.get_instance().debug_render: for spr in ent.all_debug_sprites(): yield spr else: for spr in ent.all_sprites(): yield spr for spr in self._out_of_bounds_blockers: yield spr for spr in self._grid_line_sprites: yield spr
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))
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())
def initialize(self): if configs.is_dev: _update_readme() util.set_info_for_user_data_path(configs.userdata_subdir, "Ghast") keybinds.get_instance().set_binding(const.MOVE_LEFT, [pygame.K_LEFT, pygame.K_a]) keybinds.get_instance().set_binding(const.MOVE_RIGHT, [pygame.K_RIGHT, pygame.K_d]) keybinds.get_instance().set_binding( const.JUMP, [pygame.K_UP, pygame.K_w, pygame.K_SPACE]) keybinds.get_instance().set_binding(const.CROUCH, [pygame.K_DOWN, pygame.K_s]) keybinds.get_instance().set_binding( const.ACTION, [pygame.K_f, pygame.K_j, pygame.K_RETURN]) keybinds.get_instance().set_binding(const.MENU_UP, [pygame.K_UP, pygame.K_w]) keybinds.get_instance().set_binding(const.MENU_DOWN, [pygame.K_DOWN, pygame.K_s]) keybinds.get_instance().set_binding(const.MENU_LEFT, [pygame.K_LEFT, pygame.K_a]) keybinds.get_instance().set_binding(const.MENU_RIGHT, [pygame.K_RIGHT, pygame.K_d]) keybinds.get_instance().set_binding(const.MENU_ACCEPT, [pygame.K_RETURN]) keybinds.get_instance().set_binding(const.MENU_CANCEL, [pygame.K_ESCAPE]) keybinds.get_instance().set_binding( const.RESET, keybinds.Binding(pygame.K_r, mods=pygame.KMOD_SHIFT)) keybinds.get_instance().set_binding(const.SOFT_RESET, [pygame.K_r]) keybinds.get_instance().set_binding(const.TOGGLE_MUTE, [pygame.K_m]) # debug commands keybinds.get_instance().set_binding(const.TOGGLE_SPRITE_MODE_DEBUG, [pygame.K_h]) keybinds.get_instance().set_binding(const.TOGGLE_PLAYER_TYPE, [pygame.K_p]) keybinds.get_instance().set_binding( const.TEST_KEY_1, keybinds.Binding(pygame.K_1, mods=pygame.KMOD_SHIFT)) keybinds.get_instance().set_binding( const.TEST_KEY_2, keybinds.Binding(pygame.K_2, mods=pygame.KMOD_SHIFT)) keybinds.get_instance().set_binding( const.TEST_KEY_3, keybinds.Binding(pygame.K_3, mods=pygame.KMOD_SHIFT)) keybinds.get_instance().set_binding(const.TOGGLE_SHOW_LIGHTING, keybinds.Binding(pygame.K_l)) keybinds.get_instance().set_binding( const.UNLOCK_ALL_DEBUG, keybinds.Binding(pygame.K_u, mods=pygame.KMOD_CTRL)) keybinds.get_instance().set_binding( const.SAVE, keybinds.Binding(pygame.K_s, mods=[pygame.KMOD_CTRL, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.SAVE_AS, keybinds.Binding( pygame.K_s, mods=[pygame.KMOD_CTRL, pygame.KMOD_SHIFT, pygame.KMOD_NONE])) # level editor commands keybinds.get_instance().set_binding(const.TOGGLE_SHOW_CAPTION_INFO, [pygame.K_F3]) keybinds.get_instance().set_binding(const.TOGGLE_EDIT_MODE, [pygame.K_F5]) keybinds.get_instance().set_binding(const.TOGGLE_COMPAT_MODE, [pygame.K_F6]) keybinds.get_instance().set_binding( const.MOVE_SELECTION_UP, keybinds.Binding(pygame.K_w, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.MOVE_SELECTION_LEFT, keybinds.Binding(pygame.K_a, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.MOVE_SELECTION_DOWN, keybinds.Binding(pygame.K_s, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.MOVE_SELECTION_RIGHT, keybinds.Binding(pygame.K_d, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding(const.MOVE_CAMERA_UP, [pygame.K_UP]) keybinds.get_instance().set_binding(const.MOVE_CAMERA_LEFT, [pygame.K_LEFT]) keybinds.get_instance().set_binding(const.MOVE_CAMERA_DOWN, [pygame.K_DOWN]) keybinds.get_instance().set_binding(const.MOVE_CAMERA_RIGHT, [pygame.K_RIGHT]) keybinds.get_instance().set_binding( const.SHRINK_SELECTION_VERT, keybinds.Binding(pygame.K_w, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.SHRINK_SELECTION_HORZ, keybinds.Binding(pygame.K_a, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.GROW_SELECTION_VERT, keybinds.Binding(pygame.K_s, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.GROW_SELECTION_HORZ, keybinds.Binding(pygame.K_d, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.CYCLE_SELECTION_SUBTYPE_FORWARD, keybinds.Binding(pygame.K_t, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.CYCLE_SELECTION_SUBTYPE_BACKWARD, keybinds.Binding(pygame.K_t, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.CYCLE_SELECTION_COLOR_FORWARD, keybinds.Binding(pygame.K_c, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.CYCLE_SELECTION_COLOR_BACKWARD, keybinds.Binding(pygame.K_c, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.CYCLE_SELECTION_ART_FORWARD, keybinds.Binding(pygame.K_e, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.CYCLE_SELECTION_ART_BACKWARD, keybinds.Binding(pygame.K_e, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.TOGGLE_SELECTION_INVERTED, keybinds.Binding(pygame.K_i, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.ADVANCED_EDIT, keybinds.Binding(pygame.K_o, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.ADD_POINT, keybinds.Binding(pygame.K_p, mods=pygame.KMOD_NONE)) keybinds.get_instance().set_binding( const.REMOVE_POINT, keybinds.Binding(pygame.K_p, mods=[pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.CLEAR_POINTS, keybinds.Binding( pygame.K_p, mods=[pygame.KMOD_SHIFT, pygame.KMOD_CTRL, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.ROTATE_POINTS_FORWARD, keybinds.Binding(pygame.K_p, mods=[pygame.KMOD_ALT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.ROTATE_POINTS_BACKWARD, keybinds.Binding( pygame.K_p, mods=[pygame.KMOD_ALT, pygame.KMOD_SHIFT, pygame.KMOD_NONE])) keybinds.get_instance().set_binding(const.DECREASE_EDIT_RESOLUTION, [pygame.K_LEFTBRACKET]) keybinds.get_instance().set_binding(const.INCREASE_EDIT_RESOLUTION, [pygame.K_RIGHTBRACKET]) keybinds.get_instance().set_binding(const.OPTION_0, [pygame.K_1]) keybinds.get_instance().set_binding(const.OPTION_1, [pygame.K_2]) keybinds.get_instance().set_binding(const.OPTION_2, [pygame.K_3]) keybinds.get_instance().set_binding(const.OPTION_3, [pygame.K_4]) keybinds.get_instance().set_binding(const.OPTION_4, [pygame.K_5]) keybinds.get_instance().set_binding(const.OPTION_5, [pygame.K_6]) keybinds.get_instance().set_binding(const.OPTION_6, [pygame.K_7]) keybinds.get_instance().set_binding(const.OPTION_7, [pygame.K_8]) keybinds.get_instance().set_binding(const.OPTION_8, [pygame.K_9]) keybinds.get_instance().set_binding(const.OPTION_9, [pygame.K_0]) keybinds.get_instance().set_binding( const.UNDO, keybinds.Binding(pygame.K_z, mods=pygame.KMOD_CTRL)) keybinds.get_instance().set_binding( const.REDO, keybinds.Binding(pygame.K_y, mods=pygame.KMOD_CTRL)) keybinds.get_instance().set_binding( const.DELETE, [pygame.K_DELETE, pygame.K_BACKSPACE]) keybinds.get_instance().set_binding( const.COPY, keybinds.Binding(pygame.K_c, mods=pygame.KMOD_CTRL)) keybinds.get_instance().set_binding( const.PASTE, keybinds.Binding(pygame.K_v, mods=pygame.KMOD_CTRL)) keybinds.get_instance().set_binding( const.CUT, keybinds.Binding(pygame.K_x, mods=pygame.KMOD_CTRL)) keybinds.get_instance().set_binding( const.SELECT_ALL, keybinds.Binding(pygame.K_a, mods=[pygame.KMOD_CTRL, pygame.KMOD_NONE])) keybinds.get_instance().set_binding( const.SELECT_ALL_ONSCREEN, keybinds.Binding( pygame.K_a, mods=[pygame.KMOD_SHIFT, pygame.KMOD_CTRL, pygame.KMOD_NONE])) path_to_cursors = util.resource_path("assets/cursors.png") cursors.init_cursors(path_to_cursors, [(const.CURSOR_DEFAULT, [0, 0, 16, 16], (0, 0)), (const.CURSOR_HAND, [16, 0, 16, 16], (5, 3)), (const.CURSOR_INVIS, [32, 0, 16, 16], (0, 0))]) cursors.set_cursor(const.CURSOR_DEFAULT) globaltimer.set_show_fps(True) gs.get_instance().load_data_from_disk() scenes.set_instance(menus.CircuitsSceneManager(menus.MainMenuScene()))
def all_sprites(self): for spr in gs.get_instance().all_sprites(): yield spr for spr in scenes.get_instance().all_sprites(): yield spr
def cleanup(self): gs.get_instance().save_data_to_disk()
def init(name_of_game): print("INFO: pygame version: " + pygame.version.ver) print("INFO: initializing sounds...") pygame.mixer.pre_init(44100, -16, 1, 2048) pygame.mixer.init() pygame.init() window_icon = pygame.image.load(Utils.resource_path("assets/icon.png")) pygame.display.set_icon(window_icon) window.create_instance(window_size=DEFAULT_SCREEN_SIZE, min_size=MINIMUM_SCREEN_SIZE) window.get_instance().set_caption(name_of_game) window.get_instance().show() render_eng = renderengine.create_instance() render_eng.init(*DEFAULT_SCREEN_SIZE) render_eng.set_min_size(*MINIMUM_SCREEN_SIZE) sprite_atlas = spritesheets.create_instance() spriteref.MAIN_SHEET = sprite_atlas.add_sheet(spriteref.MainSheet()) atlas_surface = sprite_atlas.create_atlas_surface() # uncomment to save out the full texture atlas # pygame.image.save(atlas_surface, "texture_atlas.png") texture_data = pygame.image.tostring(atlas_surface, "RGBA", 1) width = atlas_surface.get_width() height = atlas_surface.get_height() render_eng.set_texture(texture_data, width, height) COLOR = True SORTS = True render_eng.add_layer( layers.ImageLayer(spriteref.LAYER_SCENE_BG, 0, False, COLOR)) render_eng.add_layer( layers.ImageLayer(spriteref.LAYER_SCENE_ENVIRONMENT, 5, False, COLOR)) render_eng.add_layer( layers.ImageLayer(spriteref.LAYER_SCENE_FG, 10, SORTS, COLOR)) render_eng.add_layer( layers.ImageLayer(spriteref.LAYER_UI_BG, 12, SORTS, COLOR)) render_eng.add_layer( layers.ImageLayer(spriteref.LAYER_UI_FG, 15, SORTS, COLOR)) render_eng.add_layer( layers.ImageLayer(spriteref.LAYER_UI_TOOLTIP, 20, SORTS, COLOR)) import src.game.towers as towers # bleh towers.init_towers() gs.create_instance() gs.get_instance().set_game_state(gamestate.GameState()) inputs.create_instance() px_scale = _calc_pixel_scale(DEFAULT_SCREEN_SIZE) render_eng.set_pixel_scale(px_scale)
"Or, you can go downstairs and bring the station back online. Our work will continue and our purpose will be fulfilled.", speaker=Speaker.NONE, id_resolver=lookup), DialogFragment( "Deep down, you know what must be done. The choice is yours, A, B, C, and D.", speaker=Speaker.NONE, id_resolver=lookup)) else: return DialogFragment("I have nothing to say.", speaker=Speaker.OTHER, id_resolver=lookup) REPLACEMENTS = { "{MOVEMENT_KEYS}": lambda: gs.get_instance().get_user_friendly_movement_keys(), "{INTERACT_KEYS}": lambda: keybinds.get_instance().get_keys(const.ACTION).get_pretty_names(), "{JUMP_KEYS}": lambda: keybinds.get_instance().get_keys(const.JUMP).get_pretty_names(), "{PLAYER_A}": lambda: playertypes.PlayerTypes.FAST.get_name(), "{PLAYER_B}": lambda: playertypes.PlayerTypes.SMALL.get_name(), "{PLAYER_C}": lambda: playertypes.PlayerTypes.HEAVY.get_name(), "{PLAYER_D}": lambda: playertypes.PlayerTypes.FLYING.get_name() }
def update_sprites(self): xy = self.get_xy(absolute=True) screen_size = renderengine.get_instance().get_game_size() size = self.get_size() if self.bg_sprite is None: self.bg_sprite = sprites.ImageSprite.new_sprite( spriteref.UI_BG_LAYER, depth=10) bg_model = spritesheets.get_white_square_img(self.bg_opacity) self.bg_sprite = self.bg_sprite.update( new_model=bg_model, new_x=xy[0], new_y=xy[1], new_ratio=(size[0] / bg_model.width(), size[1] / bg_model.height()), new_color=colors.PERFECT_BLACK) text_rect = [ xy[0] + self.inset, xy[1] + self.inset, size[0] - self.inset * 2, size[1] - self.inset * 2 ] all_sprites = self.current_dialog.get_speaker_sprites() if len(all_sprites) > 0: speaker_img = all_sprites[gs.get_instance().anim_tick() // 8 % len(all_sprites)] else: speaker_img = None if speaker_img is not None: speaker_sc = 3 speaker_size = speaker_img.size(scale=speaker_sc) speaker_on_right_side = self.current_dialog.put_speaker_sprite_on_right_side( ) if speaker_on_right_side: speaker_x = xy[0] + size[0] - speaker_size[0] - self.inset text_rect = [ xy[0] + self.inset, xy[1] + self.inset, size[0] - self.inset * 2 - speaker_size[0], size[1] - self.inset * 2 ] else: speaker_x = xy[0] + self.inset text_rect = [ speaker_x + speaker_size[0] + self.inset, xy[1] + self.inset, size[0] - self.inset * 2 - speaker_size[0], size[1] - self.inset * 2 ] if self.speaker_sprite is None: self.speaker_sprite = sprites.ImageSprite.new_sprite( spriteref.UI_FG_LAYER) self.speaker_sprite = self.speaker_sprite.update( new_model=speaker_img, new_x=speaker_x, new_y=screen_size[1] - speaker_size[1], new_xflip=speaker_on_right_side, new_scale=speaker_sc) else: self.speaker_sprite = None text_color = self.current_dialog.get_text_color() visible_text = "\n".join( sprites.TextSprite.wrap_text_to_fit(self._get_visible_text(), text_rect[2], scale=1, font_lookup=self.get_font())) if self.text_sprite is None: self.text_sprite = sprites.TextSprite(spriteref.UI_FG_LAYER, 0, 0, "blah", font_lookup=self.get_font()) self.text_sprite.update(new_x=text_rect[0], new_y=text_rect[1], new_text=visible_text, new_color=text_color)
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()