Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Characters animations using AnimationPlayer #7

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 108 additions & 12 deletions addons/Popochiu/Engine/Objects/Character/PopochiuCharacter.gd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ extends 'res://addons/Popochiu/Engine/Objects/Clickable/PopochiuClickable.gd'
# TODO: Use a state machine

enum FlipsWhen { NONE, MOVING_RIGHT, MOVING_LEFT }
enum LOOKING {UP, UP_RIGHT, RIGHT, RIGHT_DOWN, DOWN, DOWN_LEFT, LEFT, UP_LEFT}
enum LOOKING {UP, UP_RIGHT, RIGHT, DOWN_RIGHT, DOWN, DOWN_LEFT, LEFT, UP_LEFT}

signal started_walk_to(character, start, end)
signal stoped_walk
Expand Down Expand Up @@ -57,8 +57,10 @@ func walk(target_pos: Vector2, is_in_queue := true) -> void:
if is_in_queue: yield()

is_moving = true
_looking_dir = LOOKING.LEFT if target_pos.x < position.x else LOOKING.RIGHT

# Make the char face in the correct direction
face_direction(target_pos)
# The ROOM will take care of moving the character
# and face her in the correct direction from here
if has_node('Sprite'):
match flips_when:
FlipsWhen.MOVING_LEFT:
Expand All @@ -81,9 +83,7 @@ func walk(target_pos: Vector2, is_in_queue := true) -> void:

return

play_walk(target_pos)

# Trigger the signal for the room to start moving the character
# Trigger the signal for the room to start moving the character
emit_signal('started_walk_to', self, position, target_pos)

yield(C, 'character_move_ended')
Expand Down Expand Up @@ -114,13 +114,29 @@ func face_up_right(is_in_queue := true) -> void:
_looking_dir = LOOKING.UP_RIGHT
yield(idle(false), 'completed')

func face_up_left(is_in_queue := true) -> void:
if is_in_queue: yield()

_looking_dir = LOOKING.UP_LEFT
yield(idle(false), 'completed')

func face_down(is_in_queue := true) -> void:
if is_in_queue: yield()

_looking_dir = LOOKING.DOWN
yield(idle(false), 'completed')

func face_down_left(is_in_queue := true) -> void:
if is_in_queue: yield()

_looking_dir = LOOKING.DOWN_LEFT
yield(idle(false), 'completed')

func face_down_right(is_in_queue := true) -> void:
if is_in_queue: yield()

_looking_dir = LOOKING.DOWN_RIGHT
yield(idle(false), 'completed')

func face_left(is_in_queue := true) -> void:
if is_in_queue: yield()
Expand Down Expand Up @@ -205,7 +221,7 @@ func get_dialog_pos() -> float:

func set_voices(value: Array) -> void:
voices = value

