def Start(self): self.skippable = False # Action-specific adjustments self.action_data["key"] = "DialogueFrame" # PROJECT DEFAULTS OVERRIDE if "sprite" not in self.action_data: self.action_data['sprite'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_frame_sprite'] if "position" not in self.action_data: self.action_data['position'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_frame_position'] if "z_order" not in self.action_data: self.action_data['z_order'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_frame_z_order'] if "center_align" not in self.action_data: self.action_data['center_align'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_frame_center_align'] dialogue_frame = SpriteRenderable(self.scene, self.action_data) # Add the dialogue interface to the sprite group so they exist until explicitly unloaded self.scene.active_renderables.Add(dialogue_frame) self.scene.Draw() self.Complete()
def Start(self): # OVERRIDES WITH NO PROJECT DEFAULTS if "position" not in self.action_data: self.action_data["position"] = (0, 0) # PROJECT DEFAULTS OVERRIDE if "z_order" not in self.action_data: self.action_data["z_order"] = Settings.getInstance( ).project_settings["Sprite"]["z_order"] if "center_align" not in self.action_data: self.action_data["center_align"] = Settings.getInstance( ).project_settings["Sprite"]["center_align"] new_sprite = SpriteRenderable(self.scene, self.action_data) # If the user requested a flip action, do so if "flip" in self.action_data: if self.action_data["flip"]: new_sprite.Flip() self.scene.active_renderables.Add(new_sprite) # Any transitions are applied to the sprite post-load if "None" not in self.action_data["transition"]["type"]: self.active_transition = self.a_manager.CreateTransition( self.action_data["transition"], new_sprite) self.active_transition.Start() else: self.scene.Draw() self.Complete() return new_sprite
def Start(self): # Action-specific adjustments self.action_data['position'] = (0, 0) self.action_data['key'] = 'Transition' self.action_data['center_align'] = False self.action_data[ 'sprite'] = "HBEngine/Content/Sprites/TransitionEffects/transition_fade_black.png" # PROJECT DEFAULTS OVERRIDE if 'z_order' not in self.action_data: self.action_data['z_order'] = Settings.getInstance( ).project_settings['Scene Transitions']['z_order'] if 'speed' not in self.action_data: self.speed = Settings.getInstance( ).project_settings['Scene Transitions']['speed'] else: self.speed = self.action_data['speed'] new_sprite = SpriteRenderable(self.scene, self.action_data) self.scene.active_renderables.Add(new_sprite) self.scene.Draw() self.renderable = new_sprite self.progress = self.renderable.GetSurface().get_alpha() self.goal = 0 return new_sprite
def UpdateResolution(self, new_size_index, flag=0): # Use the given, but always add HWSURFACE and DOUBLEBUF if not Settings.getInstance().resolution == new_size_index: Settings.getInstance().resolution = new_size_index pygame.display.set_mode( Settings.getInstance().resolution_options[new_size_index], flag) self.scene_manager.active_scene.Draw()
def Resize(self): """ Determines a new sprite size based on the difference between the main resolution and the new resolution """ # Generate the new screen size scale multiplier, then cache it in the scene manager in case scenes change new_resolution = Settings.getInstance().resolution_options[Settings.getInstance().resolution] self.resolution_multiplier = self.CalculateScreenSizeMultiplier(Settings.getInstance().main_resolution, new_resolution) self.scene_manager.resolution_multiplier = self.resolution_multiplier # Inform each renderable of the resolution change so they can update their respective elements for renderable in self.active_renderables.Get(): renderable.RecalculateSize(self.resolution_multiplier) # Resize any child renderables after resizing the parent if renderable.children: for child in renderable.children: child.RecalculateSize(self.resolution_multiplier) # Redraw the scaled sprites self.Draw()
def Start(self): new_sound = pygame.mixer.Sound( Settings.getInstance().ConvertPartialToAbsolutePath( self.action_data["sound"])) new_sound.set_volume(self.action_data["volume"]) # Sound objects don't have a way of checking their progress, so let's keep track and monitor # the channel it was assigned to. Once it's empty, it's a good assumption that it's successfully completed self.assigned_channel = new_sound.play(0) self.scene.active_sounds[self.action_data["key"]] = new_sound return self.assigned_channel
def __init__(self, window): # Objects self.window = window self.active_scene = None # Cached Values (Scene agnostic) self.resolution_multiplier = None # Null by default to allow the starting scene to generate a starting value self.pause_menu_data = None # Menu data is stored in the manager, but the menu is owned by a scene self.scene_types = { FileType.Scene_Dialogue: DialogueScene, FileType.Scene_Point_And_Click: PointAndClickScene } # Load the starting scene defined in the project settings if not Settings.getInstance( ).project_settings["Game"]["starting_scene"]: raise ValueError( "No starting scene was provided in the project settings") self.LoadScene( Settings.getInstance().project_settings["Game"]["starting_scene"])
def Main(self): pygame.init() mixer.init() clock = pygame.time.Clock() window = pygame.display.set_mode( Settings.getInstance().active_resolution) self.scene_manager = SceneManager(window) # Start the game loop is_running = True while is_running is True: events = pygame.event.get() # Handle all system actions for event in events: if event.type == pygame.QUIT: is_running = False if event.type == pygame.KEYDOWN: # Maximize if event.key == pygame.K_1: self.UpdateResolution(1, pygame.FULLSCREEN) self.scene_manager.ResizeScene() # Minimize if event.key == pygame.K_2: self.UpdateResolution(0) self.scene_manager.ResizeScene() # Exit if event.key == pygame.K_ESCAPE: is_running = False if event.type == pygame.QUIT: is_running = False # Debug - FPS if event.key == pygame.K_F3: self.show_fps = not self.show_fps # Update scene logic. This drives the core game functionality self.scene_manager.active_scene.Update(events) # Debug Logging if self.show_fps: print(clock.get_fps()) # Refresh any changes pygame.display.update() # Get the time in miliseconds converted to seconds since the last frame. Used to avoid frame dependency # on actions self.scene_manager.active_scene.delta_time = clock.tick(60) / 1000
def __init__(self, scene, renderable_data, initial_rescale=True): super().__init__(scene, renderable_data) # YAML Parameters sprite = Settings.getInstance().ConvertPartialToAbsolutePath( self.renderable_data['sprite']) try: self.surface = pygame.image.load(sprite).convert_alpha() self.rect = self.surface.get_rect() except Exception as exc: print( "Failed to load data file for Renderable - Either the file was not found, or it is not a " f"supported file type:\n{exc}\n") # For new objects, resize initially in case we're already using a scaled resolution. Allow descendents # to defer this though if they need to do any additional work beforehand if initial_rescale: self.RecalculateSize(self.scene.resolution_multiplier)
def Start(self): # OVERRIDES WITH NO PROJECT DEFAULTS if "position" not in self.action_data: self.action_data["position"] = (0, 0) # PROJECT DEFAULTS OVERRIDE if "z_order" not in self.action_data: self.action_data["z_order"] = Settings.getInstance( ).project_settings["Text"]['z_order'] if "center_align" not in self.action_data: self.action_data["center_align"] = Settings.getInstance( ).project_settings["Text"]["center_align"] if "wrap_bounds" not in self.action_data: self.action_data["wrap_bounds"] = Settings.getInstance( ).project_settings["Text"]["wrap_bounds"] if "font" not in self.action_data: self.action_data["font"] = Settings.getInstance( ).project_settings["Text"]["font"] if "text_size" not in self.action_data: self.action_data["text_size"] = Settings.getInstance( ).project_settings["Text"]["size"] if "text_color" not in self.action_data: self.action_data["text_color"] = Settings.getInstance( ).project_settings["Text"]["color"] new_text_renderable = TextRenderable(self.scene, self.action_data) # Add the text to the renderables list instead of the sprite group as text is a temporary element that is # not meant to be kept around long-term self.scene.active_renderables.Add(new_text_renderable) if "None" not in self.action_data["transition"]["type"]: self.active_transition = self.a_manager.CreateTransition( self.action_data["transition"], new_text_renderable) self.active_transition.Start() else: self.scene.Draw() self.Complete() return new_text_renderable
def LoadScene(self, scene_file): """ Given a path to a scene file, check it's type, and load the corresponding scene object """ # We need to read the file to find it's type. This is denoted by the 'type' value somewhere near the top of the # file. We can't guarentee it's position since the metadata may grow one day, and the line number would shift. scene_type = None with open( Settings.getInstance().ConvertPartialToAbsolutePath( scene_file), "r") as f: for line in f: if line.startswith("type:"): scene_type = FileType[line.replace("type: ", "").strip()] if scene_type is not None: if scene_type in self.scene_types: del self.active_scene self.active_scene = self.scene_types[scene_type](scene_file, self.window, self) else: raise ValueError( f"Failed to Load Scene - Specified scene type does not exist: {scene_type}" ) else: raise ValueError(f"No scene type specified in file '{scene_file}'")
def Start(self): self.skippable = False # Background-specific adjustments self.action_data["position"] = (0, 0) self.action_data["key"] = "Background" self.action_data["center_align"] = False # PROJECT DEFAULTS OVERRIDE if "z_order" not in self.action_data: self.action_data["z_order"] = Settings.getInstance( ).project_settings["Sprite"]["background_z_order"] new_sprite = SpriteRenderable( self.scene, self.action_data, ) self.scene.active_renderables.Add(new_sprite) self.scene.Draw() self.Complete() return new_sprite
def __init__(self, scene_data_file, window, scene_manager): self.window = window self.scene_manager = scene_manager self.active_renderables = RenderableGroup() self.active_sounds = {} self.active_music = None # Only one music stream is supported. Stores a 'SoundAction' self.a_manager = ActionManager(self) self.pause_menu = None # Keep track of delta time so time-based actions can be more accurate across systems self.delta_time = 0 # Read in the active scene data self.scene_data = Reader.ReadAll(Settings.getInstance().ConvertPartialToAbsolutePath(scene_data_file)) # Load any cached data on the scene manager if not self.scene_manager.resolution_multiplier: self.resolution_multiplier = 1 else: self.resolution_multiplier = self.scene_manager.resolution_multiplier self.LoadSceneData()
def Start(self): self.skippable = False # If the user hasn't removed the previous music, forcefully remove it here without any transition if self.scene.active_music: pygame.mixer.music.stop( ) # This will invoke the end-event on the existing music action # The pygame music system doesn't use objects, but instead uses a stream. Any changes made against music # are made to the stream itself pygame.mixer.music.load( Settings.getInstance().ConvertPartialToAbsolutePath( self.action_data["music"])) pygame.mixer.music.set_volume(self.action_data["volume"]) loop_count = 0 if self.action_data["loop"]: loop_count = -1 # Since there can only be one music item active, there is no need to use a key identifier pygame.mixer.music.play(loop_count) self.scene.active_music = self return None
def __init__(self, project_path): #@TODO: What is the right way to handle this? if not project_path: print( "Warning: No project path provided - Defaulting to the engine root" ) Settings.getInstance().SetProjectRoot(project_path) Settings.getInstance().Evaluate(Settings.getInstance().project_dir + "/Config/Game.yaml") pygame.display.set_caption( Settings.getInstance().project_settings['Game']['title']) # Declare the scene manager, but we'll initialize it during the game loop self.scene_manager = None # DEBUG TRIGGERS self.show_fps = False
def Start(self): # Dialogue-specific adjustments assert type( self.scene ) == Core.BaseClasses.scene_dialogue.DialogueScene, print( "The active scene is not of the 'DialogueScene' type. This action can not be performed" ) #@TODO: Can we consolidate to avoid duplicated if checks for global settings? # If the user provides a 'character' block, use details from the relevant character data file if it exists, as # well as any applicable global settings if 'character' in self.action_data: character_data = self.scene.character_data[ self.action_data['character']] # Dialogue-specific adjustments character_data['key'] = 'SpeakerText' # OVERRIDES WITH NO PROJECT DEFAULTS assert 'name' in character_data, print( f"Character file '{self.action_data['character']}' does not have a 'name' param" ) character_data['text'] = character_data['name'] assert 'color' in character_data, print( f"Character file '{self.action_data['character']}' does not have a 'color' param" ) character_data['text_color'] = character_data['color'] # PROJECT DEFAULTS character_data['position'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_text_position'] character_data['z_order'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_z_order'] character_data['center_align'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_center_align'] character_data['font'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_font'] character_data['text_size'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_text_size'] new_character_text = TextRenderable(self.scene, character_data) # Speaker text does not support transitions currently self.scene.active_renderables.Add(new_character_text) # If the user has specified a 'speaker' block, build the speaker renderable details using any provided # information, and / or any global settings elif 'speaker' in self.action_data: # Dialogue-specific adjustments self.action_data['speaker']['key'] = 'SpeakerText' # PROJECT DEFAULTS OVERRIDE if 'position' not in self.action_data['speaker']: self.action_data['speaker']['position'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_text_position'] if 'z_order' not in self.action_data['speaker']: self.action_data['speaker']['z_order'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_z_order'] if 'center_align' not in self.action_data['speaker']: self.action_data['speaker'][ 'center_align'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_center_align'] if 'font' not in self.action_data['speaker']: self.action_data['speaker']['font'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_font'] if 'text_size' not in self.action_data['speaker']: self.action_data['speaker'][ 'text_size'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_text_size'] if 'text_color' not in self.action_data['speaker']: self.action_data['speaker'][ 'text_color'] = Settings.getInstance( ).project_settings['Dialogue']['speaker_text_color'] new_speaker_text = TextRenderable(self.scene, self.action_data['speaker']) # Speaker text does not support transitions currently self.scene.active_renderables.Add(new_speaker_text) # If the user has specified a 'dialogue' block, build the speaker renderable if 'dialogue' in self.action_data: # Dialogue-specific adjustments self.action_data['dialogue']['key'] = 'DialogueText' # PROJECT DEFAULTS OVERRIDE if 'position' not in self.action_data['dialogue']: self.action_data['dialogue'][ 'position'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_text_position'] if 'z_order' not in self.action_data['dialogue']: self.action_data['dialogue']['z_order'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_z_order'] if 'center_align' not in self.action_data['dialogue']: self.action_data['dialogue'][ 'center_align'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_center_align'] if 'font' not in self.action_data['dialogue']: self.action_data['dialogue']['font'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_font'] if 'text_size' not in self.action_data['dialogue']: self.action_data['dialogue'][ 'text_size'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_text_size'] if 'text_color' not in self.action_data['dialogue']: self.action_data['dialogue'][ 'text_color'] = Settings.getInstance( ).project_settings['Dialogue']['dialogue_text_color'] new_dialogue_text = TextRenderable(self.scene, self.action_data['dialogue']) self.scene.active_renderables.Add(new_dialogue_text) # By default, dialogue text fades in. However, allow the user to override this behaviour if 'transition' in self.action_data['dialogue']: self.active_transition = self.a_manager.CreateTransition( self.action_data['dialogue']['transition'], new_dialogue_text) self.active_transition.Start() else: self.action_data['dialogue']['transition'] = { 'type': 'fade_in', 'speed': 1000 } self.active_transition = self.a_manager.CreateTransition( self.action_data['dialogue']['transition'], new_dialogue_text) self.active_transition.Start() return None
def Start(self): self.skippable = False # Choice-specific adjustments self.action_data["position"] = (0, 0) self.action_data["z_order"] = 0 self.action_data["center_align"] = False self.action_data["key"] = "Choice" # All choice options use the same underlying 'create_button' action. Specify and enforce that here # Additionally, apply all settings determined here to each choice button for choice in self.action_data["choices"]: # Build the child dict that gets sent to the interact action choice["action"] = { "action": "choose_branch", "branch": choice["branch"], "key": choice["key"] } # CHOICE BUTTONS - OVERRIDES WITH NO PROJECT DEFAULTS if "text_position" not in choice: choice["text_position"] = self.action_data["position"] # CHOICE BUTTONS - PROJECT DEFAULTS OVERRIDE if "sprite" not in choice: choice["sprite"] = Settings.getInstance( ).project_settings["Choice"]["button_sprite"] if 'sprite_hover' not in choice: choice["sprite_hover"] = Settings.getInstance( ).project_settings["Choice"]["button_sprite_hover"] if "sprite_clicked" not in choice: choice["sprite_clicked"] = Settings.getInstance( ).project_settings["Choice"]["button_sprite_clicked"] if "z_order" not in choice: choice["z_order"] = Settings.getInstance( ).project_settings["Choice"]["button_z_order"] if "center_align" not in choice: choice["center_align"] = Settings.getInstance( ).project_settings["Choice"]["button_center_align"] if "text_z_order" not in choice: choice["text_z_order"] = Settings.getInstance( ).project_settings["Choice"]["button_text_z_order"] if "text_center_align" not in choice: choice["center_align"] = Settings.getInstance( ).project_settings["Choice"]["button_text_center_align"] if "font" not in choice: choice["font"] = Settings.getInstance( ).project_settings["Choice"]["button_font"] if "text_size" not in choice: choice["text_size"] = Settings.getInstance( ).project_settings["Choice"]["button_text_size"] if "text_color" not in choice: choice["text_color"] = Settings.getInstance( ).project_settings["Choice"]["button_text_color"] # Choices provide blocks of options. Each one needs to be built new_renderable = Choice(self.scene, self.action_data) # Generate and add each choice button to the choice container for choice_data in self.action_data["choices"]: new_renderable.children.append( self.a_manager.PerformAction(choice_data, "create_choice_button")) self.scene.active_renderables.Add(new_renderable) self.scene.Draw() self.Complete() return new_renderable
def Start(self): # If the user has specified a 'speaker' block, build the speaker renderable details using any provided # information, and / or any global settings if "speaker" in self.action_data: # Dialogue-specific adjustments self.action_data["speaker"]['key'] = "SpeakerText" self.action_data["speaker"]["wrap_bounds"] = Settings.getInstance( ).project_settings["Dialogue"]["speaker_wrap_bounds"] # PROJECT DEFAULTS OVERRIDE if "position" not in self.action_data["speaker"]: self.action_data["speaker"]["position"] = Settings.getInstance( ).project_settings["Dialogue"]["speaker_text_position"] if "center_align" not in self.action_data["speaker"]: self.action_data["speaker"][ "center_align"] = Settings.getInstance( ).project_settings["Dialogue"]["speaker_center_align"] if "text_size" not in self.action_data["speaker"]: self.action_data["speaker"][ "text_size"] = Settings.getInstance( ).project_settings["Dialogue"]["speaker_text_size"] if "text_color" not in self.action_data["speaker"]: self.action_data["speaker"][ "text_color"] = Settings.getInstance( ).project_settings["Dialogue"]["speaker_text_color"] if "font" not in self.action_data["speaker"]: self.action_data["speaker"]["font"] = Settings.getInstance( ).project_settings["Dialogue"]["speaker_font"] if "z_order" not in self.action_data["speaker"]: self.action_data["speaker"]["z_order"] = Settings.getInstance( ).project_settings["Dialogue"]["speaker_z_order"] new_speaker_text = TextRenderable(self.scene, self.action_data["speaker"]) # Speaker text does not support transitions currently self.scene.active_renderables.Add(new_speaker_text) # If the user has specified a 'dialogue' block, build the speaker renderable if "dialogue" in self.action_data: # Dialogue-specific adjustments self.action_data["dialogue"]["key"] = "DialogueText" self.action_data["dialogue"]["wrap_bounds"] = Settings.getInstance( ).project_settings["Dialogue"]["dialogue_wrap_bounds"] # PROJECT DEFAULTS OVERRIDE if "position" not in self.action_data["dialogue"]: self.action_data["dialogue"][ "position"] = Settings.getInstance( ).project_settings["Dialogue"]["dialogue_text_position"] if "center_align" not in self.action_data["dialogue"]: self.action_data["dialogue"][ "center_align"] = Settings.getInstance( ).project_settings["Dialogue"]["dialogue_center_align"] if "text_size" not in self.action_data["dialogue"]: self.action_data["dialogue"][ "text_size"] = Settings.getInstance( ).project_settings["Dialogue"]["dialogue_text_size"] if "text_color" not in self.action_data["dialogue"]: self.action_data["dialogue"][ "text_color"] = Settings.getInstance( ).project_settings["Dialogue"]["dialogue_text_color"] if "font" not in self.action_data["dialogue"]: self.action_data["dialogue"]["font"] = Settings.getInstance( ).project_settings["Dialogue"]["dialogue_font"] if "z_order" not in self.action_data["dialogue"]: self.action_data["dialogue"]["z_order"] = Settings.getInstance( ).project_settings["Dialogue"]["dialogue_z_order"] new_dialogue_text = TextRenderable(self.scene, self.action_data["dialogue"]) self.scene.active_renderables.Add(new_dialogue_text) # By default, dialogue text fades in. However, allow the user to override this behaviour if "None" not in self.action_data["dialogue"]["transition"][ "type"]: self.active_transition = self.a_manager.CreateTransition( self.action_data["dialogue"]["transition"], new_dialogue_text) self.active_transition.Start() else: self.action_data["dialogue"]["transition"] = { "type": "fade_in", "speed": 1000 } self.active_transition = self.a_manager.CreateTransition( self.action_data["dialogue"]["transition"], new_dialogue_text) self.active_transition.Start() return None
def Start(self): self.skippable = False # OVERRIDES WITH NO PROJECT DEFAULTS if 'position' not in self.action_data: self.action_data['position'] = (0, 0) if 'text_position' not in self.action_data: self.action_data['text_position'] = self.action_data['position'] # PROJECT DEFAULTS OVERRIDE if 'sprite' not in self.action_data: self.action_data['sprite'] = Settings.getInstance( ).project_settings['Button']['sprite'] if 'sprite_hover' not in self.action_data: self.action_data['sprite_hover'] = Settings.getInstance( ).project_settings['Button']['sprite_hover'] if 'sprite_clicked' not in self.action_data: self.action_data['sprite_clicked'] = Settings.getInstance( ).project_settings['Button']['sprite_clicked'] if 'z_order' not in self.action_data: self.action_data['z_order'] = Settings.getInstance( ).project_settings['Button']['button_z_order'] if 'center_align' not in self.action_data: self.action_data['center_align'] = Settings.getInstance( ).project_settings['Button']['button_center_align'] if 'text_z_order' not in self.action_data: self.action_data['text_z_order'] = Settings.getInstance( ).project_settings['Button']['text_z_order'] if 'text_center_align' not in self.action_data: self.action_data['center_align'] = Settings.getInstance( ).project_settings['Button']['text_center_align'] if 'font' not in self.action_data: self.action_data['font'] = Settings.getInstance( ).project_settings['Button']['font'] if 'text_size' not in self.action_data: self.action_data['text_size'] = Settings.getInstance( ).project_settings['Button']['text_size'] if 'text_color' not in self.action_data: self.action_data['text_color'] = Settings.getInstance( ).project_settings['Button']['text_color'] new_renderable = Button(self.scene, self.action_data) # If the user requested a flip action, do so if 'flip' in self.action_data: if self.action_data['flip']: new_renderable.Flip() self.scene.active_renderables.Add(new_renderable) self.scene.Draw() self.Complete() return new_renderable