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

View File

@ -0,0 +1,108 @@
[gd_scene load_steps=7 format=3 uid="uid://i4v5fyt2ix01"]
[ext_resource type="PackedScene" uid="uid://nji5r3vfeuwg" path="res://godot_state_charts_examples/random_transitions/wandering_frog/wandering_frog.tscn" id="1_r2x6m"]
[ext_resource type="PackedScene" uid="uid://bcwkugn6v3oy7" path="res://addons/godot_state_charts/utilities/state_chart_debugger.tscn" id="2_n8tkm"]
[sub_resource type="Shader" id="Shader_8j6vc"]
code = "shader_type canvas_item;
void fragment() {
COLOR.rgb *= (1.0-0.3*(1.0-UV.y));
}
void vertex() {
VERTEX.x -= UV.y * (0.5 - UV.x) * 100.0;
}
"
[sub_resource type="ShaderMaterial" id="ShaderMaterial_8axp2"]
shader = SubResource("Shader_8j6vc")
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fkyfr"]
size = Vector2(36, 418)
[sub_resource type="RectangleShape2D" id="RectangleShape2D_e3j0h"]
size = Vector2(405, 35)
[node name="Random Transitions" type="Node2D"]
[node name="Ground" type="ColorRect" parent="."]
material = SubResource("ShaderMaterial_8axp2")
offset_left = 39.0
offset_top = 68.0
offset_right = 319.0
offset_bottom = 478.0
color = Color(0.0980392, 0.560784, 0.152941, 1)
[node name="ColliderLeft" type="StaticBody2D" parent="."]
position = Vector2(0, 40)
collision_layer = 2
[node name="CollisionShape2D" type="CollisionShape2D" parent="ColliderLeft"]
position = Vector2(35, 199)
shape = SubResource("RectangleShape2D_fkyfr")
[node name="ColliderRight" type="StaticBody2D" parent="."]
position = Vector2(329, 45)
collision_layer = 2
collision_mask = 2
[node name="CollisionShape2D" type="CollisionShape2D" parent="ColliderRight"]
position = Vector2(-9, 196)
shape = SubResource("RectangleShape2D_fkyfr")
[node name="ColliderTop" type="StaticBody2D" parent="."]
position = Vector2(375, 45)
collision_layer = 2
collision_mask = 2
[node name="CollisionShape2D" type="CollisionShape2D" parent="ColliderTop"]
position = Vector2(-176, 12)
shape = SubResource("RectangleShape2D_e3j0h")
[node name="ColliderBottom" type="StaticBody2D" parent="."]
position = Vector2(375, 428)
collision_layer = 2
collision_mask = 2
[node name="CollisionShape2D" type="CollisionShape2D" parent="ColliderBottom"]
position = Vector2(-188, -27)
shape = SubResource("RectangleShape2D_e3j0h")
[node name="WanderingFrog" parent="." instance=ExtResource("1_r2x6m")]
modulate = Color(0.454902, 0.458824, 1, 1)
position = Vector2(106, 158)
[node name="WanderingFrog2" parent="." instance=ExtResource("1_r2x6m")]
position = Vector2(224, 208)
[node name="WanderingFrog3" parent="." instance=ExtResource("1_r2x6m")]
position = Vector2(149, 275)
[node name="WanderingFrog4" parent="." instance=ExtResource("1_r2x6m")]
position = Vector2(297, 340)
[node name="WanderingFrog5" parent="." instance=ExtResource("1_r2x6m")]
position = Vector2(79, 359)
[node name="WanderingFrog6" parent="." instance=ExtResource("1_r2x6m")]
position = Vector2(225, 126)
[node name="StateChartDebugger" parent="." instance=ExtResource("2_n8tkm")]
offset_left = 344.0
offset_top = 33.0
offset_right = 636.0
offset_bottom = 438.0
initial_node_to_watch = NodePath("../WanderingFrog")
[node name="Label" type="RichTextLabel" parent="."]
offset_left = 10.0
offset_top = 375.0
offset_right = 334.0
offset_bottom = 459.0
mouse_filter = 2
bbcode_enabled = true
text = "[font_size=10]
The frogs random movement is controlled by the state chart. Each frog choses to wander or be idle for a random amount of seconds. Even though all frog instances use the same state chart they behave differently because they use random expressions to control which state they enter and for how long they stay in there. The debugger shows the state chart of the blue-tinted frog.
[/font_size]"
fit_content = true

View File

