gd,refacto: added state chart addon and namespace cleanup
276
godot_state_charts_examples/ant_hill/ant/ant.gd
Normal file
@ -0,0 +1,276 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
signal clicked(node:Node2D)
|
||||
|
||||
@export var marker_scene:PackedScene
|
||||
|
||||
## The navigation agent we use.
|
||||
@onready var navigation_agent:NavigationAgent2D = $NavigationAgent2D
|
||||
|
||||
## The state chart
|
||||
@onready var state_chart:StateChart = $StateChart
|
||||
|
||||
## Set of close food markers
|
||||
var food_markers:Dictionary = {}
|
||||
|
||||
## Set of close nest markers
|
||||
var nest_markers:Dictionary = {}
|
||||
|
||||
## Set of food nearby
|
||||
var food:Dictionary = {}
|
||||
|
||||
## The nest, if nearby
|
||||
var nest:Node2D = null
|
||||
|
||||
## The currently carried food
|
||||
var carried_food:Node = null
|
||||
|
||||
const SEGMENT_LENGTH = 150
|
||||
|
||||
func _ready():
|
||||
# start the state chart
|
||||
state_chart.send_event.call_deferred("initialized")
|
||||
|
||||
|
||||
## Called when we are seeking for food and need a new target.
|
||||
func _on_idle_seeking_food():
|
||||
|
||||
var current_position := get_global_position()
|
||||
|
||||
# if we have food nearby grab it
|
||||
if food.size() > 0:
|
||||
state_chart.send_event("food_detected")
|
||||
return
|
||||
|
||||
var target_position := Vector2()
|
||||
# if we have food markers nearby travel into the general direction of the closest one points
|
||||
if food_markers.size() > 0:
|
||||
var closest_food_marker := _find_closest(food_markers.keys(), current_position)
|
||||
var direction = Vector2.RIGHT.rotated(closest_food_marker.get_rotation())
|
||||
target_position = current_position + (direction * SEGMENT_LENGTH)
|
||||
|
||||
# otherwise or if we couldn't reach the last target position, pick a random
|
||||
# direction
|
||||
if food_markers.size() == 0 or not navigation_agent.is_target_reachable():
|
||||
# otherwise pick a random position in a radius of SEGMENT_LENGTH pixels
|
||||
# first calculate a random angle in radians
|
||||
var random_angle := randf() * 2 * PI
|
||||
# then calculate the x and y components of the vector
|
||||
var random_x := cos(random_angle) * SEGMENT_LENGTH
|
||||
var random_y := sin(random_angle) * SEGMENT_LENGTH
|
||||
|
||||
# add the random vector to the current position
|
||||
target_position = current_position + Vector2(random_x, random_y)
|
||||
|
||||
|
||||
navigation_agent.set_target_position(target_position)
|
||||
state_chart.set_expression_property("target_position", target_position)
|
||||
state_chart.send_event("destination_set")
|
||||
|
||||
|
||||
## Called when we have found food nearby and want to go to it
|
||||
func _on_food_detected():
|
||||
# set the target position to the closest food
|
||||
var closest_food_position = _find_closest(food.keys(), get_global_position()).global_position
|
||||
navigation_agent.set_target_position(closest_food_position)
|
||||
|
||||
|
||||
## Called when we arrived at the food and want to pick it up
|
||||
func _on_food_reached():
|
||||
var closest_food = _find_closest(food.keys(), get_global_position())
|
||||
if not is_instance_valid(closest_food):
|
||||
# some other ant must have picked it up
|
||||
state_chart.send_event("food_vanished")
|
||||
return
|
||||
|
||||
closest_food.get_parent().remove_child(closest_food)
|
||||
carried_food = closest_food
|
||||
# remove it from the food set
|
||||
food.erase(closest_food)
|
||||
# it's collected, so remove it from the food group
|
||||
closest_food.remove_from_group("food")
|
||||
# add it to our ant so it moves with us
|
||||
add_child(closest_food)
|
||||
closest_food.position = Vector2.ZERO
|
||||
closest_food.scale = Vector2(0.5, 0.5)
|
||||
|
||||
# place a marker pointing to the food (0 means point into the current direction)
|
||||
var marker = _place_marker(Marker.MarkerType.FOOD, global_position, 0)
|
||||
food_markers[marker] = true
|
||||
|
||||
# notify the state chart that we picked up food
|
||||
state_chart.send_event("food_picked_up")
|
||||
|
||||
|
||||
|
||||
## Called when we are returning home and need a new target.
|
||||
func _on_idle_returning_home():
|
||||
var current_position := get_global_position()
|
||||
|
||||
# if the nest is nearby, drop off the food
|
||||
if nest != null:
|
||||
state_chart.send_event("nest_detected")
|
||||
return
|
||||
|
||||
var target_position := Vector2()
|
||||
# if we have nest markers nearby travel into the general direction of the closest one points
|
||||
if nest_markers.size() > 0:
|
||||
# refresh them
|
||||
for marker in nest_markers.keys():
|
||||
marker.refresh()
|
||||
|
||||
var closest_nest_marker := _find_closest(nest_markers.keys(), current_position)
|
||||
var direction = Vector2.RIGHT.rotated(closest_nest_marker.get_rotation())
|
||||
target_position = current_position + (direction * SEGMENT_LENGTH)
|
||||
|
||||
# if we have no nest markers or the navigation agent couldn't reach
|
||||
# the position of the last target pick a random direction
|
||||
if nest_markers.size() == 0 or not navigation_agent.is_target_reachable():
|
||||
var random_angle := randf() * 2 * PI
|
||||
# then calculate the x and y components of the vector
|
||||
var random_x := cos(random_angle) * SEGMENT_LENGTH
|
||||
var random_y := sin(random_angle) * SEGMENT_LENGTH
|
||||
|
||||
# add the random vector to the current position
|
||||
target_position = current_position + Vector2(random_x, random_y)
|
||||
|
||||
navigation_agent.set_target_position(target_position)
|
||||
state_chart.set_expression_property("target_position", target_position)
|
||||
state_chart.send_event("destination_set")
|
||||
return
|
||||
|
||||
## Called when we are returning home and detected the nest
|
||||
func _on_nest_detected():
|
||||
# travel to the nest
|
||||
navigation_agent.set_target_position(nest.global_position)
|
||||
state_chart.set_expression_property("target_position", nest.global_position)
|
||||
|
||||
|
||||
## Called when we have arrived at the nest and want to drop off the food
|
||||
func _on_nest_reached():
|
||||
# drop off the food
|
||||
carried_food.get_parent().remove_child(carried_food)
|
||||
carried_food.queue_free()
|
||||
carried_food = null
|
||||
# notify the state chart that we dropped off the food
|
||||
state_chart.send_event("food_dropped")
|
||||
|
||||
|
||||
## Called while travelling to a destination
|
||||
func _on_travelling_state_physics_processing(_delta):
|
||||
# get the next position on the path
|
||||
var path_position = navigation_agent.get_next_path_position()
|
||||
# and move towards it
|
||||
velocity = (path_position - get_global_position()).normalized() * navigation_agent.max_speed
|
||||
look_at(path_position)
|
||||
move_and_slide()
|
||||
|
||||
|
||||
func _on_input_event(_viewport, event, _shape_idx):
|
||||
# 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:
|
||||
# print("clicked")
|
||||
clicked.emit(self)
|
||||
|
||||
|
||||
## Called when the ant is sensing something nearby.
|
||||
func _on_sensor_area_area_entered(area:Area2D):
|
||||
var node = area
|
||||
if area.has_meta("owner"):
|
||||
node = area.get_node(area.get_meta("owner"))
|
||||
|
||||
|
||||
if node.is_in_group("marker"):
|
||||
# it's a marker
|
||||
if node.is_in_group("food"):
|
||||
food_markers[node] = true
|
||||
elif node.is_in_group("nest"):
|
||||
nest_markers[node] = true
|
||||
elif node.is_in_group("food"):
|
||||
# it's food
|
||||
food[node] = true
|
||||
elif node.is_in_group("nest"):
|
||||
# it's the nest
|
||||
nest = node
|
||||
|
||||
state_chart.set_expression_property("nest_markers", nest_markers.size())
|
||||
state_chart.set_expression_property("food_markers", food_markers.size())
|
||||
|
||||
|
||||
|
||||
func _on_sensor_area_area_exited(area:Area2D):
|
||||
var node = area
|
||||
if area.has_meta("owner"):
|
||||
node = area.get_node(area.get_meta("owner"))
|
||||
|
||||
if node.is_in_group("marker"):
|
||||
# it's a marker
|
||||
if node.is_in_group("food"):
|
||||
food_markers.erase(node)
|
||||
elif node.is_in_group("nest"):
|
||||
nest_markers.erase(node)
|
||||
elif node.is_in_group("food"):
|
||||
# it's food
|
||||
food.erase(node)
|
||||
elif node.is_in_group("nest"):
|
||||
# it's the nest
|
||||
nest = null
|
||||
|
||||
state_chart.set_expression_property("nest_markers", nest_markers.size())
|
||||
state_chart.set_expression_property("food_markers", nest_markers.size())
|
||||
|
||||
|
||||
|
||||
|
||||
## Finds the closest position to the given position from the given list of nodes.
|
||||
func _find_closest(targets:Array, from:Vector2) -> Node2D:
|
||||
var shortest_distance := 99999999.00
|
||||
var result = null
|
||||
|
||||
for target in targets:
|
||||
var distance := from.distance_squared_to(target.get_global_position())
|
||||
if distance < shortest_distance:
|
||||
shortest_distance = distance
|
||||
result = target
|
||||
|
||||
return result
|
||||
|
||||
|
||||
## Places a marker of the given type at the given position
|
||||
func _place_marker(type:Marker.MarkerType, target_position:Vector2, offset:float = PI) -> Marker:
|
||||
var marker = marker_scene.instantiate()
|
||||
marker.initialize(type)
|
||||
# add to the tree on our parent
|
||||
get_parent().add_child.call_deferred(marker)
|
||||
# set the position to our current position
|
||||
marker.set_global_position(target_position)
|
||||
# set the marker rotation to look opposite to the direction we are facing
|
||||
marker.set_rotation(get_rotation() + offset)
|
||||
return marker
|
||||
|
||||
|
||||
func _place_nest_marker():
|
||||
# if there are already nest markers around, just refresh them
|
||||
if nest_markers.size() > 0:
|
||||
for marker in nest_markers:
|
||||
marker.refresh()
|
||||
else:
|
||||
# otherwise place a new one
|
||||
_place_marker(Marker.MarkerType.NEST, global_position)
|
||||
|
||||
|
||||
func _place_food_marker():
|
||||
_place_marker(Marker.MarkerType.FOOD, global_position)
|
||||
|
||||
|
||||
func _maintenance(_delta):
|
||||
# remove all markers which are no longer valid
|
||||
for marker in food_markers.keys():
|
||||
if not is_instance_valid(marker):
|
||||
food_markers.erase(marker)
|
||||
|
||||
for marker in nest_markers.keys():
|
||||
if not is_instance_valid(marker):
|
||||
nest_markers.erase(marker)
|
||||
|
||||
|
1
godot_state_charts_examples/ant_hill/ant/ant.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://d4ld8mlrjp04a
|
5
godot_state_charts_examples/ant_hill/ant/ant.gdshader
Normal file
@ -0,0 +1,5 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
void fragment() {
|
||||
COLOR = COLOR + vec4(.3,.3,.1,.0);
|
||||
}
|
@ -0,0 +1 @@
|
||||
uid://bx4vu24rcr0m5
|
686
godot_state_charts_examples/ant_hill/ant/ant.tscn
Normal file
@ -0,0 +1,686 @@
|
||||
[gd_scene load_steps=75 format=3 uid="uid://dy43c80qlfftx"]
|
||||
|
||||
[ext_resource type="Shader" path="res://godot_state_charts_examples/ant_hill/ant/ant.gdshader" id="1_01qat"]
|
||||
[ext_resource type="Texture2D" uid="uid://bqgc7cft671q0" path="res://godot_state_charts_examples/ant_hill/ant/walk.png" id="1_7ajse"]
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/ant_hill/ant/ant.gd" id="1_i761n"]
|
||||
[ext_resource type="PackedScene" uid="uid://dy5xrmjffewnk" path="res://godot_state_charts_examples/ant_hill/marker/marker.tscn" id="2_lqnr1"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="3_lard5"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="4_ejp2e"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="5_21sgy"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="7_qj278"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_bjtx1"]
|
||||
shader = ExtResource("1_01qat")
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_p0h5v"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_mubvl"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_nj3h7"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_fij1g"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_i21td"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_a0fxu"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_bwhdr"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1212, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_hm8dw"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1414, 0, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_lfnfv"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_kljff"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_t8fco"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_blb68"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_2k7ie"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_vpjgq"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ykqrl"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1212, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_yq06r"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1414, 248, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_m8wtm"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ytxlu"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_jiy2o"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_vfiyg"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_sl3a2"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_nmj2f"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_sngog"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1212, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_71qgv"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1414, 496, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_88uru"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_kqc1k"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ar5xr"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xs12g"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_6mpdc"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_lqwgf"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xrg7o"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1212, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_kmp2k"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1414, 744, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_hpmfd"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_3osu6"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_gdwlg"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_hau5u"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_2uawa"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_aj6m3"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_lnduy"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1212, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_bqt77"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1414, 992, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_plrtj"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ggvde"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xavhi"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ev8ji"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_65x5e"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_yi6fp"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_eseb1"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1212, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ux63t"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1414, 1240, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ocabh"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_8sepc"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_4d7on"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_jsu7m"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_vhyb2"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_t2dka"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_e6l64"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1212, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_mdp8v"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1414, 1488, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ywpdo"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(0, 1736, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_1d2bj"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(202, 1736, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_80asc"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(404, 1736, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_m5ngl"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(606, 1736, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_r7ql0"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(808, 1736, 202, 248)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_w0vp4"]
|
||||
atlas = ExtResource("1_7ajse")
|
||||
region = Rect2(1010, 1736, 202, 248)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_kcoy1"]
|
||||
animations = [{
|
||||
"frames": [],
|
||||
"loop": true,
|
||||
"name": &"default",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_p0h5v")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_mubvl")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_nj3h7")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_fij1g")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_i21td")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_a0fxu")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_bwhdr")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_hm8dw")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_lfnfv")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_kljff")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_t8fco")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_blb68")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_2k7ie")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_vpjgq")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ykqrl")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_yq06r")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_m8wtm")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ytxlu")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_jiy2o")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_vfiyg")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_sl3a2")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_nmj2f")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_sngog")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_71qgv")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_88uru")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_kqc1k")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ar5xr")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xs12g")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_6mpdc")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_lqwgf")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xrg7o")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_kmp2k")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_hpmfd")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_3osu6")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_gdwlg")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_hau5u")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_2uawa")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_aj6m3")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_lnduy")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_bqt77")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_plrtj")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ggvde")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_xavhi")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ev8ji")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_65x5e")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_yi6fp")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_eseb1")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ux63t")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ocabh")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_8sepc")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_4d7on")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_jsu7m")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_vhyb2")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_t2dka")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_e6l64")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_mdp8v")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ywpdo")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_1d2bj")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_80asc")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_m5ngl")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_r7ql0")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_w0vp4")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"walk",
|
||||
"speed": 64.0
|
||||
}]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_1lk3q"]
|
||||
radius = 4.0
|
||||
height = 12.0
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_htg24"]
|
||||
radius = 80.0
|
||||
|
||||
[node name="Ant" type="CharacterBody2D"]
|
||||
z_index = 2048
|
||||
z_as_relative = false
|
||||
collision_layer = 16
|
||||
input_pickable = true
|
||||
motion_mode = 1
|
||||
platform_on_leave = 2
|
||||
safe_margin = 2.615
|
||||
script = ExtResource("1_i761n")
|
||||
marker_scene = ExtResource("2_lqnr1")
|
||||
|
||||
[node name="Sprite2D" type="AnimatedSprite2D" parent="."]
|
||||
material = SubResource("ShaderMaterial_bjtx1")
|
||||
rotation = 1.5708
|
||||
scale = Vector2(0.05, 0.05)
|
||||
sprite_frames = SubResource("SpriteFrames_kcoy1")
|
||||
animation = &"walk"
|
||||
frame_progress = 0.938219
|
||||
|
||||
[node name="NavigationAgent2D" type="NavigationAgent2D" parent="."]
|
||||
editor_description = "This navigation agent sends the \"navigation_finished\" event to the state chart whenever the navigation is done."
|
||||
avoidance_enabled = true
|
||||
radius = 40.0
|
||||
max_speed = 50.0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(0, 1)
|
||||
shape = SubResource("CapsuleShape2D_1lk3q")
|
||||
|
||||
[node name="SensorArea" type="Area2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="SensorArea"]
|
||||
shape = SubResource("CircleShape2D_htg24")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
script = ExtResource("3_lard5")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
script = ExtResource("4_ejp2e")
|
||||
initial_state = NodePath("Initializing")
|
||||
|
||||
[node name="Initializing" type="Node" parent="StateChart/Root"]
|
||||
editor_description = "This state is used for script initialization."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="Transition" type="Node" parent="StateChart/Root/Initializing"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Seeking Food")
|
||||
event = &"initialized"
|
||||
|
||||
[node name="Seeking Food" type="Node" parent="StateChart/Root"]
|
||||
editor_description = "In this state, the ant will look for food."
|
||||
script = ExtResource("4_ejp2e")
|
||||
initial_state = NodePath("Idle")
|
||||
|
||||
[node name="Idle" type="Node" parent="StateChart/Root/Seeking Food"]
|
||||
editor_description = "This state is active when the ant currently has no target. It is connected to the script which will look for a new target."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="On Next Destination" type="Node" parent="StateChart/Root/Seeking Food/Idle"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Travelling/Place Marker")
|
||||
event = &"destination_set"
|
||||
|
||||
[node name="On Food Detected" type="Node" parent="StateChart/Root/Seeking Food/Idle"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../../Picking up Food")
|
||||
event = &"food_detected"
|
||||
|
||||
[node name="Travelling" type="Node" parent="StateChart/Root/Seeking Food"]
|
||||
script = ExtResource("4_ejp2e")
|
||||
initial_state = NodePath("Travel")
|
||||
|
||||
[node name="On Navigation Finish" type="Node" parent="StateChart/Root/Seeking Food/Travelling"]
|
||||
editor_description = "When navigation is finished return to idle state."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Idle")
|
||||
event = &"navigation_finished"
|
||||
|
||||
[node name="Travel" type="Node" parent="StateChart/Root/Seeking Food/Travelling"]
|
||||
editor_description = "This state is active while the ant is travelling when searching for food. Periodically the state will be left for placing a marker."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="Periodically Place Marker" type="Node" parent="StateChart/Root/Seeking Food/Travelling/Travel"]
|
||||
editor_description = "While searching for food, periodically place a marker pointing towards the nest. This transition will move to the \"Place Marker\" state which will trigger the placement of the marker. The \"Place Marker\" state will immediately return back to the \"Travel\" state."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Place Marker")
|
||||
delay_seconds = 0.75
|
||||
|
||||
[node name="Place Marker" type="Node" parent="StateChart/Root/Seeking Food/Travelling"]
|
||||
editor_description = "This state is briefly activated when the ant wants to place a marker. It will immediately exit again to the \"Travel\" state."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="Return travelling" type="Node" parent="StateChart/Root/Seeking Food/Travelling/Place Marker"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Travel")
|
||||
|
||||
[node name="Picking up Food" type="Node" parent="StateChart/Root"]
|
||||
editor_description = "This state is active when the ant has detected food and wants to pick it up."
|
||||
script = ExtResource("4_ejp2e")
|
||||
initial_state = NodePath("Travelling")
|
||||
|
||||
[node name="Travelling" type="Node" parent="StateChart/Root/Picking up Food"]
|
||||
editor_description = "This state is active while the ant is moving towards the food."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="On Navigation Finish" type="Node" parent="StateChart/Root/Picking up Food/Travelling"]
|
||||
editor_description = "When navigation is finished we can pick up the food."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Picking Up")
|
||||
event = &"navigation_finished"
|
||||
|
||||
[node name="Picking Up" type="Node" parent="StateChart/Root/Picking up Food"]
|
||||
editor_description = "This state is active when the ant has reached the food and now picks it up."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="On Picked Up" type="Node" parent="StateChart/Root/Picking up Food/Picking Up"]
|
||||
editor_description = "When navigation is finished return to idle state."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../../Returning Home")
|
||||
event = &"food_picked_up"
|
||||
|
||||
[node name="On Food Vanished" type="Node" parent="StateChart/Root/Picking up Food/Picking Up"]
|
||||
editor_description = "When navigation is finished return to idle state."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../../Seeking Food")
|
||||
event = &"food_vanished"
|
||||
|
||||
[node name="Returning Home" type="Node" parent="StateChart/Root"]
|
||||
editor_description = "This state is active when the ant has found food and wants to return home."
|
||||
script = ExtResource("4_ejp2e")
|
||||
initial_state = NodePath("Idle")
|
||||
|
||||
[node name="Idle" type="Node" parent="StateChart/Root/Returning Home"]
|
||||
editor_description = "This state is active when the ant currently has no destination. It calls back into the script which will setup a new destination."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="On Next Destination" type="Node" parent="StateChart/Root/Returning Home/Idle"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Travelling")
|
||||
event = &"destination_set"
|
||||
|
||||
[node name="On Nest Detected" type="Node" parent="StateChart/Root/Returning Home/Idle"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../../Delivering Food")
|
||||
event = &"nest_detected"
|
||||
|
||||
[node name="Travelling" type="Node" parent="StateChart/Root/Returning Home"]
|
||||
editor_description = "This state is active when the ant has a destination and is currently travelling."
|
||||
script = ExtResource("4_ejp2e")
|
||||
initial_state = NodePath("Travel")
|
||||
|
||||
[node name="On Navigation Finish" type="Node" parent="StateChart/Root/Returning Home/Travelling"]
|
||||
editor_description = "When navigation is finished return to idle state."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Idle")
|
||||
event = &"navigation_finished"
|
||||
|
||||
[node name="Travel" type="Node" parent="StateChart/Root/Returning Home/Travelling"]
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="Periodically Place Marker" type="Node" parent="StateChart/Root/Returning Home/Travelling/Travel"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Place Marker")
|
||||
delay_seconds = 1.0
|
||||
|
||||
[node name="Place Marker" type="Node" parent="StateChart/Root/Returning Home/Travelling"]
|
||||
editor_description = "This state is active when the ant has a destination and is moving towards it."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="Return travelling" type="Node" parent="StateChart/Root/Returning Home/Travelling/Place Marker"]
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Travel")
|
||||
|
||||
[node name="Delivering Food" type="Node" parent="StateChart/Root"]
|
||||
editor_description = "This state is active when the ant has detected the nest and wants to bring food back."
|
||||
script = ExtResource("4_ejp2e")
|
||||
initial_state = NodePath("Travelling")
|
||||
|
||||
[node name="Travelling" type="Node" parent="StateChart/Root/Delivering Food"]
|
||||
editor_description = "This state is active when the ant is moving towards the nest."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="On Navigation Finish" type="Node" parent="StateChart/Root/Delivering Food/Travelling"]
|
||||
editor_description = "When navigation is finished we can pick up the food."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../Dropping")
|
||||
event = &"navigation_finished"
|
||||
|
||||
[node name="Dropping" type="Node" parent="StateChart/Root/Delivering Food"]
|
||||
editor_description = "This state is active when the ant is dropping the food off at the nest."
|
||||
script = ExtResource("5_21sgy")
|
||||
|
||||
[node name="On Dropped" type="Node" parent="StateChart/Root/Delivering Food/Dropping"]
|
||||
editor_description = "When navigation is finished return to idle state."
|
||||
script = ExtResource("7_qj278")
|
||||
to = NodePath("../../../Seeking Food")
|
||||
event = &"food_dropped"
|
||||
|
||||
[connection signal="input_event" from="." to="." method="_on_input_event"]
|
||||
[connection signal="ready" from="Sprite2D" to="Sprite2D" method="play" binds= ["walk"]]
|
||||
[connection signal="navigation_finished" from="NavigationAgent2D" to="StateChart" method="send_event" binds= [&"navigation_finished"]]
|
||||
[connection signal="area_entered" from="SensorArea" to="." method="_on_sensor_area_area_entered"]
|
||||
[connection signal="area_exited" from="SensorArea" to="." method="_on_sensor_area_area_exited"]
|
||||
[connection signal="state_physics_processing" from="StateChart/Root" to="." method="_maintenance"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Seeking Food/Idle" to="." method="_on_idle_seeking_food"]
|
||||
[connection signal="state_physics_processing" from="StateChart/Root/Seeking Food/Travelling" to="." method="_on_travelling_state_physics_processing"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Seeking Food/Travelling/Place Marker" to="." method="_place_nest_marker"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Picking up Food/Travelling" to="." method="_on_food_detected"]
|
||||
[connection signal="state_physics_processing" from="StateChart/Root/Picking up Food/Travelling" to="." method="_on_travelling_state_physics_processing"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Picking up Food/Picking Up" to="." method="_on_food_reached"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Returning Home/Idle" to="." method="_on_idle_returning_home"]
|
||||
[connection signal="state_physics_processing" from="StateChart/Root/Returning Home/Travelling" to="." method="_on_travelling_state_physics_processing"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Returning Home/Travelling/Place Marker" to="." method="_place_food_marker"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Delivering Food/Travelling" to="." method="_on_nest_detected"]
|
||||
[connection signal="state_physics_processing" from="StateChart/Root/Delivering Food/Travelling" to="." method="_on_travelling_state_physics_processing"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Delivering Food/Dropping" to="." method="_on_nest_reached"]
|
BIN
godot_state_charts_examples/ant_hill/ant/walk.png
Normal file
After Width: | Height: | Size: 716 KiB |
34
godot_state_charts_examples/ant_hill/ant/walk.png.import
Normal file
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bqgc7cft671q0"
|
||||
path="res://.godot/imported/walk.png-77b94883438df4792795bd4b6c922fa6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/ant_hill/ant/walk.png"
|
||||
dest_files=["res://.godot/imported/walk.png-77b94883438df4792795bd4b6c922fa6.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
|
9
godot_state_charts_examples/ant_hill/ant_hill_demo.gd
Normal file
@ -0,0 +1,9 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
func _ready():
|
||||
# initialize the RNG
|
||||
randomize()
|
||||
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
uid://dyop2ixs375ks
|
157
godot_state_charts_examples/ant_hill/ant_hill_demo.tscn
Normal file
10
godot_state_charts_examples/ant_hill/banana/banana.svg
Normal file
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<path d="M5.333,13.165C5.333,13.165 10.079,16.966 13.732,17.071C17.386,17.176 23.307,15.769 24.798,14.929C26.289,14.089 26.856,11.297 26.856,11.297L28.325,9.953L26.94,14.32L25.995,19.003C25.995,19.003 21.018,22.152 17.26,22.635C13.501,23.118 6.971,20.598 5.879,19.276C4.787,17.953 3.566,15.518 3.36,14.488C3.152,13.453 3.57,12.388 3.57,12.388L5.333,13.165Z" style="fill:url(#_Linear1);"/>
|
||||
<path d="M3.302,13.48C3.302,13.48 7.692,16.731 9.344,17.659C10.751,18.449 12.374,18.937 13.984,19.045C15.871,19.171 18.789,18.922 20.661,18.415C22.32,17.965 26.478,14.446 26.478,14.446C26.478,14.446 24.209,18.586 22.719,19.171C21.078,19.815 17.813,20.71 16,20.724C14.407,20.737 12.122,20.406 10.625,19.864C8.997,19.274 6.156,17.773 5.06,16.828C4.245,16.125 3.302,13.48 3.302,13.48Z" style="fill:url(#_Radial2);"/>
|
||||
<defs>
|
||||
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(-3.92912,9.49081,-9.49081,-3.92912,17.2441,14.2665)"><stop offset="0" style="stop-color:rgb(214,255,76);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(157,238,0);stop-opacity:1"/></linearGradient>
|
||||
<radialGradient id="_Radial2" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.48819,-23.1229,23.1229,2.48819,12.1575,18.7297)"><stop offset="0" style="stop-color:black;stop-opacity:0.16"/><stop offset="0.38" style="stop-color:black;stop-opacity:0"/><stop offset="1" style="stop-color:black;stop-opacity:0"/></radialGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cqt6bgiwgqym7"
|
||||
path="res://.godot/imported/banana.svg-e48dc3ddd49722cb94ca8f088061cec6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/ant_hill/banana/banana.svg"
|
||||
dest_files=["res://.godot/imported/banana.svg-e48dc3ddd49722cb94ca8f088061cec6.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
20
godot_state_charts_examples/ant_hill/banana/banana.tscn
Normal file
@ -0,0 +1,20 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bqalfgp8jjady"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://cqt6bgiwgqym7" path="res://godot_state_charts_examples/ant_hill/banana/banana.svg" id="1_uoy0d"]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_vo3bi"]
|
||||
radius = 7.99901
|
||||
height = 32.0275
|
||||
|
||||
[node name="banana" type="Node2D" groups=["food"]]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture_filter = 1
|
||||
texture = ExtResource("1_uoy0d")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
metadata/owner = NodePath("..")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
rotation = 1.5865
|
||||
shape = SubResource("CapsuleShape2D_vo3bi")
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<g transform="matrix(1.89907,0,0,1.89907,-11.2249,-10.4075)">
|
||||
<circle cx="10.123" cy="9.693" r="4.213" style="fill:white;"/>
|
||||
</g>
|
||||
<path d="M8,1.533L13.596,6.688L8,6.824L8,13.638L8,6.824L2.394,6.688L8,1.533Z" style="fill:none;stroke:black;stroke-width:1px;"/>
|
||||
</svg>
|
After Width: | Height: | Size: 752 B |
@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b3k7i5rrn5hhl"
|
||||
path="res://.godot/imported/circle_white.svg-63c895b75f0338e9c3ca264b87816990.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/ant_hill/marker/circle_white.svg"
|
||||
dest_files=["res://.godot/imported/circle_white.svg-63c895b75f0338e9c3ca264b87816990.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
47
godot_state_charts_examples/ant_hill/marker/marker.gd
Normal file
@ -0,0 +1,47 @@
|
||||
class_name Marker
|
||||
extends Node2D
|
||||
|
||||
## How long should the marker live for?
|
||||
@export var lifetime_seconds:float = 30.0
|
||||
|
||||
|
||||
var expired_time:float = 0
|
||||
|
||||
|
||||
enum MarkerType {
|
||||
## A marker guiding towards food.
|
||||
FOOD,
|
||||
## A marker guiding towards a nest.
|
||||
NEST
|
||||
}
|
||||
|
||||
func initialize(type:MarkerType):
|
||||
add_to_group("marker")
|
||||
match type:
|
||||
MarkerType.FOOD:
|
||||
modulate = Color.YELLOW
|
||||
add_to_group("food")
|
||||
MarkerType.NEST:
|
||||
modulate = Color.CORNFLOWER_BLUE
|
||||
add_to_group("nest")
|
||||
lifetime_seconds *= 2
|
||||
|
||||
## Refreshes the marker, so it stays for another lifetime
|
||||
func refresh():
|
||||
expired_time = 0
|
||||
|
||||
## Updates the marker and destroys it if has evaporated.
|
||||
func _process(delta):
|
||||
expired_time += delta
|
||||
# Fade out the marker as it expires.
|
||||
modulate.a = max(0, 1 - (expired_time / lifetime_seconds))
|
||||
if expired_time > lifetime_seconds:
|
||||
queue_free()
|
||||
|
||||
## Some debug drawing currently disabled.
|
||||
func __draw():
|
||||
var offset = 0.0 if is_in_group("food") else PI
|
||||
var start_angle = - PI / 2 + offset
|
||||
var end_angle = PI / 2 + offset
|
||||
draw_arc(Vector2.ZERO, 30, start_angle, end_angle, 10, modulate, 1, true )
|
||||
|
@ -0,0 +1 @@
|
||||
uid://dikixfhsqssxf
|
20
godot_state_charts_examples/ant_hill/marker/marker.tscn
Normal file
@ -0,0 +1,20 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://dy5xrmjffewnk"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://b3k7i5rrn5hhl" path="res://godot_state_charts_examples/ant_hill/marker/circle_white.svg" id="1_2vg4s"]
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/ant_hill/marker/marker.gd" id="2_2b6iy"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_0xsut"]
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
script = ExtResource("2_2b6iy")
|
||||
|
||||
[node name="Sprite" type="Sprite2D" parent="."]
|
||||
texture_filter = 1
|
||||
rotation = 1.5708
|
||||
texture = ExtResource("1_2vg4s")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
metadata/owner = NodePath("..")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
shape = SubResource("CircleShape2D_0xsut")
|
17
godot_state_charts_examples/ant_hill/nest/nest.svg
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.5;">
|
||||
<path d="M2.751,26.163C2.751,26.163 9.264,27.569 14.887,28.036C21.176,28.559 29.249,27.192 29.249,27.192L28.619,18.541L24.672,14.026C24.672,14.026 21.585,13.858 20.367,11.108C19.15,8.357 17.071,7.853 15.349,7.496C13.627,7.139 10.457,9.869 9.68,10.079C8.903,10.289 9.722,11.717 8.063,14.278C6.404,16.84 7.307,18.667 5.921,19.864C4.535,21.06 2.751,26.163 2.751,26.163" style="fill:url(#_Linear1);"/>
|
||||
<path d="M21.816,25.071C21.816,25.071 23.097,21.585 24.714,21.858C26.331,22.131 25.512,21.186 26.268,20.367" style="fill:none;stroke:rgb(174,159,25);stroke-width:1px;"/>
|
||||
<g transform="matrix(1,0,0,0.592883,0,8.94162)">
|
||||
<path d="M5.438,21.963C5.438,21.963 8.987,25.743 11.801,25.512C14.614,25.281 16.567,23.643 16.567,23.643" style="fill:none;stroke:url(#_Linear2);stroke-width:1.22px;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,0.592883,3.65354,1.99149)">
|
||||
<path d="M5.438,21.963C5.438,21.963 9.533,27.089 12.346,26.858C15.16,26.627 18.163,29.664 18.163,29.664" style="fill:none;stroke:url(#_Linear3);stroke-width:1.22px;"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(2.09974,-9.07087,9.07087,2.09974,12.6404,23.2021)"><stop offset="0" style="stop-color:rgb(73,64,28);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(140,131,94);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear2" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(11.1286,0,0,3.55873,5.43832,23.7426)"><stop offset="0" style="stop-color:rgb(30,100,0);stop-opacity:1"/><stop offset="0.54" style="stop-color:rgb(207,198,119);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(174,159,25);stop-opacity:1"/></linearGradient>
|
||||
<linearGradient id="_Linear3" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(11.1286,0,0,3.55873,5.43832,23.7426)"><stop offset="0" style="stop-color:rgb(30,100,0);stop-opacity:1"/><stop offset="0.54" style="stop-color:rgb(207,198,119);stop-opacity:1"/><stop offset="1" style="stop-color:rgb(174,159,25);stop-opacity:1"/></linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
37
godot_state_charts_examples/ant_hill/nest/nest.svg.import
Normal file
@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://xb5fialweqfw"
|
||||
path="res://.godot/imported/nest.svg-4361abbd79cc59afa101f89034d762a6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/ant_hill/nest/nest.svg"
|
||||
dest_files=["res://.godot/imported/nest.svg-4361abbd79cc59afa101f89034d762a6.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
|
||||
svg/scale=2.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
16
godot_state_charts_examples/ant_hill/nest/nest.tscn
Normal file
@ -0,0 +1,16 @@
|
||||
[gd_scene load_steps=3 format=3]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://xb5fialweqfw" path="res://godot_state_charts_examples/ant_hill/nest/nest.svg" id="1_8slek"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_b8f1n"]
|
||||
radius = 37.1214
|
||||
|
||||
[node name="Nest" type="Sprite2D" groups=["nest"]]
|
||||
texture = ExtResource("1_8slek")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
metadata/owner = NodePath("..")
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
position = Vector2(-1, -1)
|
||||
shape = SubResource("CircleShape2D_b8f1n")
|
10
godot_state_charts_examples/ant_hill/pause_controller.gd
Normal file
@ -0,0 +1,10 @@
|
||||
extends Node
|
||||
|
||||
|
||||
func _ready():
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
|
||||
func _input(event):
|
||||
if event is InputEventKey and event.is_pressed() and event.keycode == KEY_SPACE:
|
||||
get_tree().paused = not get_tree().paused
|
||||
print("Paused ", get_tree().paused)
|
@ -0,0 +1 @@
|
||||
uid://nonu8fobnml7
|
@ -0,0 +1,201 @@
|
||||
[gd_scene load_steps=21 format=3 uid="uid://huy14b6x10bh"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bgswg1pgd01d1" path="res://godot_state_charts_examples/platformer/ninja_frog/full.png" id="2_dka03"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="3_7ryss"]
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/automatic_transitions/the_frog.gd" id="3_q65wd"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="4_64ox6"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="5_ooc8l"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/parallel_state.gd" id="5_uojl1"]
|
||||
[ext_resource type="PackedScene" uid="uid://bcwkugn6v3oy7" path="res://addons/godot_state_charts/utilities/state_chart_debugger.tscn" id="6_xggmu"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="7_v4wmr"]
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/automatic_transitions/stamina_bar.gd" id="9_rtmjc"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_is_active_guard.gd" id="10_caxti"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/not_guard.gd" id="11_rfa1s"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_2fogg"]
|
||||
size = Vector2(275, 15)
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_tsftx"]
|
||||
size = Vector2(18.5, 227)
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_bocu2"]
|
||||
radius = 15.0
|
||||
height = 32.0
|
||||
|
||||
[sub_resource type="Resource" id="Resource_m8fyc"]
|
||||
script = ExtResource("10_caxti")
|
||||
state = NodePath("../../../Walking Control/Needs Rest")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_4i0ee"]
|
||||
script = ExtResource("10_caxti")
|
||||
state = NodePath("../../../Walking Control/Needs Rest")
|
||||
|
||||
[sub_resource type="Resource" id="Resource_br5hd"]
|
||||
script = ExtResource("11_rfa1s")
|
||||
guard = SubResource("Resource_4i0ee")
|
||||
|
||||
[sub_resource type="Animation" id="Animation_nb642"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath(".:modulate")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_wtk5r"]
|
||||
resource_name = "pulsate"
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath(".:modulate")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.5, 1),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 1), Color(1, 0, 0, 1), Color(1, 1, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ghdrh"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_nb642"),
|
||||
"pulsate": SubResource("Animation_wtk5r")
|
||||
}
|
||||
|
||||
[node name="Node2D" type="Node2D"]
|
||||
|
||||
[node name="StateChartDebugger" parent="." instance=ExtResource("6_xggmu")]
|
||||
offset_left = 293.0
|
||||
offset_top = 10.0
|
||||
offset_right = 624.0
|
||||
offset_bottom = 441.0
|
||||
initial_node_to_watch = NodePath("../TheFrog/StateChart")
|
||||
|
||||
[node name="Borders" type="StaticBody2D" parent="."]
|
||||
|
||||
[node name="Top" type="CollisionShape2D" parent="Borders"]
|
||||
position = Vector2(139.25, 170)
|
||||
shape = SubResource("RectangleShape2D_2fogg")
|
||||
|
||||
[node name="Bottom" type="CollisionShape2D" parent="Borders"]
|
||||
position = Vector2(143.25, 385)
|
||||
shape = SubResource("RectangleShape2D_2fogg")
|
||||
|
||||
[node name="Left" type="CollisionShape2D" parent="Borders"]
|
||||
position = Vector2(11, 280.5)
|
||||
shape = SubResource("RectangleShape2D_tsftx")
|
||||
|
||||
[node name="Right" type="CollisionShape2D" parent="Borders"]
|
||||
position = Vector2(268.25, 276)
|
||||
shape = SubResource("RectangleShape2D_tsftx")
|
||||
|
||||
[node name="TheFrog" type="CharacterBody2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
position = Vector2(65.25, 288)
|
||||
script = ExtResource("3_q65wd")
|
||||
|
||||
[node name="Icon" type="Sprite2D" parent="TheFrog"]
|
||||
texture = ExtResource("2_dka03")
|
||||
region_enabled = true
|
||||
region_rect = Rect2(0, 0, 32, 32)
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="TheFrog"]
|
||||
shape = SubResource("CapsuleShape2D_bocu2")
|
||||
|
||||
[node name="StateChart" type="Node" parent="TheFrog"]
|
||||
unique_name_in_owner = true
|
||||
script = ExtResource("3_7ryss")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="ParallelState" type="Node" parent="TheFrog/StateChart"]
|
||||
script = ExtResource("5_uojl1")
|
||||
|
||||
[node name="Walking Control" type="Node" parent="TheFrog/StateChart/ParallelState"]
|
||||
script = ExtResource("4_64ox6")
|
||||
initial_state = NodePath("Can Walk")
|
||||
|
||||
[node name="Can Walk" type="Node" parent="TheFrog/StateChart/ParallelState/Walking Control"]
|
||||
editor_description = "In this state the frog can move around and will lose stamina. If stamina drops to 0 the frog will automatically transition to \"Needs Rest\"."
|
||||
script = ExtResource("5_ooc8l")
|
||||
|
||||
[node name="On Exhausted To Needs Rest" type="Node" parent="TheFrog/StateChart/ParallelState/Walking Control/Can Walk"]
|
||||
editor_description = "This transition will listen to the \"exhausted\" event, triggered when the frog's stamina sinks to 0. We could also use an expression property tracking the stamina but using a dedicated event is faster and more extensible."
|
||||
script = ExtResource("7_v4wmr")
|
||||
to = NodePath("../../Needs Rest")
|
||||
event = &"exhausted"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Needs Rest" type="Node" parent="TheFrog/StateChart/ParallelState/Walking Control"]
|
||||
editor_description = "In this state the frog cannot move for 3 seconds."
|
||||
script = ExtResource("5_ooc8l")
|
||||
|
||||
[node name="After 3 seconds To Can Walk" type="Node" parent="TheFrog/StateChart/ParallelState/Walking Control/Needs Rest"]
|
||||
editor_description = "This will automatically transition back to \"Can Walk\" after 3 seconds."
|
||||
script = ExtResource("7_v4wmr")
|
||||
to = NodePath("../../Can Walk")
|
||||
delay_in_seconds = "3"
|
||||
|
||||
[node name="Animation Control" type="Node" parent="TheFrog/StateChart/ParallelState"]
|
||||
editor_description = "This controls the pulsating red animation when the frog is exhausted. Note that you could also model this using state_entered and state_exited events on the \"Needs Rest\" state, which is simpler (and more performant). Its only done this way to show automatic events."
|
||||
script = ExtResource("4_64ox6")
|
||||
initial_state = NodePath("Normal")
|
||||
|
||||
[node name="Normal" type="Node" parent="TheFrog/StateChart/ParallelState/Animation Control"]
|
||||
script = ExtResource("5_ooc8l")
|
||||
|
||||
[node name="On Needs Rest to Pulsating Red" type="Node" parent="TheFrog/StateChart/ParallelState/Animation Control/Normal"]
|
||||
editor_description = "This is another example of an automatic transition. When the \"Needs Rest\" state becomes active, this will automatically transition to the \"Pulsating Red\" state."
|
||||
script = ExtResource("7_v4wmr")
|
||||
to = NodePath("../../Pulsating Red")
|
||||
guard = SubResource("Resource_m8fyc")
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Pulsating Red" type="Node" parent="TheFrog/StateChart/ParallelState/Animation Control"]
|
||||
script = ExtResource("5_ooc8l")
|
||||
|
||||
[node name="On Not Needs Rest to Normal" type="Node" parent="TheFrog/StateChart/ParallelState/Animation Control/Pulsating Red"]
|
||||
editor_description = "When the \"Needs Rest\" state becomes inactive, this will automatically transition to the \"Normal\" state."
|
||||
script = ExtResource("7_v4wmr")
|
||||
to = NodePath("../../Normal")
|
||||
guard = SubResource("Resource_br5hd")
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="TheFrog"]
|
||||
unique_name_in_owner = true
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_ghdrh")
|
||||
}
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
offset_left = 19.25
|
||||
offset_top = 401.0
|
||||
offset_right = 272.25
|
||||
offset_bottom = 458.0
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Stamina"
|
||||
|
||||
[node name="StaminaBar" type="ProgressBar" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
script = ExtResource("9_rtmjc")
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
offset_right = 286.0
|
||||
offset_bottom = 156.0
|
||||
text = "This example shows automatic transitions. Move the frog with the arrow keys. If the frog loses all stamina, it automatically transitions to a state where it will be unable to move for 3 seconds."
|
||||
autowrap_mode = 2
|
||||
|
||||
[connection signal="state_physics_processing" from="TheFrog/StateChart/ParallelState/Walking Control/Can Walk" to="TheFrog" method="_on_can_walk_state_physics_processing"]
|
||||
[connection signal="state_physics_processing" from="TheFrog/StateChart/ParallelState/Walking Control/Needs Rest" to="TheFrog" method="_on_needs_rest_state_physics_processing"]
|
||||
[connection signal="state_entered" from="TheFrog/StateChart/ParallelState/Animation Control/Normal" to="TheFrog" method="_on_normal_state_entered"]
|
||||
[connection signal="state_entered" from="TheFrog/StateChart/ParallelState/Animation Control/Pulsating Red" to="TheFrog" method="_on_pulsating_red_state_entered"]
|
@ -0,0 +1,9 @@
|
||||
extends ProgressBar
|
||||
|
||||
|
||||
@onready var the_frog = %TheFrog
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(_delta):
|
||||
value = the_frog.stamina
|
@ -0,0 +1 @@
|
||||
uid://dn780r00o0xam
|
@ -0,0 +1,48 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
# We can move 100 pixels per second
|
||||
const SPEED = 100.0
|
||||
|
||||
# We recover 20 stamina per second
|
||||
const RECOVER_RATE = 20.0
|
||||
|
||||
@onready var state_chart:StateChart = %StateChart
|
||||
@onready var animation_player = %AnimationPlayer
|
||||
|
||||
var stamina:float = 100
|
||||
|
||||
|
||||
|
||||
### WALKING CONTROL STATES
|
||||
|
||||
# In the "Can Walk" state we can walk around and lose stamina.
|
||||
func _on_can_walk_state_physics_processing(delta):
|
||||
# Get the direction
|
||||
var direction = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
|
||||
# Calculate velocity
|
||||
velocity = direction * SPEED
|
||||
|
||||
|
||||
# if we moved, subtract stamina
|
||||
if velocity.length() > 0:
|
||||
stamina = max(0, stamina - RECOVER_RATE * delta)
|
||||
else:
|
||||
# else add it.
|
||||
stamina = min(100, stamina + RECOVER_RATE * delta)
|
||||
|
||||
if stamina <= 0:
|
||||
state_chart.send_event("exhausted")
|
||||
|
||||
move_and_slide()
|
||||
|
||||
# If our stamina hits 0, we enter the "Needs rest" state which
|
||||
# only allows us to recover stamina.
|
||||
func _on_needs_rest_state_physics_processing(delta):
|
||||
stamina = min(100, stamina + RECOVER_RATE * delta)
|
||||
|
||||
### ANIMATION CONTROL STATES
|
||||
func _on_pulsating_red_state_entered():
|
||||
animation_player.play("pulsate")
|
||||
|
||||
func _on_normal_state_entered():
|
||||
animation_player.play("RESET")
|
@ -0,0 +1 @@
|
||||
uid://jjduf53mb1hc
|
6
godot_state_charts_examples/cooldown/LICENSE.md
Normal file
@ -0,0 +1,6 @@
|
||||
The icons in this demo are used under CC BY 3.0 DEED license
|
||||
(https://creativecommons.org/licenses/by/3.0/).
|
||||
|
||||
Original author:
|
||||
|
||||
J. W. Bjerk (eleazzaar) -- www.jwbjerk.com/art -- find this and other open art at: http://opengameart.org
|
140
godot_state_charts_examples/cooldown/cooldown_demo.tscn
Normal file
@ -0,0 +1,140 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://cnqh7qot0estd"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bcwkugn6v3oy7" path="res://addons/godot_state_charts/utilities/state_chart_debugger.tscn" id="1_oec6f"]
|
||||
[ext_resource type="PackedScene" uid="uid://ch1pukkyc07qo" path="res://godot_state_charts_examples/cooldown/skill_button/skill_button.tscn" id="2_aahy2"]
|
||||
[ext_resource type="Texture2D" uid="uid://bphe0g2d306fe" path="res://godot_state_charts_examples/cooldown/icons/enchant-red-3.png" id="3_a8h0q"]
|
||||
[ext_resource type="Texture2D" uid="uid://bjmc4abduaxww" path="res://godot_state_charts_examples/cooldown/icons/fireball-eerie-2.png" id="4_jhd8u"]
|
||||
[ext_resource type="Texture2D" uid="uid://b87nmomi1l48x" path="res://godot_state_charts_examples/cooldown/icons/heal-jade-2.png" id="5_xxunm"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="6_d3pqh"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/parallel_state.gd" id="7_l6ahs"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="8_pvst5"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="9_h41ei"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="10_5fig4"]
|
||||
|
||||
[node name="Cooldown Example" type="Node2D"]
|
||||
|
||||
[node name="StateChartDebugger" parent="." instance=ExtResource("1_oec6f")]
|
||||
offset_left = 290.0
|
||||
offset_top = 16.0
|
||||
offset_right = 629.0
|
||||
offset_bottom = 466.0
|
||||
initial_node_to_watch = NodePath("../StateChart")
|
||||
|
||||
[node name="InfoLabel" type="Label" parent="."]
|
||||
offset_left = 10.0
|
||||
offset_top = 24.0
|
||||
offset_right = 277.0
|
||||
offset_bottom = 128.0
|
||||
text = "This example shows how to connect delayed transitions with game UI to model skill buttons that have cooldowns. Click the buttons to try it."
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
offset_left = 18.0
|
||||
offset_top = 164.0
|
||||
offset_right = 278.0
|
||||
offset_bottom = 435.0
|
||||
theme_override_constants/separation = 15
|
||||
|
||||
[node name="AttackSkillButton" parent="VBoxContainer" instance=ExtResource("2_aahy2")]
|
||||
editor_description = "This is the attack skill button. When you press it, it will send the \"attack\" event to the state chart."
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
texture = ExtResource("3_a8h0q")
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="MagicSkillButton" parent="VBoxContainer/HBoxContainer" instance=ExtResource("2_aahy2")]
|
||||
editor_description = "This is the magic skill button. When you press it, it will send the \"magic\" event to the state chart."
|
||||
layout_mode = 2
|
||||
texture = ExtResource("4_jhd8u")
|
||||
|
||||
[node name="HealSkillButton" parent="VBoxContainer/HBoxContainer" instance=ExtResource("2_aahy2")]
|
||||
editor_description = "This is the heal skill button. When you press it, it will send the \"heal\" event to the state chart."
|
||||
layout_mode = 2
|
||||
texture = ExtResource("5_xxunm")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
script = ExtResource("6_d3pqh")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
editor_description = "Since all three skills can be used independently of each other we use a parallel state as the root here."
|
||||
script = ExtResource("7_l6ahs")
|
||||
|
||||
[node name="AttackSkill" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("8_pvst5")
|
||||
initial_state = NodePath("Available")
|
||||
|
||||
[node name="Available" type="Node" parent="StateChart/Root/AttackSkill"]
|
||||
editor_description = "State indicating that attack is available. Entering this state will reset the cooldown on the attack skill button."
|
||||
script = ExtResource("9_h41ei")
|
||||
|
||||
[node name="On Attack To Cooldown" type="Node" parent="StateChart/Root/AttackSkill/Available"]
|
||||
script = ExtResource("10_5fig4")
|
||||
to = NodePath("../../Cooldown")
|
||||
event = &"attack"
|
||||
|
||||
[node name="Cooldown" type="Node" parent="StateChart/Root/AttackSkill"]
|
||||
editor_description = "Cooldown state for the attack skill. While the delayed transition is pending, this state will send status updates on the pending transition to the attack skill button. The attack skill button will then update itself and show the remaining cooldown."
|
||||
script = ExtResource("9_h41ei")
|
||||
|
||||
[node name="Back to Available" type="Node" parent="StateChart/Root/AttackSkill/Cooldown"]
|
||||
script = ExtResource("10_5fig4")
|
||||
to = NodePath("../../Available")
|
||||
delay_seconds = 1.0
|
||||
|
||||
[node name="MagicSkill" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("8_pvst5")
|
||||
initial_state = NodePath("Available")
|
||||
|
||||
[node name="Available" type="Node" parent="StateChart/Root/MagicSkill"]
|
||||
editor_description = "State indicating that the magic skill is available. Entering this state will reset the cooldown on the magic skill button."
|
||||
script = ExtResource("9_h41ei")
|
||||
|
||||
[node name="On Magic To Cooldown" type="Node" parent="StateChart/Root/MagicSkill/Available"]
|
||||
script = ExtResource("10_5fig4")
|
||||
to = NodePath("../../Cooldown")
|
||||
event = &"magic"
|
||||
|
||||
[node name="Cooldown" type="Node" parent="StateChart/Root/MagicSkill"]
|
||||
editor_description = "Cooldown state for the magic skill. While the delayed transition is pending, this state will send status updates on the pending transition to the magic skill button. The magic skill button will then update itself and show the remaining cooldown."
|
||||
script = ExtResource("9_h41ei")
|
||||
|
||||
[node name="Back to Available" type="Node" parent="StateChart/Root/MagicSkill/Cooldown"]
|
||||
script = ExtResource("10_5fig4")
|
||||
to = NodePath("../../Available")
|
||||
delay_seconds = 3.0
|
||||
|
||||
[node name="HealSkill" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("8_pvst5")
|
||||
initial_state = NodePath("Available")
|
||||
|
||||
[node name="Available" type="Node" parent="StateChart/Root/HealSkill"]
|
||||
editor_description = "State indicating that the heal skill is available. Entering this state will reset the cooldown on the heal skill button."
|
||||
script = ExtResource("9_h41ei")
|
||||
|
||||
[node name="On Heal To Cooldown" type="Node" parent="StateChart/Root/HealSkill/Available"]
|
||||
script = ExtResource("10_5fig4")
|
||||
to = NodePath("../../Cooldown")
|
||||
event = &"heal"
|
||||
|
||||
[node name="Cooldown" type="Node" parent="StateChart/Root/HealSkill"]
|
||||
editor_description = "Cooldown state for the heal skill. While the delayed transition is pending, this state will send status updates on the pending transition to the heal skill button. The heal skill button will then update itself and show the remaining cooldown."
|
||||
script = ExtResource("9_h41ei")
|
||||
|
||||
[node name="Back to Available" type="Node" parent="StateChart/Root/HealSkill/Cooldown"]
|
||||
script = ExtResource("10_5fig4")
|
||||
to = NodePath("../../Available")
|
||||
delay_seconds = 10.0
|
||||
|
||||
[connection signal="pressed" from="VBoxContainer/AttackSkillButton" to="StateChart" method="send_event" binds= ["attack"]]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/MagicSkillButton" to="StateChart" method="send_event" binds= ["magic"]]
|
||||
[connection signal="pressed" from="VBoxContainer/HBoxContainer/HealSkillButton" to="StateChart" method="send_event" binds= ["heal"]]
|
||||
[connection signal="state_entered" from="StateChart/Root/AttackSkill/Available" to="VBoxContainer/AttackSkillButton" method="clear_cooldown"]
|
||||
[connection signal="transition_pending" from="StateChart/Root/AttackSkill/Cooldown" to="VBoxContainer/AttackSkillButton" method="set_cooldown"]
|
||||
[connection signal="state_entered" from="StateChart/Root/MagicSkill/Available" to="VBoxContainer/HBoxContainer/MagicSkillButton" method="clear_cooldown"]
|
||||
[connection signal="transition_pending" from="StateChart/Root/MagicSkill/Cooldown" to="VBoxContainer/HBoxContainer/MagicSkillButton" method="set_cooldown"]
|
||||
[connection signal="state_entered" from="StateChart/Root/HealSkill/Available" to="VBoxContainer/HBoxContainer/HealSkillButton" method="clear_cooldown"]
|
||||
[connection signal="transition_pending" from="StateChart/Root/HealSkill/Cooldown" to="VBoxContainer/HBoxContainer/HealSkillButton" method="set_cooldown"]
|
BIN
godot_state_charts_examples/cooldown/icons/cooldown_overlay.png
Normal file
After Width: | Height: | Size: 318 B |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://tgsnqiq40n41"
|
||||
path="res://.godot/imported/cooldown_overlay.png-5594f471c10cac21fce498b609075490.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/cooldown/icons/cooldown_overlay.png"
|
||||
dest_files=["res://.godot/imported/cooldown_overlay.png-5594f471c10cac21fce498b609075490.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
|
BIN
godot_state_charts_examples/cooldown/icons/enchant-red-3.png
Normal file
After Width: | Height: | Size: 30 KiB |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bphe0g2d306fe"
|
||||
path="res://.godot/imported/enchant-red-3.png-1df2c19bbfe03c22227b3db03bc16eee.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/cooldown/icons/enchant-red-3.png"
|
||||
dest_files=["res://.godot/imported/enchant-red-3.png-1df2c19bbfe03c22227b3db03bc16eee.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
|
BIN
godot_state_charts_examples/cooldown/icons/fireball-eerie-2.png
Normal file
After Width: | Height: | Size: 26 KiB |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bjmc4abduaxww"
|
||||
path="res://.godot/imported/fireball-eerie-2.png-a420ae5d8f4f4f86ea5ef03eeea7f3c6.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/cooldown/icons/fireball-eerie-2.png"
|
||||
dest_files=["res://.godot/imported/fireball-eerie-2.png-a420ae5d8f4f4f86ea5ef03eeea7f3c6.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
|
BIN
godot_state_charts_examples/cooldown/icons/heal-jade-2.png
Normal file
After Width: | Height: | Size: 32 KiB |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://b87nmomi1l48x"
|
||||
path="res://.godot/imported/heal-jade-2.png-5317fa8cf716c70c254fee8762a0dfda.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/cooldown/icons/heal-jade-2.png"
|
||||
dest_files=["res://.godot/imported/heal-jade-2.png-5317fa8cf716c70c254fee8762a0dfda.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,51 @@
|
||||
## This is tool so we can show the selected texture immediately in the editor.
|
||||
@tool
|
||||
extends MarginContainer
|
||||
|
||||
signal pressed()
|
||||
|
||||
@export var texture:Texture2D:
|
||||
set(value):
|
||||
texture = value
|
||||
_apply_settings()
|
||||
|
||||
## The progressbar we control
|
||||
@onready var _texture_progress_bar:TextureProgressBar = %TextureProgressBar
|
||||
|
||||
## The label showing the cooldown in seconds
|
||||
@onready var _label:Label = %Label
|
||||
|
||||
## The button that can be pressed
|
||||
@onready var _button:Button = %Button
|
||||
|
||||
func _ready():
|
||||
_apply_settings()
|
||||
|
||||
|
||||
func _apply_settings():
|
||||
if _texture_progress_bar != null:
|
||||
_texture_progress_bar.texture_under = texture
|
||||
|
||||
## Called while cooldown transitions run. Will update the state of the
|
||||
## cooldown in the UI elements and disable the button until clear_cooldown
|
||||
## is called.
|
||||
func set_cooldown(total:float, current:float):
|
||||
_label.visible = true
|
||||
_button.disabled = true
|
||||
_texture_progress_bar.max_value = total
|
||||
_texture_progress_bar.value = current
|
||||
_label.text = "%.1f" % current
|
||||
|
||||
|
||||
## Called to clear the cooldown. Will enable the button and clear all cooldown
|
||||
## indicators.
|
||||
func clear_cooldown():
|
||||
_label.visible = false
|
||||
_button.disabled = false
|
||||
_texture_progress_bar.value = 0
|
||||
|
||||
_texture_progress_bar.max_value = 100
|
||||
|
||||
## Signal relay for the inner button.
|
||||
func _on_button_pressed():
|
||||
pressed.emit()
|
@ -0,0 +1 @@
|
||||
uid://cjlrmcmit4jhm
|
@ -0,0 +1,34 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://ch1pukkyc07qo"]
|
||||
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/cooldown/skill_button/skill_button.gd" id="1_r0ivs"]
|
||||
[ext_resource type="Texture2D" uid="uid://tgsnqiq40n41" path="res://godot_state_charts_examples/cooldown/icons/cooldown_overlay.png" id="3_pgrfi"]
|
||||
|
||||
[node name="SkillButton" type="MarginContainer"]
|
||||
offset_right = 32.0
|
||||
offset_bottom = 32.0
|
||||
script = ExtResource("1_r0ivs")
|
||||
|
||||
[node name="Button" type="Button" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
|
||||
[node name="TextureProgressBar" type="TextureProgressBar" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
mouse_filter = 2
|
||||
step = 0.0
|
||||
fill_mode = 4
|
||||
texture_progress = ExtResource("3_pgrfi")
|
||||
tint_progress = Color(0, 0, 0, 1)
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_outline_color = Color(0, 0, 0, 1)
|
||||
theme_override_constants/outline_size = 8
|
||||
theme_override_font_sizes/font_size = 48
|
||||
text = "10"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
|
115
godot_state_charts_examples/csharp/CSharpExample.cs
Normal file
@ -0,0 +1,115 @@
|
||||
using Godot;
|
||||
using GodotStateCharts;
|
||||
|
||||
namespace Movementtests.godot_state_charts_examples.csharp;
|
||||
|
||||
/// <summary>
|
||||
/// This is an example of how to use the state chart from C#.
|
||||
/// </summary>
|
||||
// ReSharper disable once CheckNamespace
|
||||
public partial class CSharpExample : Node2D
|
||||
{
|
||||
|
||||
private StateChart _stateChart;
|
||||
private Label _feelLabel;
|
||||
private int _health = 20;
|
||||
private StateChartState _poisonedStateChartState;
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
// Get the state chart node and wrap it in a StateChart object, so we can easily
|
||||
// interact with it from C#.
|
||||
_stateChart = StateChart.Of(GetNode("%StateChart"));
|
||||
|
||||
// Get the poisoned state node and wrap it in a State object, so we can easily
|
||||
// interact with it from C#.
|
||||
_poisonedStateChartState = StateChartState.Of(GetNode("%Poisoned"));
|
||||
|
||||
// The the UI label.
|
||||
_feelLabel = GetNode<Label>("%FeelLabel");
|
||||
RefreshUi();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the drink poison button is pressed.
|
||||
/// </summary>
|
||||
private void OnDrinkPoisonButtonPressed()
|
||||
{
|
||||
// This uses the regular API to interact with the state chart.
|
||||
var currentPoisonCount = _stateChart.GetExpressionProperty("poison_count", 0);
|
||||
currentPoisonCount += 3; // we add three rounds worth of poison
|
||||
|
||||
_stateChart.SetExpressionProperty("poison_count", currentPoisonCount);
|
||||
_stateChart.SendEvent("poisoned");
|
||||
|
||||
// Ends the round
|
||||
EndRound();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the drink cure button is pressed.
|
||||
/// </summary>
|
||||
private void OnDrinkCureButtonPressed()
|
||||
{
|
||||
// Here we use some custom-made extension methods from StateChartExt.cs to have a nicer API
|
||||
// that is specific to our game. This avoids having to use strings for property names and
|
||||
// event names and it also helps with type safety and when you need to find all places where
|
||||
// a certain property is set or an event is sent.
|
||||
_stateChart.SetPoisonCount(0);
|
||||
_stateChart.SendCuredEvent();
|
||||
|
||||
// Ends the round
|
||||
EndRound();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when the next round button is pressed.
|
||||
/// </summary>
|
||||
private void OnWaitButtonPressed()
|
||||
{
|
||||
// Ends the round
|
||||
EndRound();
|
||||
}
|
||||
|
||||
|
||||
private void EndRound()
|
||||
{
|
||||
// then send a "next_round" event
|
||||
_stateChart.SendEvent("next_round");
|
||||
// and finally call Step to calculate this round's effects, based on the current state
|
||||
_stateChart.Step();
|
||||
|
||||
// Then at the beginning of the next round, we reduce any poison count by 1
|
||||
_stateChart.SetPoisonCount( Mathf.Max(0, _stateChart.GetPoisonCount() - 1));
|
||||
|
||||
// And update the UI
|
||||
RefreshUi();
|
||||
}
|
||||
|
||||
private void OnPoisonedStateStepped()
|
||||
{
|
||||
// when we step while poisoned, remove the amount of poison from our health (but not below 0)
|
||||
_health = Mathf.Max(0, _health - _stateChart.GetPoisonCount());
|
||||
}
|
||||
|
||||
private void OnNormalStateStepped()
|
||||
{
|
||||
// when we step while not poisoned, heal 1 health, up to a maximum of 20
|
||||
_health = Mathf.Min(20, _health + 1);
|
||||
}
|
||||
|
||||
|
||||
private void RefreshUi()
|
||||
{
|
||||
_feelLabel.Text = $"Health: {_health} Poison: {_stateChart.GetPoisonCount()}";
|
||||
}
|
||||
|
||||
private void OnDebugButtonPressed()
|
||||
{
|
||||
// States have an "Active" property that can be used to check if they are currently active.
|
||||
// Note that you should usually not use this in your game code, as it sort of defeats the
|
||||
// purpose of using a state chart. But it can be useful for debugging.
|
||||
GD.Print("Are we poisoned? ", _poisonedStateChartState.Active ? "Yes" : "No");
|
||||
}
|
||||
|
||||
}
|
1
godot_state_charts_examples/csharp/CSharpExample.cs.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://cpw6fi5fyccic
|
9
godot_state_charts_examples/csharp/README.txt
Normal file
@ -0,0 +1,9 @@
|
||||
This example requires the .NET version of Godot to work. It will not work with the
|
||||
standard version of Godot. You can download the .NET version of Godot from
|
||||
https://godotengine.org/download. Note that the Steam version of Godot is the
|
||||
standard version and will not work with this example.
|
||||
|
||||
If you just freshly imported this into Godot and have not yet added other C# files
|
||||
to the project, you will need to initialize the project for C# by going to
|
||||
Project -> Tools -> C# -> Create C# Solution. Otherwise the demo will not
|
||||
work because its files have not been compiled.
|
27
godot_state_charts_examples/csharp/StateChartExt.cs
Normal file
@ -0,0 +1,27 @@
|
||||
|
||||
using GodotStateCharts;
|
||||
|
||||
namespace Movementtests.godot_state_charts_examples.csharp;
|
||||
|
||||
/// <summary>
|
||||
/// This is an example on how to add extension methods to the state chart class to get
|
||||
/// more type safety and a nicer API.
|
||||
/// </summary>
|
||||
// ReSharper disable once CheckNamespace
|
||||
public static class StateChartExt
|
||||
{
|
||||
public static void SetPoisonCount(this StateChart stateChart, int poisonCount)
|
||||
{
|
||||
stateChart.SetExpressionProperty("poison_count", poisonCount);
|
||||
}
|
||||
|
||||
public static int GetPoisonCount(this StateChart stateChart)
|
||||
{
|
||||
return stateChart.GetExpressionProperty("poison_count", 0);
|
||||
}
|
||||
|
||||
public static void SendCuredEvent(this StateChart stateChart)
|
||||
{
|
||||
stateChart.SendEvent("cured");
|
||||
}
|
||||
}
|
1
godot_state_charts_examples/csharp/StateChartExt.cs.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://btrfg0cn5wgrg
|
109
godot_state_charts_examples/csharp/csharp_example.tscn
Normal file
@ -0,0 +1,109 @@
|
||||
[gd_scene load_steps=9 format=3 uid="uid://dlxg641x8w8tn"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cpw6fi5fyccic" path="res://godot_state_charts_examples/csharp/CSharpExample.cs" id="1_fkf0f"]
|
||||
[ext_resource type="Script" uid="uid://couw105c3bde4" path="res://addons/godot_state_charts/state_chart.gd" id="2_b878w"]
|
||||
[ext_resource type="Script" uid="uid://jk2jm1g6q853" path="res://addons/godot_state_charts/compound_state.gd" id="3_ck7cw"]
|
||||
[ext_resource type="Script" uid="uid://cytafq8i1y8qm" path="res://addons/godot_state_charts/atomic_state.gd" id="4_ovkn7"]
|
||||
[ext_resource type="Script" uid="uid://cf1nsco3w0mf6" path="res://addons/godot_state_charts/transition.gd" id="5_um7g8"]
|
||||
[ext_resource type="Script" uid="uid://le5w1cm0ul8p" path="res://addons/godot_state_charts/expression_guard.gd" id="6_ecpvf"]
|
||||
[ext_resource type="PackedScene" uid="uid://bcwkugn6v3oy7" path="res://addons/godot_state_charts/utilities/state_chart_debugger.tscn" id="7_yrwaw"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_j6fet"]
|
||||
script = ExtResource("6_ecpvf")
|
||||
expression = "poison_count <= 0"
|
||||
|
||||
[node name="csharp_example" type="Node2D"]
|
||||
script = ExtResource("1_fkf0f")
|
||||
|
||||
[node name="InfoLabel" type="Label" parent="."]
|
||||
offset_left = 19.0
|
||||
offset_top = 33.0
|
||||
offset_right = 293.0
|
||||
offset_bottom = 111.0
|
||||
text = "This is a demo on how to use Godot State Charts with C#.
|
||||
We have a turn-based game here. You can click \"Drink Poison\" to ingest 3 poison. \"Drink Cure\" will clear all poison. Wait will just wait a round. At the end of each round poison is subtracted from health or health regenerates if no poison is in the system. Print Debug prints out whether we are currently poisoned."
|
||||
autowrap_mode = 2
|
||||
|
||||
[node name="FeelLabel" type="Label" parent="."]
|
||||
unique_name_in_owner = true
|
||||
offset_left = 23.0
|
||||
offset_top = 367.0
|
||||
offset_right = 63.0
|
||||
offset_bottom = 390.0
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
offset_left = 90.0
|
||||
offset_top = 407.0
|
||||
offset_right = 540.0
|
||||
offset_bottom = 447.0
|
||||
|
||||
[node name="DrinkPoisonButton" type="Button" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Drink Poison"
|
||||
|
||||
[node name="DrinkCureButton" type="Button" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Drink Cure"
|
||||
|
||||
[node name="WaitButton" type="Button" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Wait"
|
||||
|
||||
[node name="PrintDebugButton" type="Button" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Print Debug"
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
unique_name_in_owner = true
|
||||
script = ExtResource("2_b878w")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
script = ExtResource("3_ck7cw")
|
||||
initial_state = NodePath("Normal")
|
||||
|
||||
[node name="Normal" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("4_ovkn7")
|
||||
|
||||
[node name="To Poisoned" type="Node" parent="StateChart/Root/Normal"]
|
||||
script = ExtResource("5_um7g8")
|
||||
to = NodePath("../../Poisoned")
|
||||
event = &"poisoned"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Poisoned" type="Node" parent="StateChart/Root"]
|
||||
unique_name_in_owner = true
|
||||
script = ExtResource("4_ovkn7")
|
||||
|
||||
[node name="To Normal On Wear Off" type="Node" parent="StateChart/Root/Poisoned"]
|
||||
editor_description = "This transition checks at the beginning of the round i the poison count is 0 and if so transitions back to normal state."
|
||||
script = ExtResource("5_um7g8")
|
||||
to = NodePath("../../Normal")
|
||||
event = &"next_round"
|
||||
guard = SubResource("Resource_j6fet")
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="To Normal On Cure" type="Node" parent="StateChart/Root/Poisoned"]
|
||||
editor_description = "This transition immediately goes back to normal state when the cure is taken."
|
||||
script = ExtResource("5_um7g8")
|
||||
to = NodePath("../../Normal")
|
||||
event = &"cured"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="StateChartDebugger" parent="." instance=ExtResource("7_yrwaw")]
|
||||
offset_left = 309.0
|
||||
offset_top = 4.0
|
||||
offset_right = 636.0
|
||||
offset_bottom = 370.0
|
||||
initial_node_to_watch = NodePath("../StateChart")
|
||||
|
||||
[connection signal="pressed" from="HBoxContainer/DrinkPoisonButton" to="." method="OnDrinkPoisonButtonPressed"]
|
||||
[connection signal="pressed" from="HBoxContainer/DrinkCureButton" to="." method="OnDrinkCureButtonPressed"]
|
||||
[connection signal="pressed" from="HBoxContainer/WaitButton" to="." method="OnWaitButtonPressed"]
|
||||
[connection signal="pressed" from="HBoxContainer/PrintDebugButton" to="." method="OnDebugButtonPressed"]
|
||||
[connection signal="state_stepped" from="StateChart/Root/Normal" to="." method="OnNormalStateStepped"]
|
||||
[connection signal="state_stepped" from="StateChart/Root/Poisoned" to="." method="OnPoisonedStateStepped"]
|
11
godot_state_charts_examples/history_states/history_demo.gd
Normal file
@ -0,0 +1,11 @@
|
||||
extends Node
|
||||
|
||||
@onready var state_chart:StateChart = $StateChart
|
||||
|
||||
func _on_area_2d_input_event(_viewport:Node, event:InputEvent, _shape_idx:int):
|
||||
if event is InputEventMouseButton:
|
||||
if event.button_index == MOUSE_BUTTON_LEFT:
|
||||
# on release send clicked event to state chart
|
||||
if not event.is_pressed():
|
||||
state_chart.send_event("clicked")
|
||||
|
@ -0,0 +1 @@
|
||||
uid://bad613wfktgah
|
102
godot_state_charts_examples/history_states/history_demo.tscn
Normal file
@ -0,0 +1,102 @@
|
||||
[gd_scene load_steps=11 format=3 uid="uid://b18rv6o4duide"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bgw8xgbwc2flx" path="res://godot_state_charts_examples/history_states/white_rectangle.svg" id="1_3v23e"]
|
||||
[ext_resource type="PackedScene" uid="uid://bcwkugn6v3oy7" path="res://addons/godot_state_charts/utilities/state_chart_debugger.tscn" id="2_fgw1q"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="2_pqmip"]
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/history_states/history_demo.gd" id="2_vphtk"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="3_nsw2j"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/history_state.gd" id="4_0qaqv"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="5_lh5sp"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="6_xvm5g"]
|
||||
[ext_resource type="Theme" uid="uid://s2bj74tt0y7f" path="res://godot_state_charts_examples/new_theme.tres" id="8_najew"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_kl3ga"]
|
||||
size = Vector2(34.243, 33.536)
|
||||
|
||||
[node name="Node" type="Node"]
|
||||
script = ExtResource("2_vphtk")
|
||||
|
||||
[node name="StateChartDebugger" parent="." instance=ExtResource("2_fgw1q")]
|
||||
offset_left = 280.0
|
||||
offset_top = 9.0
|
||||
offset_right = -12.0
|
||||
offset_bottom = -190.0
|
||||
theme = ExtResource("8_najew")
|
||||
initial_node_to_watch = NodePath("../StateChart")
|
||||
|
||||
[node name="Node2D" type="Sprite2D" parent="."]
|
||||
position = Vector2(145, 206)
|
||||
scale = Vector2(6.6875, 3.90625)
|
||||
texture = ExtResource("1_3v23e")
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="Node2D"]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Node2D/Area2D"]
|
||||
position = Vector2(0.0747795, 3.8147e-06)
|
||||
shape = SubResource("RectangleShape2D_kl3ga")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
script = ExtResource("2_pqmip")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
script = ExtResource("3_nsw2j")
|
||||
initial_state = NodePath("Red Or Blue")
|
||||
|
||||
[node name="Red Or Blue" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("3_nsw2j")
|
||||
initial_state = NodePath("Red")
|
||||
|
||||
[node name="Resume" type="Node" parent="StateChart/Root/Red Or Blue"]
|
||||
script = ExtResource("4_0qaqv")
|
||||
default_state = NodePath("../Red")
|
||||
|
||||
[node name="Red" type="Node" parent="StateChart/Root/Red Or Blue"]
|
||||
script = ExtResource("5_lh5sp")
|
||||
|
||||
[node name="To Blue" type="Node" parent="StateChart/Root/Red Or Blue/Red"]
|
||||
script = ExtResource("6_xvm5g")
|
||||
to = NodePath("../../Blue")
|
||||
delay_in_seconds = "3"
|
||||
|
||||
[node name="Blue" type="Node" parent="StateChart/Root/Red Or Blue"]
|
||||
script = ExtResource("5_lh5sp")
|
||||
|
||||
[node name="To Red" type="Node" parent="StateChart/Root/Red Or Blue/Blue"]
|
||||
script = ExtResource("6_xvm5g")
|
||||
to = NodePath("../../Red")
|
||||
delay_in_seconds = "3"
|
||||
|
||||
[node name="On Clicked To White" type="Node" parent="StateChart/Root/Red Or Blue"]
|
||||
script = ExtResource("6_xvm5g")
|
||||
to = NodePath("../../White")
|
||||
event = &"clicked"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="White" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("5_lh5sp")
|
||||
|
||||
[node name="Resume" type="Node" parent="StateChart/Root/White"]
|
||||
script = ExtResource("6_xvm5g")
|
||||
to = NodePath("../../Red Or Blue/Resume")
|
||||
delay_in_seconds = "1"
|
||||
|
||||
[node name="Label" type="RichTextLabel" parent="."]
|
||||
offset_left = 26.0
|
||||
offset_top = 318.0
|
||||
offset_right = 376.0
|
||||
offset_bottom = 416.0
|
||||
mouse_filter = 2
|
||||
bbcode_enabled = true
|
||||
text = "[font_size=10]
|
||||
[ul]
|
||||
The rectangle will switch from red to blue every 3 seconds.
|
||||
When you click the rectangle it will temporarily turn white and then return to whatever color it was previously by transitioning to the \"Resume\" state. The timer will also be properly restored, so the previously active color will remain active for the rest of the 5 seconds.
|
||||
[/ul]
|
||||
[/font_size]"
|
||||
fit_content = true
|
||||
|
||||
[connection signal="input_event" from="Node2D/Area2D" to="." method="_on_area_2d_input_event"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Red Or Blue/Red" to="Node2D" method="set_modulate" binds= [Color(1, 0.231373, 0.172549, 1)]]
|
||||
[connection signal="state_entered" from="StateChart/Root/Red Or Blue/Blue" to="Node2D" method="set_modulate" binds= [Color(0.286275, 0.501961, 1, 1)]]
|
||||
[connection signal="state_entered" from="StateChart/Root/White" to="Node2D" method="set_modulate" binds= [Color(1, 1, 1, 1)]]
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<rect id="Artboard1" x="0" y="0" width="32" height="32" style="fill:none;"/>
|
||||
<clipPath id="_clip1">
|
||||
<rect id="Artboard11" serif:id="Artboard1" x="0" y="0" width="32" height="32"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip1)">
|
||||
<g transform="matrix(1.018,0,0,1.02155,-0.335834,-0.355613)">
|
||||
<rect x="0.33" y="0.348" width="31.434" height="31.325" style="fill:rgb(235,235,235);"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 888 B |
@ -0,0 +1,37 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bgw8xgbwc2flx"
|
||||
path="res://.godot/imported/white_rectangle.svg-4d0041e2d5db811b29367f0371ead08c.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/history_states/white_rectangle.svg"
|
||||
dest_files=["res://.godot/imported/white_rectangle.svg-4d0041e2d5db811b29367f0371ead08c.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
|
||||
svg/scale=1.0
|
||||
editor/scale_with_editor_scale=false
|
||||
editor/convert_colors_with_editor_theme=false
|
4
godot_state_charts_examples/new_theme.tres
Normal file
@ -0,0 +1,4 @@
|
||||
[gd_resource type="Theme" format=3 uid="uid://s2bj74tt0y7f"]
|
||||
|
||||
[resource]
|
||||
default_font_size = 10
|
106
godot_state_charts_examples/order_of_events/order_of_events.tscn
Normal file
@ -0,0 +1,106 @@
|
||||
[gd_scene load_steps=7 format=3 uid="uid://qr4pvbbdopme"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="1_67wci"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="2_oks48"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/parallel_state.gd" id="3_p72eh"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="4_v7oq1"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="5_qwp21"]
|
||||
[ext_resource type="PackedScene" uid="uid://bcwkugn6v3oy7" path="res://addons/godot_state_charts/utilities/state_chart_debugger.tscn" id="5_xychp"]
|
||||
|
||||
[node name="order_of_events" type="Node2D"]
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
editor_description = "This is just an example state chart to complement the documentation. See the section \"order of events\" in the manual for details."
|
||||
script = ExtResource("1_67wci")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="A" type="Node" parent="StateChart"]
|
||||
script = ExtResource("2_oks48")
|
||||
initial_state = NodePath("B")
|
||||
|
||||
[node name="B" type="Node" parent="StateChart/A"]
|
||||
script = ExtResource("3_p72eh")
|
||||
|
||||
[node name="B1" type="Node" parent="StateChart/A/B"]
|
||||
script = ExtResource("4_v7oq1")
|
||||
|
||||
[node name="B2" type="Node" parent="StateChart/A/B"]
|
||||
script = ExtResource("4_v7oq1")
|
||||
|
||||
[node name="To C" type="Node" parent="StateChart/A/B"]
|
||||
script = ExtResource("5_qwp21")
|
||||
to = NodePath("../../C")
|
||||
event = &"c_button_pressed"
|
||||
|
||||
[node name="C" type="Node" parent="StateChart/A"]
|
||||
script = ExtResource("2_oks48")
|
||||
initial_state = NodePath("C1")
|
||||
|
||||
[node name="C1" type="Node" parent="StateChart/A/C"]
|
||||
script = ExtResource("4_v7oq1")
|
||||
|
||||
[node name="Immediately To C2" type="Node" parent="StateChart/A/C/C1"]
|
||||
editor_description = "This transition will immediately transition this state to the C2 state."
|
||||
script = ExtResource("5_qwp21")
|
||||
to = NodePath("../../C2")
|
||||
|
||||
[node name="C2" type="Node" parent="StateChart/A/C"]
|
||||
editor_description = "This state has it's state_entered signal connected. The receiver of this signal will immediately trigger the \"To C3\" transition below."
|
||||
script = ExtResource("4_v7oq1")
|
||||
|
||||
[node name="To C3" type="Node" parent="StateChart/A/C/C2"]
|
||||
editor_description = "This transition will be called by a signal receiver connected to C2's `state_entered` signal. It will be triggered immediately when C2 is entered."
|
||||
script = ExtResource("5_qwp21")
|
||||
to = NodePath("../../C3")
|
||||
event = &"c2_entered"
|
||||
|
||||
[node name="C3" type="Node" parent="StateChart/A/C"]
|
||||
script = ExtResource("4_v7oq1")
|
||||
|
||||
[node name="To C4 after delay" type="Node" parent="StateChart/A/C/C3"]
|
||||
editor_description = "Another automatic transition, this time with a delay."
|
||||
script = ExtResource("5_qwp21")
|
||||
to = NodePath("../../C4")
|
||||
delay_seconds = 0.5
|
||||
|
||||
[node name="C4" type="Node" parent="StateChart/A/C"]
|
||||
script = ExtResource("4_v7oq1")
|
||||
|
||||
[node name="To B" type="Node" parent="StateChart/A/C/C4"]
|
||||
script = ExtResource("5_qwp21")
|
||||
to = NodePath("../../../B")
|
||||
event = &"b_button_pressed"
|
||||
|
||||
[node name="StateChartDebugger" parent="." instance=ExtResource("5_xychp")]
|
||||
offset_left = 201.0
|
||||
offset_top = 11.0
|
||||
offset_right = 627.0
|
||||
offset_bottom = 450.0
|
||||
initial_node_to_watch = NodePath("../StateChart")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
offset_left = 18.0
|
||||
offset_top = 16.0
|
||||
offset_right = 174.0
|
||||
offset_bottom = 444.0
|
||||
|
||||
[node name="To C Button" type="Button" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Go To C"
|
||||
|
||||
[node name="To B Button" type="Button" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Go To B"
|
||||
|
||||
[node name="Spacer" type="Control" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="Label" type="Label" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "This demo shows the order of events when states are changing under various conditions. See the \"Order of events\" section in the manual for some explainers."
|
||||
autowrap_mode = 2
|
||||
|
||||
[connection signal="state_entered" from="StateChart/A/C/C2" to="StateChart" method="send_event" binds= ["c2_entered"]]
|
||||
[connection signal="pressed" from="VBoxContainer/To C Button" to="StateChart" method="send_event" binds= ["c_button_pressed"]]
|
||||
[connection signal="pressed" from="VBoxContainer/To B Button" to="StateChart" method="send_event" binds= ["b_button_pressed"]]
|
@ -0,0 +1,23 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bddhmoj1g5lv3"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://berg2d0lm33m0" path="res://godot_state_charts_examples/performance_test/ten_state_charts.tscn" id="1_djj1b"]
|
||||
|
||||
[node name="hundred_state_charts" type="Node2D"]
|
||||
|
||||
[node name="ten_state_charts" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts2" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts3" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts4" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts5" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts6" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts7" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts8" parent="." instance=ExtResource("1_djj1b")]
|
||||
|
||||
[node name="ten_state_charts9" parent="." instance=ExtResource("1_djj1b")]
|
@ -0,0 +1,36 @@
|
||||
[gd_scene load_steps=6 format=3 uid="uid://b8rr57grye1kw"]
|
||||
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/performance_test/state_chart_receiver.gd" id="1_44fbg"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="1_x4how"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="2_2eb2m"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="3_qtc2o"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="4_ue85n"]
|
||||
|
||||
[node name="state_chart" type="Node2D"]
|
||||
script = ExtResource("1_44fbg")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
script = ExtResource("1_x4how")
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
script = ExtResource("2_2eb2m")
|
||||
initial_state = NodePath("A")
|
||||
|
||||
[node name="A" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("3_qtc2o")
|
||||
|
||||
[node name="To B" type="Node" parent="StateChart/Root/A"]
|
||||
script = ExtResource("4_ue85n")
|
||||
to = NodePath("../../B")
|
||||
delay_seconds = 10.0
|
||||
|
||||
[node name="B" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("3_qtc2o")
|
||||
|
||||
[node name="To A" type="Node" parent="StateChart/Root/B"]
|
||||
script = ExtResource("4_ue85n")
|
||||
to = NodePath("../../A")
|
||||
delay_seconds = 20.0
|
||||
|
||||
[connection signal="state_processing" from="StateChart/Root/A" to="." method="_on_a_state_processing"]
|
||||
[connection signal="state_physics_processing" from="StateChart/Root/B" to="." method="_on_b_state_physics_processing"]
|
@ -0,0 +1,12 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
|
||||
func _on_a_state_processing(_delta):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
func _on_b_state_physics_processing(_delta):
|
||||
pass
|
@ -0,0 +1 @@
|
||||
uid://bv6xx4hxfew5j
|
@ -0,0 +1,25 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://berg2d0lm33m0"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://b8rr57grye1kw" path="res://godot_state_charts_examples/performance_test/state_chart.tscn" id="1_sc64n"]
|
||||
|
||||
[node name="ten_state_charts" type="Node2D"]
|
||||
|
||||
[node name="state_chart" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart2" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart3" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart4" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart5" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart6" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart7" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart8" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart9" parent="." instance=ExtResource("1_sc64n")]
|
||||
|
||||
[node name="state_chart10" parent="." instance=ExtResource("1_sc64n")]
|
@ -0,0 +1,23 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://byh6mcqhp6ky2"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bddhmoj1g5lv3" path="res://godot_state_charts_examples/performance_test/hundred_state_charts.tscn" id="1_1oume"]
|
||||
|
||||
[node name="thousand_state_charts" type="Node2D"]
|
||||
|
||||
[node name="hundred_state_charts" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts2" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts3" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts4" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts5" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts6" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts7" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts8" parent="." instance=ExtResource("1_1oume")]
|
||||
|
||||
[node name="hundred_state_charts9" parent="." instance=ExtResource("1_1oume")]
|
BIN
godot_state_charts_examples/platformer/breaking_box/break.png
Normal file
After Width: | Height: | Size: 635 B |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://p8vbysdruo4o"
|
||||
path="res://.godot/imported/break.png-76e3da8567a2ce2ef66cf2a31e3edc5e.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/breaking_box/break.png"
|
||||
dest_files=["res://.godot/imported/break.png-76e3da8567a2ce2ef66cf2a31e3edc5e.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,54 @@
|
||||
extends StaticBody2D
|
||||
|
||||
signal clicked(node)
|
||||
|
||||
@export var health:int = 3
|
||||
@onready var _state_chart:StateChart = %StateChart
|
||||
@onready var _label:Label = %Label
|
||||
@onready var _detection_shape = %CollisionShape2D
|
||||
@onready var _animation_player = %AnimationPlayer
|
||||
|
||||
func _ready():
|
||||
_label.text = str(health)
|
||||
|
||||
|
||||
func _on_idle_state_entered():
|
||||
# When we enter idle state we play the idle animation
|
||||
_animation_player.play("Idle")
|
||||
|
||||
|
||||
func _on_detection_area_body_entered(_body):
|
||||
# When someone enters the area, reduce the health
|
||||
# and notify the state chart.
|
||||
health = max(0, health-1)
|
||||
_label.text = str(health)
|
||||
_state_chart.set_expression_property("health", health)
|
||||
_state_chart.send_event("health_changed")
|
||||
|
||||
|
||||
func _on_blinking_state_entered():
|
||||
# when we enter blinking state, play the hit animation
|
||||
_animation_player.play("Hit")
|
||||
|
||||
|
||||
func _on_dying_state_entered():
|
||||
# When we enter dying state, play the final death animation
|
||||
_animation_player.play("Break")
|
||||
|
||||
|
||||
func _on_dead_state_entered():
|
||||
# When we enter dead state, we're done and can free the node.
|
||||
queue_free()
|
||||
|
||||
|
||||
func _on_animation_player_animation_finished(_anim_name):
|
||||
# Forward animation_finished events to the state chart
|
||||
_state_chart.send_event("animation_finished")
|
||||
|
||||
|
||||
# This is to make the box clickable. Clicking it will show it in the debugger.
|
||||
func _on_input_event(_viewport, event, _shape_idx):
|
||||
# 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://b7gcoyovuxkvo
|
@ -0,0 +1,425 @@
|
||||
[gd_scene load_steps=19 format=3 uid="uid://h0af1dot82p3"]
|
||||
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/platformer/breaking_box/breaking_box.gd" id="1_c2rh2"]
|
||||
[ext_resource type="Texture2D" uid="uid://c5dogybcf6yfo" path="res://godot_state_charts_examples/platformer/breaking_box/idle.png" id="1_dixph"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="2_atynw"]
|
||||
[ext_resource type="Texture2D" uid="uid://dq0ww6xvgeap3" path="res://godot_state_charts_examples/platformer/breaking_box/hit.png" id="3_ngvxc"]
|
||||
[ext_resource type="Texture2D" uid="uid://p8vbysdruo4o" path="res://godot_state_charts_examples/platformer/breaking_box/break.png" id="4_jb7vf"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="5_wouwd"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="6_p4jwe"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="7_1ecad"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/expression_guard.gd" id="8_8riiw"]
|
||||
|
||||
[sub_resource type="Animation" id="Animation_toibu"]
|
||||
resource_name = "Break"
|
||||
length = 0.3
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("BoxSprite:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("4_jb7vf")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("BoxSprite:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [4]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("BoxSprite:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(16.5643, 1),
|
||||
"update": 0,
|
||||
"values": [0, 3]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("Label:visible")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [false]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("BoxCollider:disabled")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("BoxSprite:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 8.87654),
|
||||
"update": 0,
|
||||
"values": [Vector2(0, -10), Vector2(0, 50)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("BoxSprite:modulate:a")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [1.0, 0.0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_rc67x"]
|
||||
resource_name = "Hit"
|
||||
length = 0.2
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("BoxSprite:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("3_ngvxc")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("BoxSprite:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [2]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("BoxSprite:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 1,
|
||||
"values": [0, 1]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("Label:visible")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [false]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_yu346"]
|
||||
resource_name = "Idle"
|
||||
length = 0.1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("BoxSprite:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("1_dixph")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("BoxSprite:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [1]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("BoxSprite:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [0]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("Label:visible")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("BoxCollider:disabled")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [false]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_a7q8m"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("BoxSprite:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("1_dixph")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("BoxSprite:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [1]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("BoxSprite:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [0]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("Label:visible")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
tracks/4/type = "value"
|
||||
tracks/4/imported = false
|
||||
tracks/4/enabled = true
|
||||
tracks/4/path = NodePath("BoxCollider:disabled")
|
||||
tracks/4/interp = 1
|
||||
tracks/4/loop_wrap = true
|
||||
tracks/4/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [false]
|
||||
}
|
||||
tracks/5/type = "value"
|
||||
tracks/5/imported = false
|
||||
tracks/5/enabled = true
|
||||
tracks/5/path = NodePath("BoxSprite:position")
|
||||
tracks/5/interp = 1
|
||||
tracks/5/loop_wrap = true
|
||||
tracks/5/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(0, -10)]
|
||||
}
|
||||
tracks/6/type = "value"
|
||||
tracks/6/imported = false
|
||||
tracks/6/enabled = true
|
||||
tracks/6/path = NodePath("BoxSprite:modulate")
|
||||
tracks/6/interp = 1
|
||||
tracks/6/loop_wrap = true
|
||||
tracks/6/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Color(1, 1, 1, 1)]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_t7nrw"]
|
||||
_data = {
|
||||
"Break": SubResource("Animation_toibu"),
|
||||
"Hit": SubResource("Animation_rc67x"),
|
||||
"Idle": SubResource("Animation_yu346"),
|
||||
"RESET": SubResource("Animation_a7q8m")
|
||||
}
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_8vd2b"]
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_jbwph"]
|
||||
size = Vector2(14.5, 2)
|
||||
|
||||
[sub_resource type="Resource" id="Resource_v858x"]
|
||||
script = ExtResource("8_8riiw")
|
||||
expression = "health > 0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_j86i4"]
|
||||
script = ExtResource("8_8riiw")
|
||||
expression = "health <= 0"
|
||||
|
||||
[node name="BreakingBox" type="StaticBody2D"]
|
||||
input_pickable = true
|
||||
script = ExtResource("1_c2rh2")
|
||||
|
||||
[node name="BoxSprite" type="Sprite2D" parent="."]
|
||||
texture_filter = 1
|
||||
position = Vector2(0, -10)
|
||||
texture = ExtResource("1_dixph")
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
unique_name_in_owner = true
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -20.0
|
||||
offset_top = -23.0
|
||||
offset_right = 20.0
|
||||
offset_bottom = 3.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_font_sizes/font_size = 10
|
||||
text = "3"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
unique_name_in_owner = true
|
||||
editor_description = "The animation player will send an \"animation_finished\" event back to the state chart. This will then take the appropriate transitions (e.g. switch back to the idle animation)."
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_t7nrw")
|
||||
}
|
||||
|
||||
[node name="BoxCollider" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(0, -10)
|
||||
shape = SubResource("RectangleShape2D_8vd2b")
|
||||
|
||||
[node name="DetectionArea" type="Area2D" parent="."]
|
||||
position = Vector2(0, -3)
|
||||
collision_layer = 0
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="DetectionArea"]
|
||||
unique_name_in_owner = true
|
||||
position = Vector2(0, -19)
|
||||
shape = SubResource("RectangleShape2D_jbwph")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
unique_name_in_owner = true
|
||||
script = ExtResource("2_atynw")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
script = ExtResource("5_wouwd")
|
||||
initial_state = NodePath("Idle")
|
||||
|
||||
[node name="Idle" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("6_p4jwe")
|
||||
|
||||
[node name="On Damage" type="Node" parent="StateChart/Root/Idle"]
|
||||
script = ExtResource("7_1ecad")
|
||||
to = NodePath("../../Blinking")
|
||||
event = &"health_changed"
|
||||
guard = SubResource("Resource_v858x")
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="On Break" type="Node" parent="StateChart/Root/Idle"]
|
||||
script = ExtResource("7_1ecad")
|
||||
to = NodePath("../../Dying")
|
||||
event = &"health_changed"
|
||||
guard = SubResource("Resource_j86i4")
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Blinking" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("6_p4jwe")
|
||||
|
||||
[node name="Animation Finished" type="Node" parent="StateChart/Root/Blinking"]
|
||||
script = ExtResource("7_1ecad")
|
||||
to = NodePath("../../Idle")
|
||||
event = &"animation_finished"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Dying" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("6_p4jwe")
|
||||
|
||||
[node name="Animation Finished" type="Node" parent="StateChart/Root/Dying"]
|
||||
script = ExtResource("7_1ecad")
|
||||
to = NodePath("../../Dead")
|
||||
event = &"animation_finished"
|
||||
delay_in_seconds = "0.0"
|
||||
|
||||
[node name="Dead" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("6_p4jwe")
|
||||
|
||||
[connection signal="input_event" from="." to="." method="_on_input_event"]
|
||||
[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_player_animation_finished"]
|
||||
[connection signal="body_entered" from="DetectionArea" to="." method="_on_detection_area_body_entered"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Idle" to="." method="_on_idle_state_entered"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Blinking" to="." method="_on_blinking_state_entered"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Dying" to="." method="_on_dying_state_entered"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Dead" to="." method="_on_dead_state_entered"]
|
BIN
godot_state_charts_examples/platformer/breaking_box/hit.png
Normal file
After Width: | Height: | Size: 454 B |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dq0ww6xvgeap3"
|
||||
path="res://.godot/imported/hit.png-1c36fd330c418d67632dbaced016a36f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/breaking_box/hit.png"
|
||||
dest_files=["res://.godot/imported/hit.png-1c36fd330c418d67632dbaced016a36f.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
|
BIN
godot_state_charts_examples/platformer/breaking_box/idle.png
Normal file
After Width: | Height: | Size: 406 B |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c5dogybcf6yfo"
|
||||
path="res://.godot/imported/idle.png-ceff55276331d87b08aa0aee62d3e6af.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/breaking_box/idle.png"
|
||||
dest_files=["res://.godot/imported/idle.png-ceff55276331d87b08aa0aee62d3e6af.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,36 @@
|
||||
extends Node2D
|
||||
|
||||
## emitted when this checkpoint is clicked with the mouse
|
||||
signal clicked(checkpoint:Node2D)
|
||||
|
||||
## emitted when this checkpoint is activated
|
||||
signal activated(checkpoint:Node2D)
|
||||
|
||||
## emitted when this checkpoint is deactivated
|
||||
signal deactivated(checkpoint:Node2D)
|
||||
|
||||
@onready var _state_chart:StateChart = get_node("StateChart")
|
||||
|
||||
|
||||
func _on_area_2d_input_event(_viewport:Node, event:InputEvent, _shape_idx:int):
|
||||
# if event was left mouse button up, emit clicked signal
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.is_pressed() == false:
|
||||
# print("Checkpoint clicked")
|
||||
clicked.emit(self)
|
||||
|
||||
|
||||
func _on_area_2d_body_entered(body:Node2D):
|
||||
if body.is_in_group("player"):
|
||||
_state_chart.send_event("player_entered")
|
||||
|
||||
|
||||
func _on_area_2d_body_exited(body:Node2D):
|
||||
if body.is_in_group("player"):
|
||||
_state_chart.send_event("player_exited")
|
||||
|
||||
|
||||
func emit_activated():
|
||||
activated.emit(self)
|
||||
|
||||
func emit_deactivated():
|
||||
deactivated.emit(self)
|
@ -0,0 +1 @@
|
||||
uid://ccsukp7vuknqs
|
@ -0,0 +1,343 @@
|
||||
[gd_scene load_steps=19 format=3 uid="uid://b22lg10c7wxrq"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://4nlen5j7etvq" path="res://godot_state_charts_examples/platformer/checkpoint/checkpoint_no_flag.png" id="1_7vf2w"]
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/platformer/checkpoint/checkpoint.gd" id="1_jot5v"]
|
||||
[ext_resource type="Texture2D" uid="uid://dfju87f6rw0nm" path="res://godot_state_charts_examples/platformer/checkpoint/checkpoint_idle.png" id="2_ns71f"]
|
||||
[ext_resource type="Texture2D" uid="uid://beoe1hh5aggor" path="res://godot_state_charts_examples/platformer/checkpoint/checkpoint_flag_out.png" id="3_fbg27"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="5_a58ma"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/parallel_state.gd" id="6_53g38"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="6_qkwqk"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="7_a74k1"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="8_7tjvh"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_is_active_guard.gd" id="10_fk2fi"]
|
||||
|
||||
[sub_resource type="Animation" id="Animation_xvggk"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Sprite2D:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("1_7vf2w")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Sprite2D:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [1]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("Sprite2D:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_p66ga"]
|
||||
resource_name = "close_flag"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Sprite2D:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("3_fbg27")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Sprite2D:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [26]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("Sprite2D:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 1),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [25, 0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_w48c8"]
|
||||
resource_name = "idle_no_flag"
|
||||
length = 0.1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Sprite2D:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("1_7vf2w")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Sprite2D:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [1]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("Sprite2D:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_judeo"]
|
||||
resource_name = "idle_with_flag"
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Sprite2D:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("2_ns71f")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Sprite2D:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [10]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("Sprite2D:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 1),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [0, 9]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_gr2w7"]
|
||||
resource_name = "open_flag"
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Sprite2D:texture")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [ExtResource("3_fbg27")]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Sprite2D:hframes")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [26]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("Sprite2D:frame")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0, 1),
|
||||
"transitions": PackedFloat32Array(1, 1),
|
||||
"update": 0,
|
||||
"values": [0, 25]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_5pqa5"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_xvggk"),
|
||||
"close_flag": SubResource("Animation_p66ga"),
|
||||
"idle_no_flag": SubResource("Animation_w48c8"),
|
||||
"idle_with_flag": SubResource("Animation_judeo"),
|
||||
"open_flag": SubResource("Animation_gr2w7")
|
||||
}
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_06im6"]
|
||||
radius = 18.445
|
||||
height = 59.4
|
||||
|
||||
[sub_resource type="Resource" id="Resource_22wfi"]
|
||||
script = ExtResource("10_fk2fi")
|
||||
state = NodePath("../../../../Player Presence/Absent")
|
||||
metadata/_editor_prop_ptr_state = NodePath("../../../Player Presence/Absent")
|
||||
|
||||
[node name="Checkpoint" type="Node2D"]
|
||||
script = ExtResource("1_jot5v")
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture_filter = 1
|
||||
texture = ExtResource("1_7vf2w")
|
||||
offset = Vector2(0, -32)
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_5pqa5")
|
||||
}
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
position = Vector2(-2, -26)
|
||||
shape = SubResource("CapsuleShape2D_06im6")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
script = ExtResource("5_a58ma")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
script = ExtResource("6_53g38")
|
||||
|
||||
[node name="Player Presence" type="Node" parent="StateChart/Root"]
|
||||
editor_description = "This compound state represents whether the player is currently present at the checkpoint."
|
||||
script = ExtResource("6_qkwqk")
|
||||
initial_state = NodePath("Absent")
|
||||
|
||||
[node name="Absent" type="Node" parent="StateChart/Root/Player Presence"]
|
||||
script = ExtResource("7_a74k1")
|
||||
|
||||
[node name="On Player Enter" type="Node" parent="StateChart/Root/Player Presence/Absent"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Present")
|
||||
event = &"player_entered"
|
||||
|
||||
[node name="Present" type="Node" parent="StateChart/Root/Player Presence"]
|
||||
script = ExtResource("7_a74k1")
|
||||
|
||||
[node name="On Player Exit" type="Node" parent="StateChart/Root/Player Presence/Present"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Absent")
|
||||
event = &"player_exited"
|
||||
|
||||
[node name="Animation Control" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("6_qkwqk")
|
||||
initial_state = NodePath("Idle")
|
||||
|
||||
[node name="Idle" type="Node" parent="StateChart/Root/Animation Control"]
|
||||
script = ExtResource("7_a74k1")
|
||||
|
||||
[node name="On Player Enter" type="Node" parent="StateChart/Root/Animation Control/Idle"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Expanding")
|
||||
event = &"player_entered"
|
||||
|
||||
[node name="Expanding" type="Node" parent="StateChart/Root/Animation Control"]
|
||||
script = ExtResource("7_a74k1")
|
||||
|
||||
[node name="After 1 s" type="Node" parent="StateChart/Root/Animation Control/Expanding"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Activated/Expanded")
|
||||
delay_seconds = 0.9
|
||||
|
||||
[node name="Activated" type="Node" parent="StateChart/Root/Animation Control"]
|
||||
script = ExtResource("6_qkwqk")
|
||||
initial_state = NodePath("Expanded")
|
||||
|
||||
[node name="Expanded" type="Node" parent="StateChart/Root/Animation Control/Activated"]
|
||||
script = ExtResource("7_a74k1")
|
||||
|
||||
[node name="Immediately" type="Node" parent="StateChart/Root/Animation Control/Activated/Expanded"]
|
||||
editor_description = "Immediately go to the retracting state when the player is no longer present when entering this state."
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Waiting To Retract")
|
||||
guard = SubResource("Resource_22wfi")
|
||||
|
||||
[node name="On Player Leave" type="Node" parent="StateChart/Root/Animation Control/Activated/Expanded"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Waiting To Retract")
|
||||
event = &"player_exited"
|
||||
|
||||
[node name="Waiting To Retract" type="Node" parent="StateChart/Root/Animation Control/Activated"]
|
||||
script = ExtResource("7_a74k1")
|
||||
|
||||
[node name="After 5 s" type="Node" parent="StateChart/Root/Animation Control/Activated/Waiting To Retract"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../../Retracting")
|
||||
delay_seconds = 5.0
|
||||
|
||||
[node name="On Player Enter" type="Node" parent="StateChart/Root/Animation Control/Activated/Waiting To Retract"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Expanded")
|
||||
event = &"player_entered"
|
||||
|
||||
[node name="Retracting" type="Node" parent="StateChart/Root/Animation Control"]
|
||||
script = ExtResource("7_a74k1")
|
||||
|
||||
[node name="After 1 s" type="Node" parent="StateChart/Root/Animation Control/Retracting"]
|
||||
script = ExtResource("8_7tjvh")
|
||||
to = NodePath("../../Idle")
|
||||
delay_seconds = 0.9
|
||||
|
||||
[connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"]
|
||||
[connection signal="body_exited" from="Area2D" to="." method="_on_area_2d_body_exited"]
|
||||
[connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Animation Control/Idle" to="AnimationPlayer" method="play" binds= ["idle_no_flag"]]
|
||||
[connection signal="state_entered" from="StateChart/Root/Animation Control/Expanding" to="AnimationPlayer" method="play" binds= ["open_flag"]]
|
||||
[connection signal="state_entered" from="StateChart/Root/Animation Control/Activated" to="." method="emit_activated"]
|
||||
[connection signal="state_exited" from="StateChart/Root/Animation Control/Activated" to="." method="emit_deactivated"]
|
||||
[connection signal="state_entered" from="StateChart/Root/Animation Control/Activated/Expanded" to="AnimationPlayer" method="play" binds= ["idle_with_flag"]]
|
||||
[connection signal="state_entered" from="StateChart/Root/Animation Control/Retracting" to="AnimationPlayer" method="play" binds= ["close_flag"]]
|
After Width: | Height: | Size: 3.3 KiB |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://beoe1hh5aggor"
|
||||
path="res://.godot/imported/checkpoint_flag_out.png-d1302c67d10e0b187eb8c484888649f3.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/checkpoint/checkpoint_flag_out.png"
|
||||
dest_files=["res://.godot/imported/checkpoint_flag_out.png-d1302c67d10e0b187eb8c484888649f3.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
|
After Width: | Height: | Size: 1.8 KiB |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dfju87f6rw0nm"
|
||||
path="res://.godot/imported/checkpoint_idle.png-450aa64af9f9812b4e2bfc351c4acc23.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/checkpoint/checkpoint_idle.png"
|
||||
dest_files=["res://.godot/imported/checkpoint_idle.png-450aa64af9f9812b4e2bfc351c4acc23.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
|
After Width: | Height: | Size: 530 B |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://4nlen5j7etvq"
|
||||
path="res://.godot/imported/checkpoint_no_flag.png-439157dcb5eca60e80049ff3b7e7a879.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/checkpoint/checkpoint_no_flag.png"
|
||||
dest_files=["res://.godot/imported/checkpoint_no_flag.png-439157dcb5eca60e80049ff3b7e7a879.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
|
BIN
godot_state_charts_examples/platformer/fireworks_box/box.png
Normal file
After Width: | Height: | Size: 399 B |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://roilgifkgiii"
|
||||
path="res://.godot/imported/box.png-c36de003bc6b3890e50f6a4e0637c2de.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/fireworks_box/box.png"
|
||||
dest_files=["res://.godot/imported/box.png-c36de003bc6b3890e50f6a4e0637c2de.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,24 @@
|
||||
extends Node2D
|
||||
|
||||
signal clicked(node:Node2D)
|
||||
|
||||
@onready var _state_chart:StateChart = $StateChart as StateChart
|
||||
var _counter = 0
|
||||
|
||||
func count_up():
|
||||
_counter += 1
|
||||
_notify()
|
||||
|
||||
func count_down():
|
||||
_counter -= 1
|
||||
_notify()
|
||||
|
||||
func _notify():
|
||||
_state_chart.set_expression_property("counter", _counter)
|
||||
_state_chart.send_event("counter_changed")
|
||||
|
||||
|
||||
func _on_area_2d_input_event(_viewport, event,_shape_idx):
|
||||
# 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://dn46gqfbbvsnk
|
@ -0,0 +1,244 @@
|
||||
[gd_scene load_steps=18 format=3 uid="uid://bvrbfp870t0kd"]
|
||||
|
||||
[ext_resource type="Script" path="res://godot_state_charts_examples/platformer/fireworks_box/fireworks_box.gd" id="1_6vg3k"]
|
||||
[ext_resource type="Texture2D" uid="uid://roilgifkgiii" path="res://godot_state_charts_examples/platformer/fireworks_box/box.png" id="1_aido8"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/state_chart.gd" id="2_ahjdl"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/compound_state.gd" id="3_b1cau"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/atomic_state.gd" id="4_ot1ih"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/transition.gd" id="6_bf3gq"]
|
||||
[ext_resource type="Script" path="res://addons/godot_state_charts/expression_guard.gd" id="7_tu34q"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_y5h70"]
|
||||
script = ExtResource("7_tu34q")
|
||||
expression = "counter > 0"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_lsbaa"]
|
||||
script = ExtResource("7_tu34q")
|
||||
expression = "counter > 2"
|
||||
|
||||
[sub_resource type="Resource" id="Resource_t7gf7"]
|
||||
script = ExtResource("7_tu34q")
|
||||
expression = "counter == 0"
|
||||
|
||||
[sub_resource type="Animation" id="Animation_0njji"]
|
||||
length = 0.001
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Box:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(0, -10)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Box:rotation")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [-0.132645]
|
||||
}
|
||||
tracks/2/type = "value"
|
||||
tracks/2/imported = false
|
||||
tracks/2/enabled = true
|
||||
tracks/2/path = NodePath("Box:scale")
|
||||
tracks/2/interp = 1
|
||||
tracks/2/loop_wrap = true
|
||||
tracks/2/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(1, 1)]
|
||||
}
|
||||
tracks/3/type = "value"
|
||||
tracks/3/imported = false
|
||||
tracks/3/enabled = true
|
||||
tracks/3/path = NodePath("GPUParticles2D:emitting")
|
||||
tracks/3/interp = 1
|
||||
tracks/3/loop_wrap = true
|
||||
tracks/3/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_81tef"]
|
||||
resource_name = "explode"
|
||||
length = 0.2
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Box:scale")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1, 0.2),
|
||||
"transitions": PackedFloat32Array(1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [Vector2(1, 1), Vector2(0.2, 0.2), Vector2(1e-05, 1e-05)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("GPUParticles2D:emitting")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0.2),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 1,
|
||||
"values": [true]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_yw5k5"]
|
||||
resource_name = "idle"
|
||||
length = 0.2
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Box:rotation")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [0.0]
|
||||
}
|
||||
|
||||
[sub_resource type="Animation" id="Animation_tug1d"]
|
||||
resource_name = "rattle"
|
||||
loop_mode = 1
|
||||
tracks/0/type = "value"
|
||||
tracks/0/imported = false
|
||||
tracks/0/enabled = true
|
||||
tracks/0/path = NodePath("Box:position")
|
||||
tracks/0/interp = 1
|
||||
tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"values": [Vector2(0, -10)]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
tracks/1/imported = false
|
||||
tracks/1/enabled = true
|
||||
tracks/1/path = NodePath("Box:rotation")
|
||||
tracks/1/interp = 1
|
||||
tracks/1/loop_wrap = true
|
||||
tracks/1/keys = {
|
||||
"times": PackedFloat32Array(0, 0.1, 0.3, 0.5, 0.7, 0.9, 1),
|
||||
"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1),
|
||||
"update": 0,
|
||||
"values": [0.0, -0.132645, 0.263545, -0.139626, -0.261799, -0.122173, 0.0]
|
||||
}
|
||||
|
||||
[sub_resource type="AnimationLibrary" id="AnimationLibrary_stxxq"]
|
||||
_data = {
|
||||
"RESET": SubResource("Animation_0njji"),
|
||||
"explode": SubResource("Animation_81tef"),
|
||||
"idle": SubResource("Animation_yw5k5"),
|
||||
"rattle": SubResource("Animation_tug1d")
|
||||
}
|
||||
|
||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_c15xx"]
|
||||
lifetime_randomness = 0.17
|
||||
particle_flag_disable_z = true
|
||||
direction = Vector3(0, -1, 0)
|
||||
spread = 42.97
|
||||
gravity = Vector3(0, 20, 0)
|
||||
initial_velocity_min = 26.32
|
||||
initial_velocity_max = 52.63
|
||||
orbit_velocity_min = 0.0
|
||||
orbit_velocity_max = 0.0
|
||||
turbulence_noise_scale = 8.14
|
||||
|
||||
[sub_resource type="RectangleShape2D" id="RectangleShape2D_4ryt0"]
|
||||
|
||||
[node name="FireworksBox" type="Node2D"]
|
||||
script = ExtResource("1_6vg3k")
|
||||
|
||||
[node name="Box" type="Sprite2D" parent="."]
|
||||
position = Vector2(0, -10)
|
||||
texture = ExtResource("1_aido8")
|
||||
|
||||
[node name="StateChart" type="Node" parent="."]
|
||||
editor_description = "A state chart controlling the rattling and explosion of a box. You can probably use a simple script to achieve the same behaviour but it shows how to use expression guards."
|
||||
script = ExtResource("2_ahjdl")
|
||||
track_in_editor = true
|
||||
|
||||
[node name="Root" type="Node" parent="StateChart"]
|
||||
script = ExtResource("3_b1cau")
|
||||
initial_state = NodePath("Idle")
|
||||
|
||||
[node name="Idle" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("4_ot1ih")
|
||||
|
||||
[node name="Rattle on Counter" type="Node" parent="StateChart/Root/Idle"]
|
||||
script = ExtResource("6_bf3gq")
|
||||
to = NodePath("../../Rattling")
|
||||
event = &"counter_changed"
|
||||
guard = SubResource("Resource_y5h70")
|
||||
|
||||
[node name="Rattling" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("4_ot1ih")
|
||||
|
||||
[node name="Explode on Counter" type="Node" parent="StateChart/Root/Rattling"]
|
||||
script = ExtResource("6_bf3gq")
|
||||
to = NodePath("../../Exploding")
|
||||
event = &"counter_changed"
|
||||
guard = SubResource("Resource_lsbaa")
|
||||
|
||||
[node name="Get back to Idle" type="Node" parent="StateChart/Root/Rattling"]
|
||||
script = ExtResource("6_bf3gq")
|
||||
to = NodePath("../../Idle")
|
||||
event = &"counter_changed"
|
||||
guard = SubResource("Resource_t7gf7")
|
||||
|
||||
[node name="Exploding" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("4_ot1ih")
|
||||
|
||||
[node name="Die after 4s" type="Node" parent="StateChart/Root/Exploding"]
|
||||
script = ExtResource("6_bf3gq")
|
||||
to = NodePath("../../Dead")
|
||||
delay_seconds = 4.0
|
||||
|
||||
[node name="Dead" type="Node" parent="StateChart/Root"]
|
||||
script = ExtResource("4_ot1ih")
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
reset_on_save = false
|
||||
libraries = {
|
||||
"": SubResource("AnimationLibrary_stxxq")
|
||||
}
|
||||
|
||||
[node name="GPUParticles2D" type="GPUParticles2D" parent="."]
|
||||
position = Vector2(0, -10)
|
||||
emitting = false
|
||||
amount = 300
|
||||
process_material = SubResource("ParticleProcessMaterial_c15xx")
|
||||
lifetime = 2.81
|
||||
one_shot = true
|
||||
explosiveness = 0.86
|
||||
|
||||
[node name="Area2D" type="Area2D" parent="."]
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
||||
position = Vector2(0, -10)
|
||||
shape = SubResource("RectangleShape2D_4ryt0")
|
||||
|
||||
[connection signal="state_entered" from="StateChart/Root/Idle" to="AnimationPlayer" method="play" binds= ["idle"]]
|
||||
[connection signal="state_entered" from="StateChart/Root/Rattling" to="AnimationPlayer" method="play" binds= ["rattle"]]
|
||||
[connection signal="state_entered" from="StateChart/Root/Exploding" to="AnimationPlayer" method="play" binds= ["explode"]]
|
||||
[connection signal="state_entered" from="StateChart/Root/Dead" to="." method="queue_free"]
|
||||
[connection signal="input_event" from="Area2D" to="." method="_on_area_2d_input_event"]
|
BIN
godot_state_charts_examples/platformer/ninja_frog/full.png
Normal file
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"]
|
94
godot_state_charts_examples/platformer/platformer_demo.tscn
Normal file
BIN
godot_state_charts_examples/platformer/terrain/green.png
Normal file
After Width: | Height: | Size: 543 B |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bap00a5gcipy6"
|
||||
path="res://.godot/imported/green.png-7e931e8924aaf6f1ff626e30e2c63319.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/terrain/green.png"
|
||||
dest_files=["res://.godot/imported/green.png-7e931e8924aaf6f1ff626e30e2c63319.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
|
BIN
godot_state_charts_examples/platformer/terrain/terrain_tiles.png
Normal file
After Width: | Height: | Size: 8.6 KiB |
@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://d2evtvw3l7jug"
|
||||
path="res://.godot/imported/terrain_tiles.png-2247cd6621fc9988b0ae044edcccf620.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://godot_state_charts_examples/platformer/terrain/terrain_tiles.png"
|
||||
dest_files=["res://.godot/imported/terrain_tiles.png-2247cd6621fc9988b0ae044edcccf620.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,199 @@
|
||||
[gd_resource type="TileSet" load_steps=6 format=3 uid="uid://cd6hbvgl1e2xy"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://d2evtvw3l7jug" path="res://godot_state_charts_examples/platformer/terrain/terrain_tiles.png" id="1_g8rgd"]
|
||||
[ext_resource type="Texture2D" uid="uid://bap00a5gcipy6" path="res://godot_state_charts_examples/platformer/terrain/green.png" id="2_q18a4"]
|
||||
|
||||
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_8w8gx"]
|
||||
friction = 0.0
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_p8in1"]
|
||||
texture = ExtResource("1_g8rgd")
|
||||
6:4/0 = 0
|
||||
6:4/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
6:4/0/physics_layer_0/angular_velocity = 0.0
|
||||
6:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
7:4/0 = 0
|
||||
7:4/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
7:4/0/physics_layer_0/angular_velocity = 0.0
|
||||
7:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
8:4/0 = 0
|
||||
8:4/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
8:4/0/physics_layer_0/angular_velocity = 0.0
|
||||
8:4/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
8:5/0 = 0
|
||||
8:5/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
8:5/0/physics_layer_0/angular_velocity = 0.0
|
||||
8:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
8:6/0 = 0
|
||||
8:6/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
8:6/0/physics_layer_0/angular_velocity = 0.0
|
||||
8:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
7:6/0 = 0
|
||||
7:6/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
7:6/0/physics_layer_0/angular_velocity = 0.0
|
||||
7:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
6:6/0 = 0
|
||||
6:6/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
6:6/0/physics_layer_0/angular_velocity = 0.0
|
||||
6:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
6:5/0 = 0
|
||||
6:5/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
6:5/0/physics_layer_0/angular_velocity = 0.0
|
||||
6:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
7:5/0 = 0
|
||||
7:5/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
7:5/0/physics_layer_0/angular_velocity = 0.0
|
||||
7:5/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
0:0/0 = 0
|
||||
0:0/0/terrain_set = 0
|
||||
0:0/0/terrain = 0
|
||||
0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
0:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 0.3125, 0.5, 0.5, 0, 8, -8, 7.5)
|
||||
0:0/0/terrains_peering_bit/right_side = 0
|
||||
0:0/0/terrains_peering_bit/bottom_right_corner = 0
|
||||
0:0/0/terrains_peering_bit/bottom_side = 0
|
||||
1:0/0 = 0
|
||||
1:0/0/terrain_set = 0
|
||||
1:0/0/terrain = 0
|
||||
1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
1:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(8, -8, 8, 0, -8, 0, -8, -8)
|
||||
1:0/0/terrains_peering_bit/right_side = 0
|
||||
1:0/0/terrains_peering_bit/bottom_right_corner = 0
|
||||
1:0/0/terrains_peering_bit/bottom_side = 0
|
||||
1:0/0/terrains_peering_bit/bottom_left_corner = 0
|
||||
1:0/0/terrains_peering_bit/left_side = 0
|
||||
1:1/0 = 0
|
||||
1:1/0/terrain_set = 0
|
||||
1:1/0/terrain = 0
|
||||
1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:1/0/physics_layer_0/angular_velocity = 0.0
|
||||
1:1/0/terrains_peering_bit/right_side = 0
|
||||
1:1/0/terrains_peering_bit/bottom_right_corner = 0
|
||||
1:1/0/terrains_peering_bit/bottom_side = 0
|
||||
1:1/0/terrains_peering_bit/bottom_left_corner = 0
|
||||
1:1/0/terrains_peering_bit/left_side = 0
|
||||
1:1/0/terrains_peering_bit/top_left_corner = 0
|
||||
1:1/0/terrains_peering_bit/top_side = 0
|
||||
1:1/0/terrains_peering_bit/top_right_corner = 0
|
||||
2:1/0 = 0
|
||||
2:1/0/terrain_set = 0
|
||||
2:1/0/terrain = 0
|
||||
2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
2:1/0/physics_layer_0/angular_velocity = 0.0
|
||||
2:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(0, -8, 8, -8, 8, 8, 0, 8)
|
||||
2:1/0/terrains_peering_bit/bottom_side = 0
|
||||
2:1/0/terrains_peering_bit/bottom_left_corner = 0
|
||||
2:1/0/terrains_peering_bit/left_side = 0
|
||||
2:1/0/terrains_peering_bit/top_left_corner = 0
|
||||
2:1/0/terrains_peering_bit/top_side = 0
|
||||
2:2/0 = 0
|
||||
2:2/0/terrain_set = 0
|
||||
2:2/0/terrain = 0
|
||||
2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
2:2/0/physics_layer_0/angular_velocity = 0.0
|
||||
2:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(0, -8, 8, -8, 8, 8, -8, 8, -8, 0, 0, 0)
|
||||
2:2/0/terrains_peering_bit/left_side = 0
|
||||
2:2/0/terrains_peering_bit/top_left_corner = 0
|
||||
2:2/0/terrains_peering_bit/top_side = 0
|
||||
2:0/0 = 0
|
||||
2:0/0/terrain_set = 0
|
||||
2:0/0/terrain = 0
|
||||
2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
2:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
2:0/0/physics_layer_0/polygon_0/points = PackedVector2Array(8, -8, 8, 8, -8, 8, -8, -8)
|
||||
2:0/0/terrains_peering_bit/bottom_side = 0
|
||||
2:0/0/terrains_peering_bit/bottom_left_corner = 0
|
||||
2:0/0/terrains_peering_bit/left_side = 0
|
||||
0:1/0 = 0
|
||||
0:1/0/terrain_set = 0
|
||||
0:1/0/terrain = 0
|
||||
0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:1/0/physics_layer_0/angular_velocity = 0.0
|
||||
0:1/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 0, -8, 0, 8, -8, 7.5)
|
||||
0:1/0/terrains_peering_bit/right_side = 0
|
||||
0:1/0/terrains_peering_bit/bottom_right_corner = 0
|
||||
0:1/0/terrains_peering_bit/bottom_side = 0
|
||||
0:1/0/terrains_peering_bit/top_side = 0
|
||||
0:1/0/terrains_peering_bit/top_right_corner = 0
|
||||
0:2/0 = 0
|
||||
0:2/0/terrain_set = 0
|
||||
0:2/0/terrain = 0
|
||||
0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:2/0/physics_layer_0/angular_velocity = 0.0
|
||||
0:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(-8, -8, 8, -8, 8, 8, -8, 8)
|
||||
0:2/0/terrains_peering_bit/right_side = 0
|
||||
0:2/0/terrains_peering_bit/top_side = 0
|
||||
0:2/0/terrains_peering_bit/top_right_corner = 0
|
||||
1:2/0 = 0
|
||||
1:2/0/terrain_set = 0
|
||||
1:2/0/terrain = 0
|
||||
1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:2/0/physics_layer_0/angular_velocity = 0.0
|
||||
1:2/0/physics_layer_0/polygon_0/points = PackedVector2Array(8, 0, 8, 8, -8, 8, -8, 0)
|
||||
1:2/0/terrains_peering_bit/right_side = 0
|
||||
1:2/0/terrains_peering_bit/left_side = 0
|
||||
1:2/0/terrains_peering_bit/top_left_corner = 0
|
||||
1:2/0/terrains_peering_bit/top_side = 0
|
||||
1:2/0/terrains_peering_bit/top_right_corner = 0
|
||||
|
||||
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_gpldh"]
|
||||
texture = ExtResource("2_q18a4")
|
||||
0:0/0 = 0
|
||||
0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
1:0/0 = 0
|
||||
1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
1:1/0 = 0
|
||||
1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:1/0/physics_layer_0/angular_velocity = 0.0
|
||||
1:2/0 = 0
|
||||
1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:2/0/physics_layer_0/angular_velocity = 0.0
|
||||
2:2/0 = 0
|
||||
2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
2:2/0/physics_layer_0/angular_velocity = 0.0
|
||||
0:2/0 = 0
|
||||
0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:2/0/physics_layer_0/angular_velocity = 0.0
|
||||
0:1/0 = 0
|
||||
0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:1/0/physics_layer_0/angular_velocity = 0.0
|
||||
2:0/0 = 0
|
||||
2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
2:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
3:0/0 = 0
|
||||
3:0/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
3:0/0/physics_layer_0/angular_velocity = 0.0
|
||||
3:1/0 = 0
|
||||
3:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
3:1/0/physics_layer_0/angular_velocity = 0.0
|
||||
2:1/0 = 0
|
||||
2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
2:1/0/physics_layer_0/angular_velocity = 0.0
|
||||
3:2/0 = 0
|
||||
3:2/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
3:2/0/physics_layer_0/angular_velocity = 0.0
|
||||
2:3/0 = 0
|
||||
2:3/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
2:3/0/physics_layer_0/angular_velocity = 0.0
|
||||
1:3/0 = 0
|
||||
1:3/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
1:3/0/physics_layer_0/angular_velocity = 0.0
|
||||
0:3/0 = 0
|
||||
0:3/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
0:3/0/physics_layer_0/angular_velocity = 0.0
|
||||
3:3/0 = 0
|
||||
3:3/0/physics_layer_0/linear_velocity = Vector2(0, 0)
|
||||
3:3/0/physics_layer_0/angular_velocity = 0.0
|
||||
|
||||
[resource]
|
||||
physics_layer_0/collision_layer = 1
|
||||
physics_layer_0/physics_material = SubResource("PhysicsMaterial_8w8gx")
|
||||
terrain_set_0/mode = 0
|
||||
terrain_set_0/terrain_0/name = "Stuff"
|
||||
terrain_set_0/terrain_0/color = Color(0.501961, 0.345098, 0.25098, 1)
|
||||
sources/0 = SubResource("TileSetAtlasSource_p8in1")
|
||||
sources/2 = SubResource("TileSetAtlasSource_gpldh")
|
@ -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
|
@ -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)
|
||||
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
uid://dg7apxhe32cgj
|
@ -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"]
|
59
godot_state_charts_examples/stepping/stepping.gd
Normal file
@ -0,0 +1,59 @@
|
||||
extends Node2D
|
||||
|
||||
|
||||
@onready var _add_coal_to_drill_button:Button = %AddCoalToDrillButton
|
||||
@onready var _coal_available_label:Label = %CoalAvailableLabel
|
||||
@onready var _coal_in_drill_label:Label = %CoalInDrillLabel
|
||||
@onready var _state_chart:StateChart = %StateChart
|
||||
|
||||
|
||||
var _coal_available:int = 0:
|
||||
set(value):
|
||||
_coal_available = value
|
||||
# update the UI when this changes
|
||||
_coal_available_label.text = str(_coal_available)
|
||||
_add_coal_to_drill_button.disabled = _coal_available == 0
|
||||
|
||||
var _coal_in_drill:int = 0:
|
||||
set(value):
|
||||
_coal_in_drill = value
|
||||
# update the UI when this changes
|
||||
_coal_in_drill_label.text = str(_coal_in_drill)
|
||||
if _coal_in_drill == 0:
|
||||
# if there is no more coal in the drill send the
|
||||
# coal_depleted event
|
||||
_state_chart.send_event("coal_depleted")
|
||||
else:
|
||||
# otherwise send the coal_available event
|
||||
_state_chart.send_event("coal_available")
|
||||
|
||||
|
||||
func _ready():
|
||||
_coal_available = 1 # we start with 1 coal
|
||||
|
||||
|
||||
func _on_add_coal_to_drill_button_pressed():
|
||||
# take one coal from the pile and put it into the generator
|
||||
_coal_available -= 1
|
||||
_coal_in_drill += 1
|
||||
|
||||
|
||||
func _on_drill_has_coal_state_stepped():
|
||||
# when we are in this state, we produce 2 coal and consume one of the coal in
|
||||
# the drill
|
||||
_coal_available += 2
|
||||
_coal_in_drill -= 1
|
||||
|
||||
|
||||
func _on_drill_has_no_coal_state_stepped():
|
||||
# when we are in this state, the drill has no coal so we just flash
|
||||
# the label red.
|
||||
_coal_in_drill_label.modulate = Color.RED
|
||||
create_tween().tween_property(_coal_in_drill_label, "modulate", Color.WHITE, 0.5)
|
||||
|
||||
|
||||
func _on_next_round_button_pressed():
|
||||
# when the next round button is pressed we handle all currently active states
|
||||
_state_chart.step()
|
||||
|
||||
|
1
godot_state_charts_examples/stepping/stepping.gd.uid
Normal file
@ -0,0 +1 @@
|
||||
uid://dctc1yeiwh0wx
|