for idx in value.size():
if not value[idx]:
voices[idx] = {
Expand Down Expand Up @@ -240,19 +256,99 @@ func _get_vo_cue(emotion := '') -> String:
return cue_name
return ''

func face_direction(destination: Vector2):
# Get the vector from the origin to the destination.
var vectX = destination.x - position.x
var vectY = destination.y - position.y
# Determine the angle of the movement vector.
var rad = atan2(vectY, vectX)
var angle = rad2deg(rad)
# Tolerance in degrees, to avoid U D L R are only
# achieved on precise angles such as 0 90 180 deg.
var t = 20
# Determine the direction the character is facing.
# Remember: Y coordinates have opposite sign in Godot.
# this means that negative angles are up movements.
# Set the direction using the _looking property.
# We cannot use the face_* functions because they
# set the state as IDLE.
if angle >= -(0 + t) and angle < (0 + t):
_looking_dir = LOOKING.RIGHT
elif angle >= (0 + t) and angle < (90 - t):
_looking_dir = LOOKING.DOWN_RIGHT
elif angle >= (90 - t) and angle < (90 + t):
_looking_dir = LOOKING.DOWN
elif angle >= (90 + t) and angle < (180 - t):
_looking_dir = LOOKING.DOWN_LEFT
elif angle >= (180 - t) or angle <= -(180 -t ):
_looking_dir = LOOKING.LEFT
elif angle <= -(0 + t) and angle > -(90 - t):
_looking_dir = LOOKING.UP_RIGHT
elif angle <= -(90 - t) and angle > -(90 + t):
_looking_dir = LOOKING.UP
elif angle <= -(90 + t) and angle > -(180 - t):
_looking_dir = LOOKING.UP_LEFT


func _get_valid_oriented_animation(animation_label):
var suffixes = []
# Based on the character facing direction,
# define a set of animation suffixes in
# preference order.
match _looking_dir:
LOOKING.DOWN_LEFT: suffixes = ['_dl', '_l']
LOOKING.UP_LEFT: suffixes = ['_ul', '_l']
LOOKING.LEFT: suffixes = ['_l']
LOOKING.UP_RIGHT: suffixes = ['_ur', '_r']
LOOKING.DOWN_RIGHT: suffixes = ['_dr', '_r']
LOOKING.RIGHT: suffixes = ['_r']
LOOKING.DOWN: suffixes = ['_d']
LOOKING.UP: suffixes = ['_u']
# Add an empty suffix to support the most
# basic animation case.
suffixes = suffixes + ['']
# The list of prefixes is in order of preference
# Eg. walk_dl, walk_l, walk
# Scan the AnimationPlayer and return the first that matches.
for suffix in suffixes:
var animation = "%s%s" % [animation_label, suffix]
if $AnimationPlayer.has_animation(animation):
return animation
# No valid animation is found.
return null


func play_animation(animation_label: String, animation_fallback := 'idle', blocking := false):
if not has_node("AnimationPlayer"):
printerr("Expected AnimationPlayer not fount in character ", script_name)
return

# Search for a valid animation corresponding to animation_label
var animation = _get_valid_oriented_animation(animation_label)
# If is not present, do the same for the the fallback animation.
if animation == null: animation = _get_valid_oriented_animation(animation_fallback)
# In neither are available, exit and throw an error to check for the presence of the animations.
if animation == null: # Again!
printerr("Neither the requested nor the fallback animation could be found for character ", script_name, ". Requested: ", animation_label, " - Fallback: " , animation_fallback)
return
# Play the animation in the best available orientation.
$AnimationPlayer.play(animation)


# ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ VIRTUAL ░░░░
func play_idle() -> void:
pass
play_animation('idle');


func play_walk(target_pos: Vector2) -> void:
pass
# Set the default parameters for play_animation()
var animation_label = 'walk'
var animation_fallback = 'idle'
play_animation(animation_label, animation_fallback);


func play_talk() -> void:
pass
play_animation('talk');


func play_grab() -> void:
pass
play_animation('grab');
7 changes: 6 additions & 1 deletion addons/Popochiu/Engine/Objects/Room/PopochiuRoom.gd
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,11 @@ func _move_along_path(distance):
while _path.size():
var distance_between_points = last_point.distance_to(_path[0])
if distance <= distance_between_points:
# Based on the destination, turn the character
_moving_character.face_direction(_path[0])
# Play the animation on the character
_moving_character.play_walk(_path[0])
# Move the character on the destination
_moving_character.position = last_point.linear_interpolate(
_path[0], distance / distance_between_points
)
Expand All @@ -265,7 +270,7 @@ func _move_along_path(distance):
distance -= distance_between_points
last_point = _path[0]
_path.remove(0)

_moving_character.position = last_point
_clear_navigation_path()

Expand Down
2 changes: 2 additions & 0 deletions popochiu/Characters/Goddiu/CharacterGoddiu.gd
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func on_item_used(item: PopochiuInventoryItem) -> void:

# Use it to play the idle animation for the character
func play_idle() -> void:
.play_idle()
pass


Expand All @@ -40,6 +41,7 @@ func play_walk(target_pos: Vector2) -> void:

# Use it to play the talk animation for the character
func play_talk() -> void:
.play_talk()
pass


Expand Down
104 changes: 102 additions & 2 deletions popochiu/Characters/Goddiu/CharacterGoddiu.tscn
Original file line number Diff line number Diff line change
@@ -1,8 +1,97 @@
[gd_scene load_steps=3 format=2]
[gd_scene load_steps=8 format=2]

[ext_resource path="res://popochiu/Characters/Goddiu/CharacterGoddiu.gd" type="Script" id=1]
[ext_resource path="res://popochiu/Characters/Goddiu/goddiu.png" type="Texture" id=2]

[sub_resource type="Animation" id=1]
resource_name = "idle"
length = 0.5
loop = true
tracks/0/type = "value"
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0 ),
"transitions": PoolRealArray( 1 ),
"update": 1,
"values": [ 0 ]
}

[sub_resource type="Animation" id=5]
resource_name = "talk"
length = 0.5
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.25 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ 4, 5 ]
}

[sub_resource type="Animation" id=2]
resource_name = "walk"
length = 0.3
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.15 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ 7, 6 ]
}

[sub_resource type="Animation" id=4]
resource_name = "walk_d"
length = 0.3
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.15 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ 8, 9 ]
}

[sub_resource type="Animation" id=3]
resource_name = "walk_u"
length = 0.3
loop = true
step = 0.05
tracks/0/type = "value"
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/keys = {
"times": PoolRealArray( 0, 0.15 ),
"transitions": PoolRealArray( 1, 1 ),
"update": 1,
"values": [ 10, 11 ]
}

[node name="CharacterGoddiu" type="Area2D"]
script = ExtResource( 1 )
__meta__ = {
Expand All @@ -14,15 +103,18 @@ clickable = false
cursor = 8
is_player = true
flips_when = 2
walk_speed = 100.0

[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="."]
polygon = PoolVector2Array( -9, -45, -1, -47, 17, -39, 22, -34, 23, -26, 19, -18, 10, -13, -4, -12, -17, -14, -22, -20, -22, -28 )

[node name="BaselineHelper" type="Line2D" parent="."]
visible = false
points = PoolVector2Array( -10000, 0, 10000, 0 )
width = 1.0

[node name="WalkToHelper" type="Position2D" parent="."]
visible = false
__meta__ = {
"_edit_group_": true
}
Expand All @@ -37,7 +129,15 @@ color = Color( 0, 1, 1, 1 )
[node name="Sprite" type="Sprite" parent="."]
position = Vector2( 0, -27 )
texture = ExtResource( 2 )
hframes = 6
hframes = 12

[node name="DialogPos" type="Position2D" parent="."]
visible = false
position = Vector2( -3, -48 )

[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
anims/idle = SubResource( 1 )
anims/talk = SubResource( 5 )
anims/walk = SubResource( 2 )
anims/walk_d = SubResource( 4 )
anims/walk_u = SubResource( 3 )
Binary file modified popochiu/Characters/Goddiu/goddiu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.