@ -0,0 +1,49 @@
extends CharacterBody2D
const SPEED:float = 50.0
@onready var _sprite: Sprite2D = $Sprite
@onready var _animation_player:AnimationPlayer = $AnimationPlayer
var _direction:Vector2
# When we enter walk state ...
func _on_walk_state_entered():
# pick a random direction to walk in (360 degrees)
_direction = Vector2(randf() * 2 - 1, randf() * 2 - 1).normalized()
# and play the walk animation
_animation_player.play("walk")
# flip the sprite. since we keep this direction for as long as
# we are in the walk state, we don't need to do this per frame.
_sprite.flip_h = _direction.x < 0
# While we are in walk state...
func _on_walk_state_physics_processing(_delta):
# set a new velocity
velocity = _direction * SPEED
# and move into the given direction
move_and_slide()
# and update scale
rescale()
# When we enter idle state ...
func _on_idle_state_entered():
# clear the direction
_direction = Vector2.ZERO
# and play the idle animation
_animation_player.play("idle")
# also rescale here in case we entered idle state first
rescale()
func rescale():
# scale the frog depending on its y position to achieve some pseudo-3d effect
# this is hard-coded for resolution of this project which has 480 vertical pixels
# so we assume 240 to be 100% size, 0 would be 50% size and 480 would be 150% size.
var scale_factor = 1.0 + ((global_position.y - 240) / 480)
scale = Vector2(scale_factor, scale_factor)

View File

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

View File

@ -0,0 +1,211 @@
[gd_scene load_steps=19 format=3 uid="uid://nji5r3vfeuwg"]
[ext_resource type="Script" path="res://godot_state_charts_examples/random_transitions/wandering_frog/wandering_frog.gd" id="1_tfcjx"]
[ext_resource type="Texture2D" uid="uid://bgswg1pgd01d1" path="res://godot_state_charts_examples/platformer/ninja_frog/full.png" id="2_hm4wf"]
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="3_2vqqk"]
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="4_44md5"]
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="5_j65h7"]
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="6_s6am2"]
[ext_resource type="Script" path="res://addons/godot_state_charts/expression_guard.gd" id="7_f5w5i"]
[sub_resource type="Shader" id="Shader_pnpgx"]
code = "shader_type canvas_item;
void fragment() {
COLOR.rgb = vec3(0);
COLOR.a = 0.5 * 1.0-smoothstep(0.0, 1.0, distance(UV, vec2(0.5)));
}
"
[sub_resource type="ShaderMaterial" id="ShaderMaterial_fnfpn"]
shader = SubResource("Shader_pnpgx")
[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="Resource" id="Resource_27kjk"]
script = ExtResource("7_f5w5i")
expression = "randf() < 0.5"
[node name="WanderingFrog" type="CharacterBody2D"]
collision_mask = 2
input_pickable = true
script = ExtResource("1_tfcjx")
[node name="Shadow" type="ColorRect" parent="."]
material = SubResource("ShaderMaterial_fnfpn")
offset_left = -19.0
offset_top = -6.0
offset_right = 21.0
offset_bottom = 12.0
[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("2_hm4wf")
offset = Vector2(0, -12)
hframes = 31
[node name="StateChart" type="Node" parent="."]
script = ExtResource("3_2vqqk")
track_in_editor = true
[node name="Wander" type="Node" parent="StateChart"]
editor_description = "This controls the wandering."
script = ExtResource("4_44md5")
initial_state = NodePath("Decide Next")
[node name="Decide Next" type="Node" parent="StateChart/Wander"]
editor_description = "In this state the frog randomly decides what to do next. The \"To Idle\" transition has a guard which will pick it with a chance of 50%. If it is not picked, then the \"To Walk\" transition is picked. "
script = ExtResource("5_j65h7")
[node name="To Idle" type="Node" parent="StateChart/Wander/Decide Next"]
script = ExtResource("6_s6am2")
to = NodePath("../../Idle")
guard = SubResource("Resource_27kjk")
delay_in_seconds = "0.0"
[node name="To Walk" type="Node" parent="StateChart/Wander/Decide Next"]
script = ExtResource("6_s6am2")
to = NodePath("../../Walk")
delay_in_seconds = "0.0"
[node name="Idle" type="Node" parent="StateChart/Wander"]
editor_description = "In this state the frog stands idly around for a random time."
script = ExtResource("5_j65h7")
[node name="To Decide Next" type="Node" parent="StateChart/Wander/Idle"]
editor_description = "This will bring the frog back into the \"Decide Next\" state after a random amount of time."
script = ExtResource("6_s6am2")
to = NodePath("../../Decide Next")
delay_in_seconds = "randf_range(1.5, 3)"
[node name="Walk" type="Node" parent="StateChart/Wander"]
editor_description = "In this state the frog walks into a random direction for a random amount of time."
script = ExtResource("5_j65h7")
[node name="To Decide Next" type="Node" parent="StateChart/Wander/Walk"]
editor_description = "This will bring the frog back into the \"Decide Next\" state after a random amount of time."
script = ExtResource("6_s6am2")
to = NodePath("../../Idle")
delay_in_seconds = "randf_range(3, 7)"
[connection signal="state_entered" from="StateChart/Wander/Idle" to="." method="_on_idle_state_entered"]
[connection signal="state_entered" from="StateChart/Wander/Walk" to="." method="_on_walk_state_entered"]
[connection signal="state_physics_processing" from="StateChart/Wander/Walk" to="." method="_on_walk_state_physics_processing"]