Continue to move logic into base classes. Inheritence is maybe not so bad. Added debug flags for state machine that also sets it for children so I can test one child at a time.

This commit is contained in:
Nitsud Yarg 2024-06-02 09:12:06 -07:00
parent 267850a2f6
commit e076952b12
12 changed files with 125 additions and 85 deletions

View File

@ -212,3 +212,4 @@ position = Vector2( 394, 47 )
[node name="ActorTemplate" parent="." instance=ExtResource( 6 )]
position = Vector2( 262, 44 )
actor_type = "NPC"

View File

@ -4,6 +4,7 @@ extends KinematicBody2D
var velocity = Vector2(0,0)
var direction = Vector2(-1,0)
export(String, "Player", "Enemy", "NPC") var actor_type
export var sprite_facing_right: bool = true
export(Array, Resource) var SoundEffects
@ -23,6 +24,36 @@ var sound_effects_dict: Dictionary
# not a huge deal because this is mostly to help with
# interfaces for the state machines.
func _ready() -> void:
movement_state_machine.init_animated_actor(self, movement_animations, movement_component)
# movement_component.player_number = player_number
# Experimenting with sound based resources I did this and it worked
#sound_effect_player.stream = sound_effects.sounds["pew"]
#print(sounds.sounds["pew"])
#sound_effects.play()
# Trying something new with a custom resourse.
for i in SoundEffects:
sound_effects_dict[i.animation_name + str(i.frame_number)] = i.sound
print (sound_effects_dict)
func _unhandled_input(event: InputEvent) -> void:
if actor_type == "Player":
movement_component.process_input(event)
movement_state_machine.process_input(event)
func _physics_process(delta: float) -> void:
movement_state_machine.process_physics(delta)
func _process(delta: float) -> void:
if actor_type == "NPC" or actor_type == "Enemy":
movement_component.process(delta)
movement_state_machine.process_frame(delta)
# PlayerInfo.player_position = global_position
play_sound_frame(movement_animations.animation , movement_animations.frame)
var last_sound_frame_animation: String = ''
var last_sound_frame: int = -1
func play_sound_frame(animation: String, frame: int ):

View File

