gd,refacto: added state chart addon and namespace cleanup

This commit is contained in:
2025-06-05 14:47:51 +02:00
parent 8818e77d23
commit 5c36765a36
239 changed files with 10430 additions and 115 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bgswg1pgd01d1"
path="res://.godot/imported/full.png-a85a82780a54dfe88e1678c76076d884.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://godot_state_charts_examples/platformer/ninja_frog/full.png"
dest_files=["res://.godot/imported/full.png-a85a82780a54dfe88e1678c76076d884.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1

View File

@ -0,0 +1,80 @@
extends CharacterBody2D
## Emitted when this node is clicked with a mouse
signal clicked(node:Node2D)
const SPEED = 300.0
const JUMP_VELOCITY = -400.0
# Get the gravity from the project settings to be synced with RigidBody nodes.
var _gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
@onready var _sprite: Sprite2D = $Sprite
@onready var _state_chart: StateChart = $StateChart
@onready var _animation_tree: AnimationTree = $AnimationTree
@onready var _animation_state_machine: AnimationNodeStateMachinePlayback = _animation_tree.get("parameters/playback")
## Flag indicating if the character was on the floor in the last frame.
var _was_on_floor:bool = false
# In all states, move and slide and handle left/right movement and gravity.
func _physics_process(delta):
# handle left/right movement
var direction = Input.get_axis("ui_left", "ui_right")
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
# flip the sprite. we do this before moving, so it flips
# even if we stand at a wall
if signf(velocity.x) != 0:
_sprite.flip_h = velocity.x < 0
# gravity handled in Grounded and Airborne states
move_and_slide()
# if we are on the floor right now
if is_on_floor():
velocity.y = 0
# if we just touched the floor, notify the state chart
if not _was_on_floor:
_was_on_floor = true
_state_chart.send_event("grounded")
else:
velocity.y += _gravity * delta
# if we just left the floor, notify the state chart
if _was_on_floor:
_was_on_floor = false
_state_chart.send_event("airborne")
# let the state machine know if we are moving or not
if velocity.length_squared() <= 0.005:
_animation_state_machine.travel("Idle")
else:
_animation_state_machine.travel("Move")
# set the velocity to the animation tree, so it can blend between animations
_animation_tree["parameters/Move/blend_position"] = signf(velocity.y)
## Called in states that allow jumping, we process jumps only in these.
func _on_jump_enabled_state_physics_processing(_delta):
if Input.is_action_just_pressed("ui_accept"):
velocity.y = JUMP_VELOCITY
_state_chart.send_event("jump")
## Called when the jump transition is taken in the double-jump
## state. Only used to play the double jump animation.
func _on_double_jump_jump():
_animation_state_machine.travel("DoubleJump")
func _on_input_event(_viewport:Node, event:InputEvent, _shape_idx:int):
# if the left mouse button is up emit the clicked signal
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed() == false:
clicked.emit(self)

View File

@ -0,0 +1 @@
uid://qid37o42he05

View File

@ -0,0 +1,275 @@
[gd_scene load_steps=28 format=3 uid="uid://v5vg88it87oj"]
[ext_resource type="Script" path="res://godot_state_charts_examples/platformer/ninja_frog/ninja_frog.gd" id="1_xi1lh"]
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="3_qw75p"]
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="4_g6c55"]
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="6_vmkuk"]
[ext_resource type="Texture2D" uid="uid://bgswg1pgd01d1" path="res://godot_state_charts_examples/platformer/ninja_frog/full.png" id="7_fehuj"]
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="9_wswdv"]
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1ethx"]
radius = 12.0
[sub_resource type="Animation" id="Animation_uq0h4"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 0
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0]
}
[sub_resource type="Animation" id="Animation_10ku2"]
resource_name = "double_jump"
length = 0.4
step = 0.05
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 0.4),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [23, 28]
}
[sub_resource type="Animation" id="Animation_ibg22"]
resource_name = "fall"
length = 0.1
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [29]
}
[sub_resource type="Animation" id="Animation_5rh2e"]
resource_name = "idle"
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [12, 22]
}
[sub_resource type="Animation" id="Animation_jaga7"]
resource_name = "jump"
length = 0.1
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [30]
}
[sub_resource type="Animation" id="Animation_6odvc"]
resource_name = "walk"
loop_mode = 1
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Sprite:frame")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 1),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [0, 11]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_au2ov"]
_data = {
"RESET": SubResource("Animation_uq0h4"),
"double_jump": SubResource("Animation_10ku2"),
"fall": SubResource("Animation_ibg22"),
"idle": SubResource("Animation_5rh2e"),
"jump": SubResource("Animation_jaga7"),
"walk": SubResource("Animation_6odvc")
}
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_k3ia7"]
animation = &"double_jump"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_iie7f"]
animation = &"idle"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_oetyn"]
animation = &"jump"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_gw83y"]
animation = &"walk"
[sub_resource type="AnimationNodeAnimation" id="AnimationNodeAnimation_iq3nb"]
animation = &"fall"
[sub_resource type="AnimationNodeBlendSpace1D" id="AnimationNodeBlendSpace1D_o7w1c"]
blend_point_0/node = SubResource("AnimationNodeAnimation_oetyn")
blend_point_0/pos = -1.0
blend_point_1/node = SubResource("AnimationNodeAnimation_gw83y")
blend_point_1/pos = 0.0
blend_point_2/node = SubResource("AnimationNodeAnimation_iq3nb")
blend_point_2/pos = 1.0
blend_mode = 1
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_i3ow4"]
advance_mode = 2
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_a52qu"]
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_1q7sj"]
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_4cnci"]
[sub_resource type="AnimationNodeStateMachineTransition" id="AnimationNodeStateMachineTransition_ddbej"]
switch_mode = 2
advance_mode = 2
[sub_resource type="AnimationNodeStateMachine" id="AnimationNodeStateMachine_ckafx"]
states/DoubleJump/node = SubResource("AnimationNodeAnimation_k3ia7")
states/DoubleJump/position = Vector2(767.5, 63.4141)
states/End/position = Vector2(962, 49)
states/Idle/node = SubResource("AnimationNodeAnimation_iie7f")
states/Idle/position = Vector2(342.5, 63.625)
states/Move/node = SubResource("AnimationNodeBlendSpace1D_o7w1c")
states/Move/position = Vector2(575.5, 62.7813)
states/Start/position = Vector2(210.5, 73.75)
transitions = ["Start", "Idle", SubResource("AnimationNodeStateMachineTransition_i3ow4"), "Idle", "Move", SubResource("AnimationNodeStateMachineTransition_a52qu"), "Move", "Idle", SubResource("AnimationNodeStateMachineTransition_1q7sj"), "Move", "DoubleJump", SubResource("AnimationNodeStateMachineTransition_4cnci"), "DoubleJump", "Move", SubResource("AnimationNodeStateMachineTransition_ddbej")]
graph_offset = Vector2(84, -7)
[sub_resource type="AnimationNodeStateMachinePlayback" id="AnimationNodeStateMachinePlayback_63x7j"]
[node name="NinjaFrog" type="CharacterBody2D" groups=["player"]]
input_pickable = true
script = ExtResource("1_xi1lh")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
position = Vector2(0, -15)
shape = SubResource("CapsuleShape2D_1ethx")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
libraries = {
"": SubResource("AnimationLibrary_au2ov")
}
[node name="Sprite" type="Sprite2D" parent="."]
texture_filter = 1
texture = ExtResource("7_fehuj")
offset = Vector2(0, -12)
hframes = 31
[node name="AnimationTree" type="AnimationTree" parent="."]
tree_root = SubResource("AnimationNodeStateMachine_ckafx")
anim_player = NodePath("../AnimationPlayer")
active = true
process_callback = 0
parameters/playback = SubResource("AnimationNodeStateMachinePlayback_63x7j")
parameters/Move/blend_position = -0.380028
[node name="StateChart" type="Node" parent="."]
script = ExtResource("3_qw75p")
track_in_editor = true
[node name="Root" type="Node" parent="StateChart"]
editor_description = "This is the root of all movement related states."
script = ExtResource("4_g6c55")
initial_state = NodePath("Grounded")
[node name="Grounded" type="Node" parent="StateChart/Root"]
editor_description = "This state is active when the player is on the ground."
script = ExtResource("6_vmkuk")
[node name="On Jump" type="Node" parent="StateChart/Root/Grounded"]
editor_description = "When jumping become airborne and enable double-jump."
script = ExtResource("9_wswdv")
to = NodePath("../../Airborne/DoubleJumpEnabled")
event = &"jump"
delay_in_seconds = "0.0"
[node name="On Airborne" type="Node" parent="StateChart/Root/Grounded"]
editor_description = "When becoming airborne (e.g. through falling) move to airborne state."
script = ExtResource("9_wswdv")
to = NodePath("../../Airborne")
event = &"airborne"
delay_in_seconds = "0.0"
[node name="Airborne" type="Node" parent="StateChart/Root"]
editor_description = "This is the root state for when the player is in the air. We have sub-states to handle the various input that is allowed when in the air."
script = ExtResource("4_g6c55")
initial_state = NodePath("CoyoteJumpEnabled")
[node name="On Grounded" type="Node" parent="StateChart/Root/Airborne"]
script = ExtResource("9_wswdv")
to = NodePath("../../Grounded")
event = &"grounded"
delay_in_seconds = "0.0"
[node name="CoyoteJumpEnabled" type="Node" parent="StateChart/Root/Airborne"]
editor_description = "While in this state, the player can jump for a short time. The state is activated by default when the player becomes airborne from falling. Allowing a jump for a short time makes the controls feel nicer. The \"On Expiration\" transition will leave this state after the grace period."
script = ExtResource("6_vmkuk")
[node name="On Jump" type="Node" parent="StateChart/Root/Airborne/CoyoteJumpEnabled"]
editor_description = "On jump handle this as if the player originally jumped."
script = ExtResource("9_wswdv")
to = NodePath("../../DoubleJumpEnabled")
event = &"jump"
delay_in_seconds = "0.0"
[node name="On Expiration" type="Node" parent="StateChart/Root/Airborne/CoyoteJumpEnabled"]
editor_description = "After 0.2 seconds automatically move to falling state where no more jump is possible."
script = ExtResource("9_wswdv")
to = NodePath("../../CannotJump")
delay_in_seconds = "0.2"
[node name="DoubleJumpEnabled" type="Node" parent="StateChart/Root/Airborne"]
editor_description = "This state is active while the player is in the air and has jumped one time already. While the state is active, a second jump is allowed."
script = ExtResource("6_vmkuk")
[node name="On Jump" type="Node" parent="StateChart/Root/Airborne/DoubleJumpEnabled"]
editor_description = "When jumping in double jump state, move to a state where no more jumps are possible.
Triggers the double-jump animation as a side effect."
script = ExtResource("9_wswdv")
to = NodePath("../../CannotJump")
event = &"jump"
delay_in_seconds = "0.0"
[node name="CannotJump" type="Node" parent="StateChart/Root/Airborne"]
editor_description = "This state is active when the player is airborne but can no longer jump either because the coyote-jump grace period has expired or the player has already used the double-jump."
script = ExtResource("6_vmkuk")
[connection signal="input_event" from="." to="." method="_on_input_event"]
[connection signal="state_physics_processing" from="StateChart/Root/Grounded" to="." method="_on_jump_enabled_state_physics_processing"]
[connection signal="state_physics_processing" from="StateChart/Root/Airborne/CoyoteJumpEnabled" to="." method="_on_jump_enabled_state_physics_processing"]
[connection signal="state_physics_processing" from="StateChart/Root/Airborne/DoubleJumpEnabled" to="." method="_on_jump_enabled_state_physics_processing"]
[connection signal="taken" from="StateChart/Root/Airborne/DoubleJumpEnabled/On Jump" to="." method="_on_double_jump_jump"]