wip: splits out camera from UI game scene; makes camera a per-room thing; updated check for running rooms directly; corrected timing issue w/ updating state immediately by ensuring animation player does seek with immediate animation update

This commit is contained in:
Duncan Brown
2022-04-14 22:31:01 -04:00
committed by Julian Murgia
parent 8d1b00bb90
commit 0175342a61
8 changed files with 86 additions and 54 deletions

View File

@@ -12,7 +12,7 @@ const RESERVED_OBJECTS = [
MUSIC,
SOUND,
SPEECH,
CAMERA
#CAMERA
]
@@ -283,6 +283,7 @@ func get_object(global_id: String, room: ESCRoom = null) -> ESCObject:
room_key = current_room_key
else:
room_key = ESCRoomObjectsKey.new()
room_key.room_global_id = room.global_id
room_key.room_instance_id = room.get_instance_id()

View File

@@ -89,6 +89,10 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void
]
)
if escoria.main.current_scene \
and escoria.game_scene.get_parent() == escoria.main.current_scene:
escoria.main.current_scene.remove_child(escoria.game_scene)
# Load room scene
var res_room = escoria.resource_cache.get_resource(room_path)
@@ -102,6 +106,16 @@ func change_scene(room_path: String, enable_automatic_transitions: bool) -> void
else:
room_scene.enabled_automatic_transitions = enable_automatic_transitions
# If the game scene is already in the tree but not a child of the room
# we remove it
if escoria.game_scene.is_inside_tree() \
and escoria.game_scene.get_parent() != room_scene:
var game_parent = escoria.game_scene.get_parent()
game_parent.remove_child(escoria.game_scene)
room_scene.add_child(escoria.game_scene)
room_scene.move_child(escoria.game_scene, 0)
room_scene.game = escoria.game_scene
escoria.main.set_scene(room_scene)
# We know the scene has been loaded. Make its global ID available for
@@ -160,11 +174,7 @@ func init_room(room: ESCRoom) -> void:
room.add_child(room.game)
room.move_child(room.game, 0)
# Determine whether this room was run from change_scene or directly
if escoria.main.has_node(room.name):
room.is_run_directly = false
else:
room.is_run_directly = true
if room.is_run_directly:
if escoria.main.current_scene == null:
escoria.main.set_scene(room)
@@ -219,25 +229,6 @@ func _perform_script_events(room: ESCRoom) -> void:
# With the room transitioned out, finish any room prep and run :setup if
# it exists.
if escoria.main.current_scene \
and escoria.game_scene.get_parent() == escoria.main.current_scene:
escoria.main.current_scene.remove_child(escoria.game_scene)
# If the game scene is already in the tree but not a child of the room
# we remove it
if escoria.game_scene.is_inside_tree() \
and escoria.game_scene.get_parent() != room:
var game_parent = escoria.game_scene.get_parent()
game_parent.remove_child(escoria.game_scene)
room.add_child(escoria.game_scene)
room.move_child(escoria.game_scene, 0)
room.game = escoria.game_scene
# We must first et the camera limits, and then worry about subsequent
# player setup since it relies on this.
escoria.main.set_camera_limits(0, room)
if room.player_scene:
room.player = room.player_scene.instance()
room.add_child(room.player)
@@ -264,7 +255,7 @@ func _perform_script_events(room: ESCRoom) -> void:
)
room.player.update_idle()
escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.set_target(room.player)
#escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.set_target(room.player)
if room.global_id.empty():
room.global_id = room.name
@@ -274,7 +265,27 @@ func _perform_script_events(room: ESCRoom) -> void:
and escoria.object_manager.get_start_location() != null:
room.player.teleport(escoria.object_manager.get_start_location().node)
# We make sure 'room' is set as the new current_scene, but without making
# it visible/the current scene tree.
if not yielded:
escoria.main.finish_current_scene_init(room)
# Add new camera to scene being prepared.
var new_player_camera: ESCCamera = escoria.resource_cache.get_resource(escoria.CAMERA_SCENE_PATH).instance()
new_player_camera.register()
room.player_camera = new_player_camera
# We must first set the camera limits, and then worry about subsequent
# player setup since it relies on this.
escoria.main.set_camera_limits(0, room)
# Add the camera in to the scene tree but don't make it active just yet.
new_player_camera.current = false
room.add_child(new_player_camera)
room.move_child(new_player_camera, 0)
var setup_event_added: bool = false
# Run the setup event, if there is one.
setup_event_added = _run_script_event(escoria.event_manager.EVENT_SETUP, room)
@@ -288,11 +299,17 @@ func _perform_script_events(room: ESCRoom) -> void:
yielded = true
if not yielded:
escoria.main.finish_current_scene_init(room)
if room.player:
escoria.object_manager.get_object(escoria.object_manager.CAMERA).node.set_target(room.player)
# Conclude the call to set_scene (thankyouverymuch, coroutines), including
# making the new room visible.
escoria.main.set_scene_finish()
# Maybe this is ok to put in set_scene_finish() above? But it might be a bit
# confusing to not see the matching camera.current updates.
new_player_camera.make_current()
# We know the scene has been loaded. Make its global ID available for
# use by ESC script.
escoria.globals_manager.set_global(

View File

@@ -134,7 +134,7 @@ func has_animation(name: String) -> bool:
func seek_end(name: String):
if _is_animation_player:
_animation_player.current_animation = name
_animation_player.seek(_animation_player.get_animation(name).length)
_animation_player.seek(_animation_player.get_animation(name).length, true)
else:
_animated_sprite.animation = name
_animated_sprite.frame = _animated_sprite.frames.get_frame_count(name)

View File

@@ -34,6 +34,9 @@ export(EditorRoomDebugDisplay) var editor_debug_mode \
# The player scene instance
var player
# The player camera
var player_camera: ESCCamera
# The game scene instance
var game
@@ -56,6 +59,10 @@ func _enter_tree():
# Sanitize camera limits, add player node and set the global id to the
# name of this node if it's not set manually
func _ready():
# Might as well just check here.
if get_parent() == get_tree().root and ProjectSettings.get_setting("application/run/main_scene") != self.filename:
is_run_directly = true
escoria.room_manager.init_room(self)

View File

@@ -30,6 +30,8 @@ const BUS_SFX = "SFX"
const BUS_MUSIC = "Music"
const BUS_SPEECH = "Speech"
const CAMERA_SCENE_PATH = "res://addons/escoria-core/game/scenes/camera_player/camera.tscn"
# Logger used
var logger: ESCLogger
@@ -97,6 +99,9 @@ var save_manager: ESCSaveManager
# The game scene loaded
var game_scene: ESCGame
# The main player camera
var player_camera: ESCCamera
# The compiled start script loaded from ProjectSettings
# escoria/main/game_start_script
var start_script: ESCScript

View File

@@ -67,10 +67,6 @@ func set_scene(p_scene: Node) -> void:
current_scene = p_scene
check_game_scene_methods()
#set_camera_limits(current_scene)
# Only called by the room manager in the case where it hasn't executed a
# coroutine prior to calling set_scene_finish().
@@ -83,24 +79,23 @@ func finish_current_scene_init(p_scene: Node) -> void:
current_scene = p_scene
check_game_scene_methods()
# set_camera_limits(current_scene)
# Completes the room swap and should be called by the room manager at the
# appropriate time.
func set_scene_finish() -> void:
current_scene.visible = true
# Final check for the critical game scene's existence.
check_game_scene_methods()
if previous_scene != null:
clear_scene()
# Make our new scene visible.
current_scene.visible = true
clear_previous_scene()
emit_signal("room_ready")
# Cleanup the previous scene
func clear_scene() -> void:
# Cleanup the previous scene if there was one.
func clear_previous_scene() -> void:
if previous_scene == null:
return

View File

@@ -21,14 +21,6 @@ func _ready():
_tween = Tween.new()
add_child(_tween)
_tween.connect("tween_all_completed", self, "_target_reached")
escoria.object_manager.register_object(
ESCObject.new(
escoria.object_manager.CAMERA,
self
),
null,
true
)
# Update the position if the followed target is moving
@@ -37,6 +29,24 @@ func _process(_delta):
self.global_position = _follow_target.global_position
# Register this camera with the object manager. We do it out here so we can
# work with the camera before it's made active as part of the current scene
# tree.
#
# #### Parameters
#
# - room: The room with which to register the camera.
func register(room = null):
escoria.object_manager.register_object(
ESCObject.new(
escoria.object_manager.CAMERA,
self
),
room,
true
)
# Sets camera limits so it doesn't go out of the scene
#
# #### Parameters