@ -1,9 +1,8 @@
[gd_scene load_steps=26 format=2]
[gd_scene load_steps=25 format=2]
[ext_resource path="res://src/templates/Actor/ActorTemplate.tscn" type="PackedScene" id=1]
[ext_resource path="res://src/enemyC/enemyC_movement_component.gd" type="Script" id=2]
[ext_resource path="res://src/state_animated_actor.gd" type="Script" id=3]
[ext_resource path="res://src/enemyC/states/idle.gd" type="Script" id=4]
[ext_resource path="res://src/enemyC/states/wander.gd" type="Script" id=5]
[sub_resource type="StreamTexture" id=1]
load_path = "res://.import/botEnemy.png-46efd539a38730ff15fb4ddb087329c6.stex"
@ -112,12 +111,13 @@ animations = [ {
extents = Vector2( 9, 3.5 )
[node name="EnemyC" instance=ExtResource( 1 )]
actor_type = "Enemy"
[node name="AnimatedSprite" parent="." index="0"]
position = Vector2( 11, -7 )
frames = SubResource( 20 )
animation = "idle"
frame = 2
frame = 0
__meta__ = {
"_aseprite_wizard_config_": {
"layer": "",
@ -134,29 +134,28 @@ __meta__ = {
[node name="CollisionShape2D" parent="." index="1"]
position = Vector2( -0.5, -2 )
[node name="movement_component" parent="." index="2"]
script = ExtResource( 2 )
[node name="IdleTimeout" type="Timer" parent="movement_component" index="0"]
wait_time = 2.0
one_shot = true
autostart = true
[node name="idle" parent="movement_state_machine" index="0"]
script = ExtResource( 4 )
timeout_seconds = 2.0
animation_sequence = [ "idle" ]
wander_node = NodePath("../wander")
attack_node = NodePath("../attack")
[node name="fall" parent="movement_state_machine" index="1"]
animation_sequence = [ "idle" ]
[node name="wander" type="Node" parent="movement_state_machine" index="2"]
script = ExtResource( 5 )
timeout_seconds = 2.0
animation_sequence = [ "walk" ]
idle_node = NodePath("../idle")
attack_node = NodePath("../attack")
fall_node = NodePath("../fall")
[node name="attack" type="Node" parent="movement_state_machine" index="3"]
[node name="attack" type="Node" parent="movement_state_machine" index="2"]
script = ExtResource( 3 )
timeout_seconds = 3.0
animation_sequence = [ "attack" ]
[node name="move" parent="movement_state_machine" index="3"]
animation_sequence = [ "walk" ]
[node name="PlayerDetection" type="RayCast2D" parent="." index="6"]
cast_to = Vector2( 21, 0 )

View File

@ -0,0 +1,22 @@
extends MovementComponent
onready var idle_timeout = $IdleTimeout
var flip_flop = false
func process(delta):
if current_movement_state == "idle" and idle_timeout.time_left == 0:
print ("Time to move!")
if flip_flop:
flip_flop = false
go_right()
idle_timeout.start()
else:
flip_flop = true
go_left()
idle_timeout.start()
if current_movement_state == "move" and idle_timeout.time_left == 0:
print("Time to stop.")
idle_timeout.start()
stop()
return

View File

@ -4,11 +4,32 @@ extends Node
onready var desired_movement_vector: Vector2 = Vector2(0,0)
var current_movement_state:String
enum directions {UP, DOWN, LEFT, RIGHT}
#Can't use floats here, switched to constants.
#enum directions {UP = -1, DOWN = 1, LEFT, RIGHT}
const UP = -1.0
const DOWN = 1.0
const LEFT = -1.0
const RIGHT = 1.0
func process(delta):
pass
func process_input(event: InputEvent):
pass
# A Series of helper functions
func go_up():
desired_movement_vector.y = UP
func go_down():
desired_movement_vector.y = DOWN
func go_left():
desired_movement_vector.x = LEFT
func go_right():
desired_movement_vector.x = RIGHT
func stop():
desired_movement_vector = Vector2(0,0)
# Return the desired direction of movement for the character
# in the range [-1, 1], where positive values indicate a desire
# to move to the right and negative values to the left.

View File

@ -9,49 +9,6 @@ onready var gun = $Gun
#var sound_effects = preload("res://src/playerC/resources/sound_effects.tres")
func _ready() -> void:
movement_state_machine.init_animated_actor(self, movement_animations, movement_component)
movement_component.player_number = player_number
# Experimenting with sound based resources I did this and it worked
#sound_effect_player.stream = sound_effects.sounds["pew"]
#print(sounds.sounds["pew"])
#sound_effects.play()
# Trying something new with a custom resourse.
for i in SoundEffects:
sound_effects_dict[i.animation_name + str(i.frame_number)] = i.sound
print (sound_effects_dict)
func _unhandled_input(event: InputEvent) -> void:
movement_state_machine.process_input(event)
func _physics_process(delta: float) -> void:
movement_state_machine.process_physics(delta)
# #TODO: So much hack
# if direction.x != 0:
# gun.set_scale( Vector2(direction.x,1))
# Commented out to try parent transforms instead
# if direction.x < 0:
# var t = Transform2D()
# # Translation
# t.origin = Vector2(gun.offset_position.x * -1, gun.offset_position.y)
# gun.transform = t
# elif direction.x > 0:
# var t = Transform2D()
# # Translation
# t.origin = Vector2(gun.offset_position.x, gun.offset_position.y)
# gun.transform = t
# Attempting a Kinematic2D level scale for flip operations instead.
#self.transform
#self.scale.x = -1
func _process(delta: float) -> void:
movement_state_machine.process_frame(delta)
PlayerInfo.player_position = global_position
play_sound_frame(movement_animations.animation , movement_animations.frame)
##TODO: I don't like player class having do do this.
@ -65,12 +22,9 @@ func _on_Hurtbox_area_entered(area):
movement_state_machine.change_state($Controllers/state_machine/hurt)
func set_hurtbox(enabled: bool):
#player_hurtbox.disabled = enabled #nope
player_hurtbox.set_deferred("disabled", !enabled) #WTF Apparently this is how to do it
#$Hurtbox.monitoring = enabled #nope
#$Hurtbox.set_deferred("monitoring", enabled) #works
#$Hurtbox.monitoring = false #nope
#$Hurtbox.set_monitoring(enabled) # Nope
pass
## TODO: This breaks now I guess because I moved the process functions out to parent class
#player_hurtbox.set_deferred("disabled", !enabled) #WTF Apparently this is how to do it
func shoot_projectile():
var is_shooting = false

View File

@ -417,6 +417,7 @@ extents = Vector2( 14, 18.5 )
[node name="Player" type="KinematicBody2D"]
collision_layer = 2
script = ExtResource( 1 )
actor_type = "Player"
SoundEffects = [ SubResource( 148 ) ]
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]

View File

@ -1,6 +1,7 @@
class_name StateMachine extends Node
export (NodePath) var starting_state
export var debug_state_machine: bool = false
var current_state: State
var state_modifiers: Array
@ -10,8 +11,11 @@ var state_modifiers: Array
func init() -> void:
for child in get_children():
if child is State:
if debug_state_machine:
print("Initializing State Node: ", child.name)
child.modifier_stack_ref = state_modifiers
if debug_state_machine:
child.debug_state = true
# Initialize to the default state
change_state(get_node(starting_state))
@ -23,7 +27,7 @@ func change_state(new_state: State) -> void:
current_state = new_state
current_state.enter()
if(state_modifiers.size() > 0):
if(state_modifiers.size() > 0 and debug_state_machine):
print("Active Modifiers:")
for mods in state_modifiers:
print(mods.name)

View File

@ -6,11 +6,14 @@ func init_animated_actor(parent: KinematicBody2D, animations: AnimatedSprite, mo
animations.connect("animation_finished", self, "_on_AnimatedSprite_animation_finished")
for child in get_children():
if child is StateAnimatedActor:
if debug_state_machine:
print("Initializing State Node for ", parent.name, ": ", child.name)
child.parent = parent
child.animations = animations
child.move_component = move_component
child.modifier_stack_ref = state_modifiers
if debug_state_machine:
child.debug_state = true
# Initialize to the default state
change_state(get_node(starting_state))
@ -23,6 +26,7 @@ func process_frame(delta: float) -> void:
# states to be that complex.
if state_modifiers.empty() == false:
if state_modifiers[-1].state_timeout.time_left == 0:
if debug_state_machine:
print("Pop State Modifier: ", state_modifiers[-1].name)
state_modifiers.pop_back()
# Reset animation suffix

View File

@ -55,11 +55,5 @@ func _process(delta: float) -> void:
# if movement_animations.frames.get_animation_loop(movement_animations.animation) == false:
# movement_state_machine.current_state.animation_index += 1
func _on_Hurtbox_area_entered(area):
print("Ouch.",area)
movement_state_machine.change_state($Controllers/state_machine/hurt)
func set_hurtbox(enabled: bool):
actor_hurtbox.set_deferred("disabled", !enabled) #WTF Apparently this is how to do it

View File

@ -7,7 +7,7 @@
[ext_resource path="res://src/movement_component.gd" type="Script" id=5]
[ext_resource path="res://src/templates/Actor/resources/Smiley.png" type="Texture" id=6]
[ext_resource path="res://src/templates/Actor/states/move.gd" type="Script" id=7]
[ext_resource path="res://src/templates/Actor/ActorTemplate.gd" type="Script" id=12]
[ext_resource path="res://src/actor.gd" type="Script" id=8]
[sub_resource type="AtlasTexture" id=76]
atlas = ExtResource( 6 )
@ -46,11 +46,11 @@ extents = Vector2( 14, 18.5 )
[node name="ActorTemplate" type="KinematicBody2D"]
collision_layer = 2
script = ExtResource( 12 )
script = ExtResource( 8 )
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
frames = SubResource( 75 )
frame = 4
frame = 3
playing = true
flip_h = true
__meta__ = {
@ -81,6 +81,7 @@ starting_state = NodePath("idle")
script = ExtResource( 4 )
animation_sequence = [ "default" ]
fall_node = NodePath("../fall")
move_node = NodePath("../move")
[node name="fall" type="Node" parent="movement_state_machine"]
script = ExtResource( 3 )

View File

@ -1,21 +1,29 @@
extends StateAnimatedActor
export (NodePath) var fall_node
export (NodePath) var move_node
onready var fall_state: State = get_node(fall_node)
onready var move_state: State = get_node(move_node)
func enter() -> void:
.enter()
parent.set_hurtbox(true)
# parent.set_hurtbox(true)
parent.velocity.x = 0
print("Move Component: ", move_component.desired_movement_vector.x)
func process_physics(delta: float) -> State:
parent.velocity.y += gravity * delta
# parent.velocity.y += gravity * delta
# #parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1))
# parent.velocity.x = move_component.desired_movement_vector.x * move_speed
# parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1))
parent.velocity.x = move_component.desired_movement_vector.x * move_speed
parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1))
move_actor_as_desired(delta)
if parent.velocity.x != 0.0:
return move_state
if !parent.is_on_floor():
return fall_state