gd,refacto: added state chart addon and namespace cleanup
This commit is contained in:
BIN
godot_state_charts_examples/platformer/ninja_frog/full.png
Normal file
BIN
godot_state_charts_examples/platformer/ninja_frog/full.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
@ -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
|
@ -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)
|
||||
|
@ -0,0 +1 @@
|
||||
uid://qid37o42he05
|
@ -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"]
|
Reference in New Issue
Block a user