Stable interface for both Animation player and Animated Sprite (#363)
Co-authored-by: Dennis Ploeger <develop@dieploegers.de>
This commit is contained in:
@@ -107,17 +107,16 @@ func _process(delta: float) -> void:
|
||||
last_deg = escoria.utils.get_deg_from_rad(angle)
|
||||
last_dir = _get_dir_deg(last_deg, parent.animations)
|
||||
|
||||
var current_animation = ""
|
||||
if parent.animation_sprite != null:
|
||||
current_animation = parent.animation_sprite.animation
|
||||
var animation_player: ESCAnimationPlayer = \
|
||||
parent.get_animation_player()
|
||||
|
||||
var current_animation = animation_player.get_animation()
|
||||
|
||||
var animation_to_play = \
|
||||
parent.animations.directions[last_dir].animation
|
||||
if current_animation != animation_to_play:
|
||||
if parent.animation_sprite.frames.has_animation(
|
||||
animation_to_play
|
||||
):
|
||||
parent.animation_sprite.play(animation_to_play)
|
||||
if animation_player.has_animation(animation_to_play):
|
||||
animation_player.play(animation_to_play)
|
||||
else:
|
||||
current_animation = animation_to_play
|
||||
escoria.logger.report_warnings(
|
||||
@@ -241,19 +240,19 @@ func walk_stop(pos: Vector2) -> void:
|
||||
walk_context.target_object.interactive:
|
||||
var orientation = walk_context.target_object.node.interaction_direction
|
||||
last_dir = orientation
|
||||
parent.animation_sprite.play(
|
||||
parent.get_animation_player().play(
|
||||
parent.animations.idles[orientation].animation
|
||||
)
|
||||
pose_scale = -1 if parent.animations.idles[orientation].mirrored else 1
|
||||
else:
|
||||
parent.animation_sprite.play(
|
||||
parent.get_animation_player().play(
|
||||
parent.animations.idles[last_dir].animation
|
||||
)
|
||||
pose_scale = -1 if parent.animations.idles[last_dir].mirrored else 1
|
||||
|
||||
update_terrain()
|
||||
|
||||
yield(parent.animation_sprite, "animation_finished")
|
||||
yield(parent.get_animation_player(), "animation_finished")
|
||||
if walk_context.target_object:
|
||||
escoria.logger.debug(
|
||||
"%s arrived at %s" % [
|
||||
@@ -399,9 +398,9 @@ func set_angle(deg: int, immediate = true) -> void:
|
||||
|
||||
# The character may have a state animation from before, which would be
|
||||
# resumed, so we immediately force the correct idle animation
|
||||
if parent.animation_sprite.animation != \
|
||||
if parent.get_animation_player().get_animation() != \
|
||||
parent.animations.idles[last_dir].animation:
|
||||
parent.animation_sprite.play(
|
||||
parent.get_animation_player().play(
|
||||
parent.animations.idles[last_dir].animation
|
||||
)
|
||||
pose_scale = -1 if parent.animations.idles[last_dir].mirrored else 1
|
||||
@@ -420,10 +419,10 @@ func set_angle(deg: int, immediate = true) -> void:
|
||||
if dir < 0:
|
||||
dir = parent.animations.dir_angles.size() - 1
|
||||
|
||||
parent.animation_sprite.play(
|
||||
parent.get_animation_player().play(
|
||||
parent.animations.idles[dir].animation
|
||||
)
|
||||
yield(parent.animation_sprite, "animation_finished")
|
||||
yield(parent.get_animation_player(), "animation_finished")
|
||||
pose_scale = -1 if parent.animations.idles[dir].mirrored else 1
|
||||
|
||||
update_terrain()
|
||||
|
||||
@@ -38,7 +38,8 @@ func run(command_params: Array) -> int:
|
||||
var obj = escoria.object_manager.objects[command_params[0]]
|
||||
var anim_id = command_params[1]
|
||||
var reverse = command_params[2]
|
||||
var animator = (obj.node as ESCItem).get_animation_player()
|
||||
var animator: ESCAnimationPlayer = \
|
||||
(obj.node as ESCItem).get_animation_player()
|
||||
if reverse:
|
||||
animator.play_backwards(anim_id)
|
||||
else:
|
||||
|
||||
@@ -38,7 +38,8 @@ func run(command_params: Array) -> int:
|
||||
var obj = escoria.object_manager.objects[command_params[0]]
|
||||
var anim_id = command_params[1]
|
||||
var reverse = command_params[2]
|
||||
var animator = (obj.node as ESCItem).get_animation_player()
|
||||
var animator: ESCAnimationPlayer = \
|
||||
(obj.node as ESCItem).get_animation_player()
|
||||
if reverse:
|
||||
animator.play_backwards(anim_id)
|
||||
else:
|
||||
|
||||
@@ -38,28 +38,16 @@ func set_state(p_state: String, immediate: bool = false):
|
||||
state = p_state
|
||||
|
||||
if node.has_method("get_animation_player"):
|
||||
var animation_node = node.get_animation_player()
|
||||
var animation_node: ESCAnimationPlayer = node.get_animation_player()
|
||||
|
||||
if animation_node:
|
||||
animation_node.stop()
|
||||
var actual_animator
|
||||
if animation_node is AnimationPlayer:
|
||||
if animation_node.has_animation(p_state):
|
||||
if immediate:
|
||||
animation_node.current_animation = p_state
|
||||
animation_node.seek(
|
||||
animation_node.get_animation(p_state).length
|
||||
)
|
||||
else:
|
||||
animation_node.play(p_state)
|
||||
elif animation_node is AnimatedSprite:
|
||||
if animation_node.frames.has_animation(p_state):
|
||||
if immediate:
|
||||
animation_node.animation = p_state
|
||||
animation_node.frame = \
|
||||
animation_node.frames.get_frame_count(p_state)
|
||||
else:
|
||||
animation_node.play(p_state)
|
||||
if animation_node.has_animation(p_state):
|
||||
if immediate:
|
||||
animation_node.seek_end(p_state)
|
||||
else:
|
||||
animation_node.play(p_state)
|
||||
|
||||
|
||||
# Set the active value, thus hiding or showing the object
|
||||
|
||||
139
addons/escoria-core/game/core-scripts/esc_animation_player.gd
Normal file
139
addons/escoria-core/game/core-scripts/esc_animation_player.gd
Normal file
@@ -0,0 +1,139 @@
|
||||
# An abstraction class to expose the same animation methods for noth
|
||||
# AnimatedSprite and AnimationPlayer
|
||||
extends Node
|
||||
class_name ESCAnimationPlayer
|
||||
|
||||
|
||||
signal animation_finished(name)
|
||||
|
||||
|
||||
# The actual player node
|
||||
var _player_node: Node
|
||||
|
||||
# A AnimationPlayer typed reference to the player node (for intellisense)
|
||||
var _animation_player: AnimationPlayer
|
||||
|
||||
# A AnimationPlayer typed reference to the player node (for intellisense)
|
||||
var _animated_sprite: AnimatedSprite
|
||||
|
||||
# Wether the player node is of type AnimationPlayer (just for convenience)
|
||||
var _is_animation_player: bool = false
|
||||
|
||||
|
||||
# Create a new animation player
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - node: The actual player node
|
||||
func _init(node: Node):
|
||||
_player_node = node
|
||||
if node is AnimationPlayer:
|
||||
_is_animation_player = true
|
||||
_animation_player = node
|
||||
else:
|
||||
_animated_sprite = node
|
||||
|
||||
|
||||
# Return the currently playing animation
|
||||
# **Returns** the currently playing animation name
|
||||
func get_animation() -> String:
|
||||
if _is_animation_player:
|
||||
return _animation_player.current_animation
|
||||
else:
|
||||
return _animated_sprite.animation
|
||||
|
||||
|
||||
# Returns a list of all animation names
|
||||
# **Returns** A list of all animation names
|
||||
func get_animations() -> PoolStringArray:
|
||||
if _is_animation_player:
|
||||
return _animation_player.get_animation_list()
|
||||
else:
|
||||
return _animated_sprite.frames.get_animation_names()
|
||||
|
||||
|
||||
# Wether the animation is playing
|
||||
# **Returns: Wether the animation is playing**
|
||||
func is_playing() -> bool:
|
||||
return _player_node.is_playing()
|
||||
|
||||
|
||||
# Stop the animation
|
||||
func stop():
|
||||
_player_node.stop()
|
||||
|
||||
|
||||
# Play the animation
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - name: The animation name to play
|
||||
# - backwards: Play backwards
|
||||
func play(name: String, backwards: bool = false):
|
||||
if _player_node.is_connected(
|
||||
"animation_finished",
|
||||
self,
|
||||
"_on_animation_finished"
|
||||
):
|
||||
_player_node.disconnect(
|
||||
"animation_finished",
|
||||
self,
|
||||
"_on_animation_finished"
|
||||
)
|
||||
_player_node.connect(
|
||||
"animation_finished",
|
||||
self,
|
||||
"_on_animation_finished",
|
||||
[name]
|
||||
)
|
||||
if backwards and _is_animation_player:
|
||||
_animation_player.play_backwards(name)
|
||||
elif backwards:
|
||||
_animated_sprite.play(name, true)
|
||||
else:
|
||||
_player_node.play(name)
|
||||
|
||||
|
||||
# Play the given animation backwards
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - name: Animation to play
|
||||
func play_backwards(name: String):
|
||||
self.play(name, true)
|
||||
|
||||
|
||||
# Check if the given animation exists
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - name: Name of the animation to check
|
||||
# **Returns** Wether the animation player has the animation
|
||||
func has_animation(name: String) -> bool:
|
||||
if _is_animation_player:
|
||||
return _animation_player.has_animation(name)
|
||||
else:
|
||||
return _animated_sprite.frames.has_animation(name)
|
||||
|
||||
|
||||
# Play an animation and directly skip to the end
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - name: Name of the animation to play
|
||||
func seek_end(name: String):
|
||||
if _is_animation_player:
|
||||
_animation_player.current_animation = name
|
||||
_animation_player.seek(_animation_player.get_animation(name).length)
|
||||
else:
|
||||
_animated_sprite.animation = name
|
||||
_animated_sprite.frame = _animated_sprite.frames.get_frame_count(name)
|
||||
|
||||
|
||||
# Transport the animation_finished signal
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - name: Name of the animation played
|
||||
func _on_animation_finished(name: String):
|
||||
emit_signal("animation_finished", name)
|
||||
@@ -120,15 +120,13 @@ export(int) var speed: int = 300
|
||||
# Speed damp of this item if movable
|
||||
export(float) var v_speed_damp: float = 1.0
|
||||
|
||||
# The node used to play animations
|
||||
export(NodePath) var animation_player_node: NodePath = "" \
|
||||
setget _set_animation_player_node
|
||||
|
||||
# ESCAnimationsResource (for walking, idling...)
|
||||
var animations: ESCAnimationResource
|
||||
|
||||
# The movable subnode
|
||||
var _movable: ESCMovable = null
|
||||
|
||||
# Reference to the animation node (null if none was found)
|
||||
var animation_sprite = null
|
||||
|
||||
# Reference to the current terrain
|
||||
var terrain: ESCTerrain
|
||||
|
||||
@@ -140,6 +138,13 @@ var collision: Node
|
||||
var inventory_item: ESCInventoryItem = null setget ,_get_inventory_item
|
||||
|
||||
|
||||
# The movable subnode
|
||||
var _movable: ESCMovable = null
|
||||
|
||||
# The identified animation player
|
||||
var _animation_player: ESCAnimationPlayer = null
|
||||
|
||||
|
||||
# Add the movable node, connect signals, detect child nodes
|
||||
# and register this item
|
||||
func _ready():
|
||||
@@ -194,8 +199,20 @@ func _ready():
|
||||
|
||||
|
||||
# Return the animation player node
|
||||
func get_animation_player():
|
||||
return animation_sprite
|
||||
func get_animation_player() -> Node:
|
||||
if _animation_player == null:
|
||||
var player_node_path = animation_player_node
|
||||
if player_node_path == "":
|
||||
for child in self.get_children():
|
||||
if child is AnimatedSprite or \
|
||||
child is AnimationPlayer:
|
||||
player_node_path = child.get_path()
|
||||
if not has_node(player_node_path):
|
||||
escoria.logger.error(
|
||||
"Can not find node at path %s" % player_node_path
|
||||
)
|
||||
_animation_player = ESCAnimationPlayer.new(get_node(player_node_path))
|
||||
return _animation_player
|
||||
|
||||
|
||||
# Return the position the player needs to walk to to interact with this
|
||||
@@ -327,29 +344,20 @@ func set_angle(deg: int, immediate = true):
|
||||
|
||||
# Play the talking animation
|
||||
func start_talking():
|
||||
if animation_sprite.is_playing():
|
||||
animation_sprite.stop()
|
||||
animation_sprite.play(animations.speaks[_movable.last_dir].animation)
|
||||
if get_animation_player().is_playing():
|
||||
get_animation_player().stop()
|
||||
get_animation_player().play(animations.speaks[_movable.last_dir].animation)
|
||||
|
||||
|
||||
# Stop playing the talking animation
|
||||
func stop_talking():
|
||||
if animation_sprite.is_playing():
|
||||
animation_sprite.stop()
|
||||
animation_sprite.play(animations.idles[_movable.last_dir].animation)
|
||||
if get_animation_player().is_playing():
|
||||
get_animation_player().stop()
|
||||
get_animation_player().play(animations.idles[_movable.last_dir].animation)
|
||||
|
||||
|
||||
# Detect the child nodes and set respective references
|
||||
func _detect_children() -> void:
|
||||
# Detect animation player
|
||||
for n in get_children():
|
||||
if n is AnimatedSprite:
|
||||
animation_sprite = n
|
||||
continue
|
||||
if n is AnimationPlayer:
|
||||
animation_sprite = n
|
||||
continue
|
||||
|
||||
# Initialize collision variable.
|
||||
for c in get_children():
|
||||
if c is CollisionShape2D or c is CollisionPolygon2D:
|
||||
@@ -380,3 +388,23 @@ func _get_property_list():
|
||||
"hint_string": "ESCAnimationResource"
|
||||
})
|
||||
return properties
|
||||
|
||||
|
||||
# Set the node path to the animation player
|
||||
#
|
||||
# #### Parameters
|
||||
#
|
||||
# - node_path: Path to the player node
|
||||
func _set_animation_player_node(node_path: NodePath):
|
||||
if node_path == "":
|
||||
animation_player_node = node_path
|
||||
return
|
||||
|
||||
assert(has_node(node_path), "Node with path %s not found" % node_path)
|
||||
assert(
|
||||
get_node(node_path) is AnimatedSprite or \
|
||||
get_node(node_path) is AnimationPlayer,
|
||||
"Selected node has to be an AnimatedSprite or AnimationPlayer node"
|
||||
)
|
||||
|
||||
animation_player_node = node_path
|
||||
|
||||
@@ -107,7 +107,7 @@ var result_angles = []
|
||||
func _ready():
|
||||
# Find player animations
|
||||
$player_animations.add_item("")
|
||||
for anim_name in $player.get_animation_player.get_sprite_frames().get_animation_names():
|
||||
for anim_name in $player.get_animation_player().get_animations():
|
||||
$player_animations.add_item(anim_name)
|
||||
|
||||
# Set initial angles
|
||||
|
||||
Reference in New Issue
Block a user