class Game: _control_to_selected_index = { Controls.select_item_0: 0, Controls.select_item_1: 1, Controls.select_item_2: 2, Controls.select_item_3: 3, Controls.select_item_4: 4, Controls.select_item_5: 5, Controls.select_item_6: 6, Controls.select_item_7: 7, Controls.select_item_8: 8, } def __init__(self): pg.init() pg.mouse.set_cursor(*CURSOR) self._camera = Camera() self._hotbar = Hotbar() self._world = World() self._main_player = Player("main_player", spawn_pos=PLAYER_DEFAULT_SPAWN_POS) self._action = GameAction.play def main_loop(self): while True: # Keyboard inputs keys_pressed = pg.key.get_pressed() mods_pressed = pg.key.get_mods() if (keys_pressed[Controls.quit] or pg.event.peek(pg.QUIT) or self._action == GameAction.quit or self._action == GameAction.quit_without_saving): return # Requesting horizontal movements does_horiz_movement = False if keys_pressed[Controls.move_left]: if mods_pressed == pg.KMOD_NONE: self._main_player.req_move_left() else: if mods_pressed & Mods.sprinting: self._main_player.req_sprint_left() does_horiz_movement ^= True if keys_pressed[Controls.move_right]: if mods_pressed == pg.KMOD_NONE: self._main_player.req_move_right() else: if mods_pressed & Mods.sprinting: self._main_player.req_sprint_right() does_horiz_movement ^= True if not does_horiz_movement: self._main_player.req_h_move_stop() # Requesting jumps if keys_pressed[Controls.jump]: self._main_player.req_jump() else: self._main_player.req_jump_stop() # Requesting camera zooms is_zooming = False if keys_pressed[Controls.zoom_in]: self._camera.req_zoom_in() is_zooming ^= True if keys_pressed[Controls.zoom_out]: self._camera.req_zoom_out() is_zooming ^= True if not is_zooming: self._camera.req_zoom_stop() # Mouse inputs mb_pressed = pg.mouse.get_pressed() # Select item in hotbar for control in self._control_to_selected_index: if keys_pressed[control]: self._hotbar.req_select_index( self._control_to_selected_index[control]) # Breaking blocks if mb_pressed[Controls.break_block]: self._world.req_break_block(self._camera.selected_block_w_pos) # Placing blocks if mb_pressed[Controls.place_block]: block = self._hotbar.selected_item self._world.req_place_block(self._camera.selected_space_w_pos, block, self._main_player.get_bounds()) # Applying movements self._main_player.move(self._world) self._camera.req_move(self._main_player.pos) self._camera.move() # Graphics self._world.draw_and_tick(self._camera) self._main_player.draw(self._camera, self._world) self.draw_gui() if DEBUG: self._camera.draw_debug_info() self._camera.display_flip_and_clock_tick() # Death if self._main_player.is_dead: self.death_loop() def death_loop(self): self._main_player.spawn() self._action = GameAction.quit def __enter__(self): if LOAD: # Create SAVES_CURRENT_DIR if it doesn't already exist. try: os.makedirs(CURRENT_SAVE_PATH) except FileExistsError: pass world_load_result = self._world.load_from_disk(CURRENT_SAVE_PATH) player_load_result = self._main_player.load_from_disk( CURRENT_SAVE_PATH) if world_load_result == LoadResult.incompatible or player_load_result == LoadResult.incompatible: self._action = GameAction.quit_without_saving print("Error: incompatible save file.") self._camera.set_transforms(self._main_player.pos) return self def __exit__(self, exc_type, exc_val, exc_tb): if SAVE and not self._action == GameAction.quit_without_saving: self._world.save_to_disk(CURRENT_SAVE_PATH) self._main_player.save_to_disk(CURRENT_SAVE_PATH) pg.quit() def draw_gui(self): self._camera.draw_block_selector(self._main_player.action_w_pos, self._world) self._hotbar.draw(self._camera)