commit 52f21499b0b8e2318bf67d06c34d29983288b547
parent 0e3b34b5cbf9fda75fb4c0156f9ea2b0496066c1
Author: Erik Letson <hmagellan@hmagellan.com>
Date: Fri, 30 Oct 2020 14:19:13 -0500
Camera implemented
Diffstat:
5 files changed, 69 insertions(+), 18 deletions(-)
diff --git a/data/json/stats/jisella_1.json b/data/json/stats/jisella_1.json
@@ -2,19 +2,12 @@
"name" : "Jisella",
"LVL" : 1,
"HP" : 100,
- "HP_GR" : 100,
"ATK" : 135,
- "ATK_GR" : 110,
"DEF" : 45,
- "DEF_GR" : 100,
"SPD" : 100,
- "SPD_GR" : 100,
"ACC" : 60,
- "ACC_GR" : 100,
"INT" : 50,
- "INT_GR" : 90,
"WIS" : 30,
- "WIS_GR" : 90,
"MOVE" : 8,
"CRIT" : 10,
"SKIL" : 4,
diff --git a/src/board.py b/src/board.py
@@ -38,6 +38,7 @@ class BoardManager(manager.Manager):
self.current_board = None
self.loaded_boards = {}
self.board_overlay = pygame.sprite.LayeredDirty()
+ self.current_board_dimensions = (0, 0)
# Move values
self.moving_entity = None
@@ -71,6 +72,7 @@ class BoardManager(manager.Manager):
"""
if boardname in self.loaded_boards.keys():
self.current_board = self.loaded_boards[boardname]
+ self.current_board_dimensions = (self.current_board.tmx_data.width * self.current_board.tmx_data.tilewidth, self.current_board.tmx_data.height * self.current_board.tmx_data.tileheight)
self.load_overlay()
def get_tile_pos_at_position(self, pos):
diff --git a/src/constants.py b/src/constants.py
@@ -25,7 +25,7 @@ COLORKEY = (255, 0, 255)
# Other constants
PIECE_MOVE_SPEED = 2
-PIECE_MOVE_DELAY = PIECE_MOVE_SPEED * 3
+PIECE_MOVE_DELAY = PIECE_MOVE_SPEED * 4
# File paths
DATA_PATH = os.path.join(os.getcwd(), "data")
diff --git a/src/game.py b/src/game.py
@@ -42,6 +42,7 @@ class Game(object):
# Subsystems
self.interface = subsystem.GameInterface(self)
self.manager_bus = subsystem.ManagerBus(self)
+ self.camera = subsystem.GameCamera(self)
# Managers
self.sheet_manager = images.SheetManager(self, self.manager_bus)
@@ -77,6 +78,7 @@ class Game(object):
self.control_mode = CTRL_MODES.Main_Menu_Normal
self.menu_manager.load_menu_from_file("mainmenu.json")
self.menu_manager.switch_to_menu("mainmenu.json")
+ self.camera.load_camera_surface((SCREEN_WIDTH, SCREEN_HEIGHT))
elif new_mode == STATE_MODES.Battle_Mode:
self.control_mode = CTRL_MODES.Turn_Normal
# TODO: Obv this must be made more generic. Currently only
@@ -86,14 +88,19 @@ class Game(object):
self.unit_manager.load_stats_from_json("jisella_1.json")
self.entity_manager.load_entities_from_json("testmap1.json")
self.entity_manager.load_tile_cursor("cursor1")
+ self.camera.load_camera_surface(self.board_manager.current_board_dimensions)
elif new_mode == STATE_MODES.Still_Scene_Mode:
self.control_mode = CTRL_MODES.Still_Scene_Normal
# TODO: Generic-ify
self.scene_manager.load_still_scene_from_file("testscene.json")
+ self.camera.load_camera_surface((SCREEN_WIDTH, SCREEN_HEIGHT))
def lose_control(self, time = -1, followup_mode = None):
"""
- Switch to no-control mode for a set period of time.
+ Switch to no-control mode for a set period of time. If
+ time is a negative number, automatic followup will not
+ occur in the update loop, thus locking the game in
+ No_Control mode.
"""
if followup_mode != None:
self.return_control_mode = followup_mode
@@ -116,7 +123,7 @@ class Game(object):
"""
# First, fill the entire screen with black
- self.screen.fill((0, 0, 0))
+ self.screen.fill((200, 200, 200))
# Next, update all the subsurfaces/game objects and draw them
# TODO: This is WIP and will change
@@ -124,16 +131,19 @@ class Game(object):
# State_Mode-specific actions (can be further subdivided by Control_Mode)
if self.state_mode == STATE_MODES.Main_Menu_Mode:
- self.menu_manager.update_current_menu(self.screen)
+ self.menu_manager.update_current_menu(self.camera.camera_surface)
elif self.state_mode == STATE_MODES.Battle_Mode:
- self.board_manager.update_board(self.screen)
- self.entity_manager.update_entities(self.screen)
+ self.board_manager.update_board(self.camera.camera_surface)
+ self.entity_manager.update_entities(self.camera.camera_surface)
# NOTE: MenuManager should not be an overlay for the
# battle mode. In-battle menus should be handled
# by EntityManager most likely
#self.menu_manager.update_current_menu(self.screen)
elif self.state_mode == STATE_MODES.Still_Scene_Mode:
- self.scene_manager.update_scene(self.screen)
+ self.scene_manager.update_scene(self.camera.camera_surface)
+
+ # Draw the camera to the screen
+ self.screen.blit(self.camera.camera_surface, self.camera.camera_surface_offset)
# State_Mode agnostic, Control_Mode specific actions
if self.control_mode == CTRL_MODES.No_Control:
diff --git a/src/subsystem.py b/src/subsystem.py
@@ -9,6 +9,7 @@ from .constants import *
# 1. The generic GameSubsystem class, which abstract subsystems (like Interface) are children of, as well as all Managers
# 2. The GameInterface class, which handles game events such as keyboard and mouse input
# 3. The ManagerBus class, which is a communication mechanism used by Managers as well as other subsystems and ever game objects
+# 4. The GameCamera class, which controls camera-oriented logic and drawing
#######################################
# Section 1 - The GameSubsystem class #
@@ -80,15 +81,17 @@ class GameInterface(GameSubsystem):
"""
# TODO: ManagerBus will have a field day here...
if event.button == 1:
+ mousepos = pygame.mouse.get_pos()
+ mousepos = (mousepos[0] - self.game.camera.camera_surface_offset[0], mousepos[1] - self.game.camera.camera_surface_offset[1])
if self.game.state_mode == STATE_MODES.Main_Menu_Mode:
if self.game.control_mode == CTRL_MODES.Main_Menu_Normal:
- self.game.menu_manager.trigger_button_at_pos(pygame.mouse.get_pos())
+ self.game.menu_manager.trigger_button_at_pos(mousepos)
elif self.game.state_mode == STATE_MODES.Battle_Mode:
if self.game.control_mode == CTRL_MODES.Turn_Normal:
- if self.game.entity_manager.select_entities_with_tile_cursor(self.game.board_manager.get_tile_at_position(pygame.mouse.get_pos())):
+ if self.game.entity_manager.select_entities_with_tile_cursor(self.game.board_manager.get_tile_at_position(mousepos)):
self.game.control_mode = CTRL_MODES.Turn_Select_Move
elif self.game.control_mode == CTRL_MODES.Turn_Select_Move:
- to_path = self.game.board_manager.get_path_by_previous_moves(self.game.entity_manager.selected_entity.tile_pos, self.game.board_manager.get_tile_pos_at_position(pygame.mouse.get_pos()))
+ to_path = self.game.board_manager.get_path_by_previous_moves(self.game.entity_manager.selected_entity.tile_pos, self.game.board_manager.get_tile_pos_at_position(mousepos))
if self.game.entity_manager.set_entity_move_to_tile_path(self.game.entity_manager.selected_entity, to_path):
# TODO: The length of time shouldn't have magic numbers. Neither should unit visual movement speed.
self.game.lose_control(len(to_path) * PIECE_MOVE_DELAY, CTRL_MODES.Turn_Normal)
@@ -111,7 +114,11 @@ class GameInterface(GameSubsystem):
"""
# Update cursor position
if self.game.state_mode == STATE_MODES.Battle_Mode:
- self.game.entity_manager.position_tile_cursor(self.game.board_manager.get_tile_at_position(pygame.mouse.get_pos()))
+ mousepos = pygame.mouse.get_pos()
+ mousepos = (mousepos[0] - self.game.camera.camera_surface_offset[0], mousepos[1] - self.game.camera.camera_surface_offset[1])
+ tilepos = self.game.board_manager.get_tile_at_position(mousepos)
+ if tilepos != None:
+ self.game.entity_manager.position_tile_cursor(tilepos)
####################################
# Section 3 - The ManagerBus class #
@@ -138,3 +145,42 @@ class ManagerBus(GameSubsystem):
# Module references
self.managers = {}
+
+####################################
+# Section 4 - The GameCamera class #
+####################################
+
+class GameCamera(GameSubsystem):
+ """
+ Object that controls the camera surface and
+ moves it in relation to input. The camera
+ surface is then drawn onto the game's real
+ screen at an offset determined by input.
+ """
+
+ def __init__(self, game):
+
+ # Parent init
+ super().__init__(game)
+
+ # Camera surface values
+ self.camera_surface = pygame.Surface((0, 0)).convert() # This surface is initialized whenever a new map or other game area is loaded
+ self.camera_surface_rect = self.camera_surface.get_rect()
+ self.camera_surface_offset = (0, 0) # The rect topleft is never changed; rather, this value is used by game to draw the camera surface at an offset
+
+ def load_camera_surface(self, dimensions, init_offset = (300, 0)):
+ """
+ Load up the camera surface as a new PyGame
+ surface object of the necessary size. Also
+ resets the camera offset.
+ """
+ self.camera_surface = pygame.Surface(dimensions).convert()
+ self.camera_surface_rect = self.camera_surface.get_rect()
+ self.camera_surface_offset = init_offset
+
+ def update_camera(self, surface = None):
+ """
+ Update and draw the camera contents.
+ """
+ if surface != None:
+ surface.blit(self.camera_surface, self.camera_surface_offset)