Compare commits

..

7 Commits

21 changed files with 996 additions and 594 deletions

View File

@ -1,4 +1,6 @@
[gd_scene load_steps=2 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://src/actors/players/playerE/PlayerE.tscn" type="PackedScene" id=1]
[sub_resource type="RectangleShape2D" id=1]
extents = Vector2( 208, 20 )
@ -15,3 +17,5 @@ margin_bottom = 200.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="ColorRect/StaticBody2D"]
position = Vector2( 208, 20 )
shape = SubResource( 1 )
[node name="PlayerE" parent="." instance=ExtResource( 1 )]

View File

@ -0,0 +1,130 @@
[gd_resource type="SpriteFrames" load_steps=27 format=2]
[sub_resource type="StreamTexture" id=1]
load_path = "res://.import/idle.png-dac221ba43c70fde9cf788217116f029.stex"
[sub_resource type="AtlasTexture" id=2]
atlas = SubResource( 1 )
region = Rect2( 0, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=3]
atlas = SubResource( 1 )
region = Rect2( 48, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=4]
atlas = SubResource( 1 )
region = Rect2( 96, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=5]
atlas = SubResource( 1 )
region = Rect2( 0, 48, 48, 48 )
[sub_resource type="AtlasTexture" id=6]
atlas = SubResource( 1 )
region = Rect2( 48, 48, 48, 48 )
[sub_resource type="AtlasTexture" id=7]
atlas = SubResource( 1 )
region = Rect2( 96, 48, 48, 48 )
[sub_resource type="StreamTexture" id=8]
load_path = "res://.import/jump.png-e5e27a6608040d3526a151777807f18b.stex"
[sub_resource type="AtlasTexture" id=9]
atlas = SubResource( 8 )
region = Rect2( 0, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=10]
atlas = SubResource( 8 )
region = Rect2( 48, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=11]
atlas = SubResource( 8 )
region = Rect2( 0, 48, 48, 48 )
[sub_resource type="StreamTexture" id=12]
load_path = "res://.import/land.png-c462761c5fb4bf0befa8d4a5a879e2f5.stex"
[sub_resource type="AtlasTexture" id=13]
atlas = SubResource( 12 )
region = Rect2( 0, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=14]
atlas = SubResource( 12 )
region = Rect2( 48, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=15]
atlas = SubResource( 12 )
region = Rect2( 96, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=16]
atlas = SubResource( 12 )
region = Rect2( 0, 48, 48, 48 )
[sub_resource type="AtlasTexture" id=17]
atlas = SubResource( 12 )
region = Rect2( 48, 48, 48, 48 )
[sub_resource type="StreamTexture" id=18]
load_path = "res://.import/run.png-d086b4c01d4e3ff36f750b9aff5a303a.stex"
[sub_resource type="AtlasTexture" id=19]
atlas = SubResource( 18 )
region = Rect2( 0, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=20]
atlas = SubResource( 18 )
region = Rect2( 48, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=21]
atlas = SubResource( 18 )
region = Rect2( 96, 0, 48, 48 )
[sub_resource type="AtlasTexture" id=22]
atlas = SubResource( 18 )
region = Rect2( 0, 48, 48, 48 )
[sub_resource type="AtlasTexture" id=23]
atlas = SubResource( 18 )
region = Rect2( 48, 48, 48, 48 )
[sub_resource type="AtlasTexture" id=24]
atlas = SubResource( 18 )
region = Rect2( 96, 48, 48, 48 )
[sub_resource type="AtlasTexture" id=25]
atlas = SubResource( 18 )
region = Rect2( 0, 96, 48, 48 )
[sub_resource type="AtlasTexture" id=26]
atlas = SubResource( 18 )
region = Rect2( 48, 96, 48, 48 )
[resource]
resource_name = "PlayerE"
animations = [ {
"frames": [ SubResource( 2 ) ],
"loop": true,
"name": "default",
"speed": 13.0
}, {
"frames": [ SubResource( 2 ), SubResource( 3 ), SubResource( 4 ), SubResource( 5 ), SubResource( 5 ), SubResource( 6 ), SubResource( 2 ), SubResource( 7 ), SubResource( 7 ), SubResource( 7 ) ],
"loop": true,
"name": "idle",
"speed": 11.0
}, {
"frames": [ SubResource( 9 ), SubResource( 10 ), SubResource( 11 ) ],
"loop": false,
"name": "jump",
"speed": 10.0
}, {
"frames": [ SubResource( 13 ), SubResource( 14 ), SubResource( 14 ), SubResource( 15 ), SubResource( 15 ), SubResource( 16 ), SubResource( 16 ), SubResource( 17 ), SubResource( 17 ) ],
"loop": false,
"name": "land",
"speed": 13.0
}, {
"frames": [ SubResource( 19 ), SubResource( 20 ), SubResource( 21 ), SubResource( 22 ), SubResource( 23 ), SubResource( 24 ), SubResource( 25 ), SubResource( 26 ) ],
"loop": true,
"name": "run",
"speed": 13.0
} ]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/idle.png-dac221ba43c70fde9cf788217116f029.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/actors/players/playerE/idle.png"
dest_files=[ "res://.import/idle.png-dac221ba43c70fde9cf788217116f029.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/jump.png-e5e27a6608040d3526a151777807f18b.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/actors/players/playerE/jump.png"
dest_files=[ "res://.import/jump.png-e5e27a6608040d3526a151777807f18b.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/land.png-c462761c5fb4bf0befa8d4a5a879e2f5.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/actors/players/playerE/land.png"
dest_files=[ "res://.import/land.png-c462761c5fb4bf0befa8d4a5a879e2f5.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/run.png-d086b4c01d4e3ff36f750b9aff5a303a.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://assets/actors/players/playerE/run.png"
dest_files=[ "res://.import/run.png-d086b4c01d4e3ff36f750b9aff5a303a.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=false
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
process/normal_map_invert_y=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0

View File

@ -10,13 +10,15 @@ export(Array, Resource) var SoundEffects
export var debug_actor: bool = false
onready var movement_animations: AnimatedSprite = $AnimatedSprite
#onready var movement_animations: AnimatedSprite = $AnimatedSprite
onready var sound_effect_player: AudioStreamPlayer = $SE_Player
onready var movement_component: MovementComponent = $movement_component
#onready var movement_component: MovementComponent = $movement_component
onready var movement_component: Movement_StateReceiver = $Movement_StateReceiver
onready var movement_state_machine: StateMachineAnimatedActor = $movement_state_machine
#onready var movement_state_machine: StateMachineAnimatedActor = $movement_state_machine
onready var movement_state_machine: StateMachine = $movement_state_machine
var sound_effects_dict: Dictionary
@ -27,8 +29,8 @@ var sound_effects_dict: Dictionary
# interfaces for the state machines.
func _ready() -> void:
movement_state_machine.init_animated_actor(self, movement_animations, movement_component)
movement_component.attack_function = funcref(self, "attack")
#movement_state_machine.init_animated_actor(self)
#movement_component.attack_function = funcref(self, "attack")
# movement_component.player_number = player_number
# Experimenting with sound based resources I did this and it worked
@ -44,18 +46,18 @@ func _ready() -> void:
func _unhandled_input(event: InputEvent) -> void:
if actor_type == "Player":
movement_component.process_input(event)
movement_state_machine.process_input(event)
#movement_state_machine.process_input(event)
func _physics_process(delta: float) -> void:
movement_component.process_physics(delta)
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)
#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 = ''

View File

@ -0,0 +1,219 @@
class_name AnimatedSprite_StateReceiver
extends AnimatedSprite
# Declare member variables here. Examples:
# var a = 2
# var b = "text"
export var callable_state_machine :NodePath
onready var current_state = StateAnimatedActor.new()
var animation_finished: bool = false
var request_state_change: FuncRef
# this just wouldn't work well. Maybe I can try a resource
# export(Array, NodePath) var transition_state_nodes
#TODO: I think these two variables accidentally serve the same purpose
# I think one was intended to be a string of the current animation name.
var animation_index: int = 0
var current_animation_sequence: int = 0
var animation_suffix: String = '';
var mod_animation_sequence = [PoolStringArray()]
var previous_animation_name : String
var previous_state_frame_number : int
var previous_state_name: String
var previous_speed_multiplier: float
# Called when the node enters the scene tree for the first time.
func _ready():
request_state_change = funcref(get_node(callable_state_machine), 'change_to_known_state')
get_node(callable_state_machine).connect("state_changed", self,"_on_state_change")
self.connect("animation_finished",self,"_on_animation_finished")
# Sprites should only have a process function
# but if I have this will the sprite still animate?
func _process(delta):
if current_state.state_timeout != null:
if current_state.state_timeout.time_left == 0:
print("You're out of time! I saw it!")
request_state_change.call_func('idle')
#play()
process_animations()
func _on_animation_finished():
#Disabling for now:
if frames.get_animation_loop(animation) == false:
#print("Stop!!!!!", current_state.animation_sequence.size(), " - ", current_state.animation_index)
if current_state.animation_sequence.size() > 0:
#print("<-- next anim.")
animation_index += 1
if animation_index >= current_state.animation_sequence.size():
#print("Stop!!!!!")
current_state.animation_finished = true
# Called every frame. 'delta' is the elapsed time since the previous frame.
#func _process(delta):
# pass
# If called, this will attempt to make the most appropriate animation change
# would likely be triggered from an animation sequence finishing or a
# modifier being applied/removed outside of enter/exit transitions.
func update_animation(enter_frame := 0, index := 0, suffix := ''):
## TODO:
# Need to find a way to attempt to keep and transfer the Index or frame
#
# if clear_modifier:
# print("Goodbye Modifiers!")
# modifier = null
# if modifier:
# if modifier.state_timeout and modifier.timeout_seconds == 0:
# modifier = null
# By Default, we build an animation sequence off of this state's before checking
# for modifiers
var animation_sequence = current_state.animation_sequence
#var animations = current_state
mod_animation_sequence.clear()
mod_animation_sequence.append_array(animation_sequence)
# Reset animation suffix in case there isn't one
animation_suffix = suffix
animation_index = index
current_animation_sequence = animation_index
#var enter_animation = ''
#var enter_frame = 0
var modifier :StateModifier = current_state.modifier
if modifier != null:
# if modifier.modifier_type == modifier.TYPE.EXIT_ANIMATION:
# #print("OHHH Modifier Applies! ", modifier.animation_name)
# mod_animation_sequence.push_front(modifier.animation_name)
# enter_frame = modifier.starting_frame
match modifier.modifier_type:
modifier.TYPE.EXIT_ANIMATION:
mod_animation_sequence.push_front(modifier.animation_name)
enter_frame = modifier.starting_frame
modifier.TYPE.ANIMATION_SUFFIX:
if frames.has_animation(mod_animation_sequence[animation_index] + modifier.animation_name):
animation_suffix = modifier.animation_name
else:
print("Warning!: Modifier attempting to apply suffix that doesn't exist ",
mod_animation_sequence[animation_index] + modifier.animation_name)
modifier.TYPE.REPLACE_ANIMATION:
#animations.play(modifier_stack_ref[i].animation_name)
#animations.frame = modifier_stack_ref[i].starting_frame
mod_animation_sequence.clear()
mod_animation_sequence.push_back(modifier.animation_name)
enter_frame = modifier.starting_frame
# Some safety checks with supplied update parameters
if animation_index != 0:
if mod_animation_sequence.size() < animation_index + 1:
if current_state.debug_state:
print("Warning!: attempting to set to non-existant index ")
animation_index = 0
current_animation_sequence = animation_index
if frames.has_animation(mod_animation_sequence[animation_index] + animation_suffix) == false:
if current_state.debug_state:
print("Warning!: Animation doesn't exist! ")
if enter_frame != 0:
if frames.get_frame_count(animation) != frames.get_frame_count(mod_animation_sequence[animation_index] + animation_suffix):
if current_state.debug_state:
print("Warning!: attempting to set a mismatched frame ")
enter_frame = 0
if mod_animation_sequence.size() > 0:
if current_state.debug_state:
print("Starting Animation: " , mod_animation_sequence[animation_index] + animation_suffix)
play(mod_animation_sequence[animation_index] + animation_suffix)
#TODO: maybe check current animatio has this frame
frame = enter_frame
else:
print("Error! Resolved to empty animation sequence!?")
return
func process_animations():
var modifier :StateModifier = current_state.modifier
if modifier != null:
if modifier.state_timeout and modifier.state_timeout.time_left == 0:
print("Expired Modifier, updating animation.")
#modifier = null
match modifier.modifier_type:
modifier.TYPE.ANIMATION_SUFFIX:
# Attempt to seemlessly transition animations.
modifier = null
update_animation(frame,animation_index)
modifier.TYPE.REPLACE_ANIMATION:
if current_state.debug_state:
print("I don't have anything for replacements yet.")
modifier = null
update_animation()
_:
modifier = null
return
# We have no more sequence animations and the current one doesn't loop
# we do this to prevent the default idle animation from playing.
##TODO: between this and the signal based iterator I get some really strange behavior
if animation_index >= mod_animation_sequence.size() and frames.get_animation_loop(
animation) == false:
#print(animations.animation, " Animation Stopped")
stop()
#animation_finished = true
elif mod_animation_sequence.size() > animation_index and current_animation_sequence != animation_index:
#TODO: why was I doing this
# if animation_index >= mod_animation_sequence.size():
# animation_index = 0
##TODO: Add a safety check here.
play(mod_animation_sequence[animation_index] + animation_suffix)
if current_state.debug_state:
print("An animation sequence: ", mod_animation_sequence[animation_index - 1], " -> ",
animation , " (", animation_index, ")")
current_animation_sequence = animation_index
##TODO: Could probably add some more checks here.
# Singal based frame call.
#TODO: reimplement this later.
# if emitter_frame_subscriptions.has(animations.frame):
# if emitter_frame_subscriptions[animations.frame] == animations.animation:
# if frame_signal_emitted == false:
# emit_signal("frame_reached", self.name, animations.animation, animations.frame)
# # Try to only so this once.
# frame_signal_emitted = true
# else:
# frame_signal_emitted = false
func set_previous_animation( old_state: StateAnimatedActor, new_state: StateAnimatedActor ) -> void:
# added this to help prevent nul index crashes. (Usually because of signal based state changes.)
if old_state.mod_animation_sequence:
new_state.previous_animation_name = old_state.mod_animation_sequence[old_state.current_animation_sequence]
new_state.previous_state_frame_number = old_state.animations.frame
new_state.previous_state_name = old_state.name
new_state.previous_speed_multiplier = old_state.speed_multiplier
#animation_name :String, frame_number : int, animation_sequence :Array
return
# Handle state change from subscribed state machine.
#From signal state_changed(old_state_name, new_state)
func _on_state_change(old_state_name:String, new_state :State):
print ("got the state change signal ", new_state.name)
# set current state to new_state
#TODO: Confirm that this is a reference to the state in the
###### State machine
if new_state is StateAnimatedActor: #Testing this. Update: It works
current_state = new_state
update_animation()
print("It's an animated Actor state!")
else:
push_warning("Received non animated Actor state.")
#current_state = new_state

View File

@ -0,0 +1,304 @@
class_name Movement_StateReceiver
extends Node
## Movement component
# attempts to interact with movement of the scene root without knowing what
# it is. It can be perhaps a static body or kinematicbody
# it doesn't actually move a node, that's what the state machine does
# but it does keep track of velocity
# I can't give it an actor node or a direct reference.
# It can use a number of detection components to help inform decisions.
export var debug_component: bool = false
onready var current_state = StateAnimatedActor.new()
onready var parent: KinematicBody2D = get_parent()
export var callable_state_machine :NodePath
var request_state_change: FuncRef
onready var desired_movement_vector: Vector2 = Vector2(0,0)
var current_movement_state:String
# Since animactor state machine can actually view properties from this type
# I'm thinking about moving the velocity tracker in here instead of player.
var velocity = Vector2(0,0)
var momentum = Vector2(0,0)
var acceleration = Vector2(0,0)
var sim_velocity = Vector2(0,0)
#Can't use floats here, switched to constants.
#enum directions {UP = -1, DOWN = 1, LEFT, RIGHT}
var attack_function: FuncRef
const UP = -1.0
const DOWN = 1.0
const LEFT = -1.0
const RIGHT = 1.0
func _ready():
request_state_change = funcref(get_node(callable_state_machine), 'change_to_known_state')
get_node(callable_state_machine).connect("state_changed", self,"_on_state_change")
############
# These get called by the parent
############
func process_physics(delta):
move_actor_as_desired(delta)
# Shouldn't need a proces function
#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.
func get_movement_direction() -> float:
return desired_movement_vector.x
# Return a boolean indicating if the character wants to jump
func wants_jump() -> bool:
return false
# Return a boolean indicating if the character wants to attack
func wants_shoot() -> bool:
return false
# Return a boolean indicating if the character wants to dash
func wants_dash() -> bool:
return false
func wants_roll() -> bool:
return false
func wants_climb() -> bool:
return false
func get_climb_shape_location() -> Vector2:
return Vector2(-1,-1)
func _on_state_change(old_state_name:String, new_state :State):
print ("got the state change signal (MC) ", new_state.name)
# set current state to new_state
#TODO: Confirm that this is a reference to the state in the
###### State machine
if new_state is StateAnimatedActor: #Testing this. Update: It works
current_state = new_state
else:
push_warning("Received non animated Actor state.")
#current_state = new_state
func move_actor_as_desired(delta: float, x_move_direction_override: float = 0):
var _move_speed = current_state.move_speed
var _move_speed_modifier = current_state.move_speed_modifier
var _move_modifier_move_acceleration = current_state.move_modifier_move_acceleration
var _move_acceleration = current_state.move_acceleration
var _jerk_factor = current_state.jerk_factor
var _gravity = current_state.gravity
if current_state.physics_modifier:
#physics_modifier.modifier_properties.jerk_factor
#print(physics_modifier.name)
#UiManager.debug_text = physics_modifier.name + str(round(adjusted_move_speed))
var mod_props :ModifierProperties = current_state.physics_modifier.get_modifier_properties()
if mod_props.move_speed != 0 and mod_props.directional_modifier == false:
_move_speed = mod_props.move_speed
_move_speed_modifier += mod_props.move_speed_modifier
_move_acceleration += mod_props.move_acceleration
_move_modifier_move_acceleration += mod_props.move_modifier_move_acceleration
_jerk_factor += mod_props.jerk_factor
var help_me_not_be_dumb = ''
# Allow us to bump out of halt.
if _move_speed == 0 and desired_movement_vector.x != 0:
_move_speed = abs(desired_movement_vector.x)
# Determine or physics movement direction
var current_x_velocity = velocity.x #move_component.velocity.x
var move_direction = 0.0
# Determine movement direction if we have momentum
if momentum.x != 0:
if x_move_direction_override == 0:
move_direction = sign(current_x_velocity)
# if move_component.desired_movement_vector.x != 0:
# # set the move direction to the desired direction
# move_direction = move_component.desired_movement_vector.x
# else:
# # Set move direction to the transform direction
# move_direction = parent.transform.x.x
else:
move_direction = x_move_direction_override
else: # No current momentum in place
if x_move_direction_override == 0:
move_direction = desired_movement_vector.x
else:
move_direction = x_move_direction_override
## TODO: I hate that I have to do this check again.
if current_state.physics_modifier:
var mod_props :ModifierProperties = current_state.physics_modifier.get_modifier_properties()
if mod_props.move_speed != 0 and mod_props.directional_modifier == true:
# Since move_direction is always positive
if sign(move_direction) == sign(mod_props.move_speed):
_move_speed += mod_props.move_speed
else:
_move_speed -= mod_props.move_speed
if sign(move_direction) == 0:
move_direction = sign(mod_props.move_speed) * -1
#print("doing this? ")
# Determine the maximum move speed
var MAX_SPEED :float = 0
var MIN_SPEED :float = 0
if sign(_move_speed_modifier) == -1: # decreased speed modifier
help_me_not_be_dumb += '-SpeedMod'
# Move speed cannot go below zero with modifier applied
MIN_SPEED = _move_speed + _move_speed_modifier
# Poor man's clamp
if MIN_SPEED < 0:
MIN_SPEED = 0
MAX_SPEED = _move_speed
elif sign(_move_speed_modifier) == +1: # increased speed modifier
help_me_not_be_dumb += '+SpeedMod'
MIN_SPEED = _move_speed
MAX_SPEED = _move_speed + _move_speed_modifier
else: # physics won't apply here
help_me_not_be_dumb += '_Speed' # Neutral Speed
MIN_SPEED = _move_speed
MAX_SPEED = _move_speed
# get the latest aggregate acceleration
# If we have any acceleration applying
if (_move_modifier_move_acceleration + _move_acceleration) != 0:
# The acceleration is differant
# Perhaps it would be better to trigger this on a difference in modifier but they usually go together.
if abs(acceleration.x) != abs(_move_modifier_move_acceleration + _move_acceleration):
if move_direction:
print("Acceleration changed.", abs(acceleration.x), "-", (_move_modifier_move_acceleration + _move_acceleration))
acceleration.x = _move_modifier_move_acceleration + _move_acceleration
# If we're no longer tryingg to move int the direction of our movement and momentum.
if sign(current_x_velocity) != sign(desired_movement_vector.x) and momentum.x != 0:
if sign(_move_speed_modifier) == -1 : # decreased speed modifier
# Maybe we can compare the direction of the acceleration
# The direction of the acceleration should usually be positive at this point.
# when the modifier is negative.
if sign(move_direction) == sign(current_x_velocity):
if sign(acceleration.x) == sign(momentum.x):
print("Whoh Woah")
# Flip the direction of the acceleration
acceleration.x *= -1
if (sign(desired_movement_vector.x) == -1 and
sign(current_x_velocity) == 1) or (sign(desired_movement_vector.x) == -1 and
sign(current_x_velocity) == -1):
print("be more opposite")
# if sign(_move_speed_modifier) == 1: # increased speed modifier
# print("faster faster.")
elif sign(desired_movement_vector.x) == sign(current_x_velocity) and momentum.x != 0:
if sign(acceleration.x) != sign(momentum.x) and x_move_direction_override == 0:
print("Step it up!")
# Flip the direction of the acceleration
acceleration.x *= -1
# Apply momentum and acceleration if a modifer exists
if momentum.x <= 0 and _move_speed_modifier !=0:
#if we're trying to move but we have no momentum applied currently
#if move_component.desired_movement_vector.x != 0:
if move_direction:
acceleration.x = _move_modifier_move_acceleration + _move_acceleration
##TODO: I don't know where I should actually set the momentum. :
if sign(_move_speed_modifier) == -1: # decreased speed modifier
momentum.x = 0
elif sign(_move_speed_modifier) == +1: # increased speed modifier
##TODO: in most cases this should only be applied once. need to find a way to warn against this.
momentum.x = abs(current_state.move_speed_modifier)
print("momentum applied!")
# Reverse the accelerations if we carry over momentum but the modifier no longer applies.
if momentum.x > 0 and _move_speed_modifier == 0:
if sign(acceleration.x) == sign(momentum.x):
print("Whoh Woah your done.")
# Flip the direction of the acceleration
acceleration.x *= -1
# We're going to adjust our move speed only to the modifier
momentum.x += acceleration.x * delta
current_state.jerk += _jerk_factor * delta
var new_move_speed :float = 0
if sign(_move_speed_modifier) == -1: # decreased speed modifier
# MIN_SPEED = _move_speed + _move_speed_modifier
# MAX_SPEED = _move_speed
momentum.x = clamp(momentum.x, 0, abs(_move_speed_modifier))
# new_move_speed = (_move_speed + _move_speed_modifier ) + (sign(_move_speed_modifier) * -1 * move_component.momentum.x) # + jerk
new_move_speed = MIN_SPEED + (sign(_move_speed_modifier) * -1 * momentum.x) # + jerk
elif sign(_move_speed_modifier) == +1: # increased speed modifier
# MIN_SPEED = _move_speed
# MAX_SPEED = _move_speed + _move_speed_modifier
momentum.x = clamp(momentum.x, 0, _move_speed_modifier )
new_move_speed = _move_speed + momentum.x # + jerk
else: # physics won't apply here
# move_component.acceleration.x = 0
# move_component.momentum.x = 0
# new_move_speed = _move_speed
momentum.x = clamp(momentum.x, 0, MIN_SPEED )
new_move_speed = _move_speed + momentum.x # + jerk
#new_move_speed = clamp(new_move_speed, MIN_SPEED, MAX_SPEED)
var sim_move_speed = (MIN_SPEED + (sign(_move_speed_modifier) * -1 * momentum.x))
# if move_component.momentum.x != 0:
if true:
UiManager.debug_text = ( "Mod(" + str(sign(_move_speed_modifier)) + ") Dir(" + str(move_direction) + ") Vel(" + str(sign(current_x_velocity)) + ") Mov(" + str(sign(desired_movement_vector.x)) +
")\nNS:" + str(round(sim_move_speed)) + #" Z:" + str(sign(_move_speed_modifier) * -1 * move_component.momentum.x) +
"\nS:" + str(round(_move_speed + _move_speed_modifier)) + ",M" + str(round(momentum.x)) +
",A" + str(round(acceleration.x)) +
"\nVel:" + str(round(velocity.x)) + "Min:" + str(round(MIN_SPEED)) + ",Max:" + str(round(MAX_SPEED))
) # str(round(jerk))
sim_velocity.x = move_direction * sim_move_speed
#print(adjusted_move_speed, ",", new_move_speed, ",", jerk)
#print(new_move_speed, " ", adjusted_move_speed)
velocity.y += _gravity * delta
#parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1))
#print(speed_multiplier)
# move_component.velocity.x = move_component.desired_movement_vector.x * _move_speed
velocity.x = move_direction * new_move_speed
#move_component.velocity = parent.move_and_slide(move_component.velocity, Vector2.UP)
var snap = Vector2.DOWN * 8
if velocity.y < -8:
snap = Vector2.ZERO
velocity = parent.move_and_slide_with_snap(velocity, snap , Vector2.UP, true)

View File

@ -12,7 +12,7 @@ signal state_exited()
var state_timeout: Timer
var state_ready: bool = true
var name: String
export var name: String
# Called when the node enters the scene tree for the first time.
# Resources don't have _ready callbacks I think
@ -23,10 +23,13 @@ var name: String
#func _init():
# print ("Am I really a parent's constructor?")
func _init():
##TODO: this bit me in the butt. Should add a safety or something.
# needed because _ready isn't called and state variables aren't
# populated yet. Don't want to use init or ready because they're
# too close to _init and _ready so we're going with setup
func setup():
# Only add timout node if timer value was specified.
if(timeout_seconds > 0.0):
print("init timer...")
state_timeout = Timer.new()
state_timeout.wait_time = timeout_seconds
state_timeout.one_shot = true
@ -34,20 +37,31 @@ func _init():
#add_child(state_timeout)
#get_tree().get_root().add_child(state_timeout)
#TODO: Need to figure out how to add this to tree
print ("State init called for no reason?")
#modifier = StateModifier.new()
#Hopefully this passes by reference.
func copy(state: State) -> void:
state.name = name
return
func enter() -> void:
pass
print("Got call to enter state ", name)
if state_timeout != null:
print(name, "-Starting Timer")
state_timeout.start()
emit_signal("state_entered")
return
func exit() -> void:
pass
emit_signal("state_exited")
return
func process_input(_event: InputEvent) -> String:
return ''
func process_frame(_delta: float) -> String:
return ''
func process_physics(_delta: float) -> String:
return ''
# Disable to test whether actually needed.
#func process_input(_event: InputEvent) -> String:
# return ''
#
#func process_frame(_delta: float) -> String:
# return ''
#
#func process_physics(_delta: float) -> String:
# return ''

View File

@ -28,142 +28,27 @@ var jerk: float
var physics_modifier :StateModifier
##TODO: Deprecate this useless fool!
var speed_multiplier: float = 1.0
# Not sure if this should be here. probably not
export(Array, String) var animation_sequence
signal frame_reached(state_name, animation_name, frame_number)
# can't remember what this did
export(Dictionary) var emitter_frame_subscriptions
var frame_signal_emitted: bool = false
var animation_finished: bool = false
# this just wouldn't work well. Maybe I can try a resource
# export(Array, NodePath) var transition_state_nodes
#TODO: I think these two variables accidentally serve the same purpose
# I think one was intended to be a string of the current animation name.
var animation_index: int = 0
var current_animation_sequence: int = 0
var animation_suffix: String = '';
var mod_animation_sequence = [PoolStringArray()]
var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
var animations: AnimatedSprite
var move_component: MovementComponent
var parent: KinematicBody2D
#animation_name :String, frame_number : int, animation_sequence :Array
var previous_animation_name : String
var previous_state_frame_number : int
var previous_state_name: String
var previous_speed_multiplier: float
var modifier: StateModifier
# If called, this will attempt to make the most appropriate animation change
# would likely be triggered from an animation sequence finishing or a
# modifier being applied/removed outside of enter/exit transitions.
func update_animation(enter_frame := 0, index := 0, suffix := ''):
## TODO:
# Need to find a way to attempt to keep and transfer the Index or frame
#
# if clear_modifier:
# print("Goodbye Modifiers!")
# modifier = null
# if modifier:
# if modifier.state_timeout and modifier.timeout_seconds == 0:
# modifier = null
# By Default, we build an animation sequence off of this state's before checking
# for modifiers
mod_animation_sequence.clear()
mod_animation_sequence.append_array(animation_sequence)
# Reset animation suffix in case there isn't one
animation_suffix = suffix
animation_index = index
current_animation_sequence = animation_index
#var enter_animation = ''
#var enter_frame = 0
if modifier != null:
# if modifier.modifier_type == modifier.TYPE.EXIT_ANIMATION:
# #print("OHHH Modifier Applies! ", modifier.animation_name)
# mod_animation_sequence.push_front(modifier.animation_name)
# enter_frame = modifier.starting_frame
match modifier.modifier_type:
modifier.TYPE.EXIT_ANIMATION:
mod_animation_sequence.push_front(modifier.animation_name)
enter_frame = modifier.starting_frame
modifier.TYPE.ANIMATION_SUFFIX:
if animations.frames.has_animation(mod_animation_sequence[animation_index] + modifier.animation_name):
animation_suffix = modifier.animation_name
else:
print("Warning!: Modifier attempting to apply suffix that doesn't exist ",
mod_animation_sequence[animation_index] + modifier.animation_name)
modifier.TYPE.REPLACE_ANIMATION:
#animations.play(modifier_stack_ref[i].animation_name)
#animations.frame = modifier_stack_ref[i].starting_frame
mod_animation_sequence.clear()
mod_animation_sequence.push_back(modifier.animation_name)
enter_frame = modifier.starting_frame
# Some safety checks with supplied update parameters
if animation_index != 0:
if mod_animation_sequence.size() < animation_index + 1:
if debug_state:
print("Warning!: attempting to set to non-existant index ")
animation_index = 0
current_animation_sequence = animation_index
if animations.frames.has_animation(mod_animation_sequence[animation_index] + animation_suffix) == false:
if debug_state:
print("Warning!: Animation doesn't exist! ")
if enter_frame != 0:
if animations.frames.get_frame_count(animations.animation) != animations.frames.get_frame_count(mod_animation_sequence[animation_index] + animation_suffix):
if debug_state:
print("Warning!: attempting to set a mismatched frame ")
enter_frame = 0
if mod_animation_sequence.size() > 0:
if debug_state:
print("Starting Animation: " , mod_animation_sequence[animation_index] + animation_suffix)
animations.play(mod_animation_sequence[animation_index] + animation_suffix)
#TODO: maybe check current animatio has this frame
animations.frame = enter_frame
else:
print("Error! Resolved to empty animation sequence!?")
return
func enter() -> void:
if debug_state:
print(parent.name, " entering State: ", self.name)
move_component.current_movement_state = self.name
emit_signal("state_entered")
#modifier_stack_ref = state_modifiers
update_animation()
# Call parent class enter
.enter()
# Reset movespeed counters
#move_component.momentum.x = move_speed_modifier
jerk = 0
return
func exit() -> void:
emit_signal("state_exited")
# animations.disconnect("animation_finished", self, "_on_AnimatedSprite_animation_finished")
#modifier = null
return
func transfer_modifiers(exiting_state_modifier : StateModifier):
if modifier == null: # We have no existing modifier applied.
match exiting_state_modifier.modifier_type:
@ -177,262 +62,3 @@ func transfer_modifiers(exiting_state_modifier : StateModifier):
else:
print("Insert modifier merge function here...")
func process_input(_event: InputEvent) -> String:
return ''
func process_animations():
if modifier != null:
if modifier.state_timeout and modifier.state_timeout.time_left == 0:
print("Expired Modifier, updating animation.")
#modifier = null
match modifier.modifier_type:
modifier.TYPE.ANIMATION_SUFFIX:
# Attempt to seemlessly transition animations.
modifier = null
update_animation(animations.frame,animation_index)
modifier.TYPE.REPLACE_ANIMATION:
if debug_state:
print("I don't have anything for replacements yet.")
modifier = null
update_animation()
_:
modifier = null
return
# We have no more sequence animations and the current one doesn't loop
# we do this to prevent the default idle animation from playing.
##TODO: between this and the signal based iterator I get some really strange behavior
if animation_index >= mod_animation_sequence.size() and animations.frames.get_animation_loop(
animations.animation) == false:
#print(animations.animation, " Animation Stopped")
animations.stop()
#animation_finished = true
elif mod_animation_sequence.size() > animation_index and current_animation_sequence != animation_index:
#TODO: why was I doing this
# if animation_index >= mod_animation_sequence.size():
# animation_index = 0
##TODO: Add a safety check here.
animations.play(mod_animation_sequence[animation_index] + animation_suffix)
if debug_state:
print("An animation sequence: ", mod_animation_sequence[animation_index - 1], " -> ",
animations.animation , " (", animation_index, ")")
current_animation_sequence = animation_index
##TODO: Could probably add some more checks here.
# Singal based frame call.
if emitter_frame_subscriptions.has(animations.frame):
if emitter_frame_subscriptions[animations.frame] == animations.animation:
if frame_signal_emitted == false:
emit_signal("frame_reached", self.name, animations.animation, animations.frame)
# Try to only so this once.
frame_signal_emitted = true
else:
frame_signal_emitted = false
func process_frame(_delta: float) -> String:
return ''
func process_physics(_delta: float) -> String:
move_actor_as_desired(_delta)
return ''
#func _on_AnimatedSprite_animation_finished():
# if animations.frames.get_animation_loop(animations.animation) == false:
# animation_index += 1
func move_actor_as_desired(delta: float, x_move_direction_override: float = 0):
var _move_speed = move_speed
var _move_speed_modifier = move_speed_modifier
var _move_modifier_move_acceleration = move_modifier_move_acceleration
var _move_acceleration = move_acceleration
var _jerk_factor = jerk_factor
var _gravity = gravity
if physics_modifier:
#physics_modifier.modifier_properties.jerk_factor
#print(physics_modifier.name)
#UiManager.debug_text = physics_modifier.name + str(round(adjusted_move_speed))
var mod_props :ModifierProperties = physics_modifier.get_modifier_properties()
if mod_props.move_speed != 0 and mod_props.directional_modifier == false:
_move_speed = mod_props.move_speed
_move_speed_modifier += mod_props.move_speed_modifier
_move_acceleration += mod_props.move_acceleration
_move_modifier_move_acceleration += mod_props.move_modifier_move_acceleration
_jerk_factor += mod_props.jerk_factor
var help_me_not_be_dumb = ''
# Allow us to bump out of halt.
if _move_speed == 0 and move_component.desired_movement_vector.x != 0:
_move_speed = abs(move_component.desired_movement_vector.x)
# Determine or physics movement direction
var current_x_velocity = move_component.velocity.x #move_component.velocity.x
var move_direction = 0.0
# Determine movement direction if we have momentum
if move_component.momentum.x != 0:
if x_move_direction_override == 0:
move_direction = sign(current_x_velocity)
# if move_component.desired_movement_vector.x != 0:
# # set the move direction to the desired direction
# move_direction = move_component.desired_movement_vector.x
# else:
# # Set move direction to the transform direction
# move_direction = parent.transform.x.x
else:
move_direction = x_move_direction_override
else: # No current momentum in place
if x_move_direction_override == 0:
move_direction = move_component.desired_movement_vector.x
else:
move_direction = x_move_direction_override
## TODO: I hate that I have to do this check again.
if physics_modifier:
var mod_props :ModifierProperties = physics_modifier.get_modifier_properties()
if mod_props.move_speed != 0 and mod_props.directional_modifier == true:
# Since move_direction is always positive
if sign(move_direction) == sign(mod_props.move_speed):
_move_speed += mod_props.move_speed
else:
_move_speed -= mod_props.move_speed
if sign(move_direction) == 0:
move_direction = sign(mod_props.move_speed) * -1
#print("doing this? ")
# Determine the maximum move speed
var MAX_SPEED :float = 0
var MIN_SPEED :float = 0
if sign(_move_speed_modifier) == -1: # decreased speed modifier
help_me_not_be_dumb += '-SpeedMod'
# Move speed cannot go below zero with modifier applied
MIN_SPEED = _move_speed + _move_speed_modifier
# Poor man's clamp
if MIN_SPEED < 0:
MIN_SPEED = 0
MAX_SPEED = _move_speed
elif sign(_move_speed_modifier) == +1: # increased speed modifier
help_me_not_be_dumb += '+SpeedMod'
MIN_SPEED = _move_speed
MAX_SPEED = _move_speed + _move_speed_modifier
else: # physics won't apply here
help_me_not_be_dumb += '_Speed' # Neutral Speed
MIN_SPEED = _move_speed
MAX_SPEED = _move_speed
# get the latest aggregate acceleration
# If we have any acceleration applying
if (_move_modifier_move_acceleration + _move_acceleration) != 0:
# The acceleration is differant
# Perhaps it would be better to trigger this on a difference in modifier but they usually go together.
if abs(move_component.acceleration.x) != abs(_move_modifier_move_acceleration + _move_acceleration):
if move_direction:
print("Acceleration changed.", abs(move_component.acceleration.x), "-", (_move_modifier_move_acceleration + _move_acceleration))
move_component.acceleration.x = _move_modifier_move_acceleration + _move_acceleration
# If we're no longer tryingg to move int the direction of our movement and momentum.
if sign(current_x_velocity) != sign(move_component.desired_movement_vector.x) and move_component.momentum.x != 0:
if sign(_move_speed_modifier) == -1 : # decreased speed modifier
# Maybe we can compare the direction of the acceleration
# The direction of the acceleration should usually be positive at this point.
# when the modifier is negative.
if sign(move_direction) == sign(current_x_velocity):
if sign(move_component.acceleration.x) == sign(move_component.momentum.x):
print("Whoh Woah")
# Flip the direction of the acceleration
move_component.acceleration.x *= -1
if (sign(move_component.desired_movement_vector.x) == -1 and
sign(current_x_velocity) == 1) or (sign(move_component.desired_movement_vector.x) == -1 and
sign(current_x_velocity) == -1):
print("be more opposite")
# if sign(_move_speed_modifier) == 1: # increased speed modifier
# print("faster faster.")
elif sign(move_component.desired_movement_vector.x) == sign(current_x_velocity) and move_component.momentum.x != 0:
if sign(move_component.acceleration.x) != sign(move_component.momentum.x) and x_move_direction_override == 0:
print("Step it up!")
# Flip the direction of the acceleration
move_component.acceleration.x *= -1
# Apply momentum and acceleration if a modifer exists
if move_component.momentum.x <= 0 and _move_speed_modifier !=0:
#if we're trying to move but we have no momentum applied currently
#if move_component.desired_movement_vector.x != 0:
if move_direction:
move_component.acceleration.x = _move_modifier_move_acceleration + _move_acceleration
##TODO: I don't know where I should actually set the momentum. :
if sign(_move_speed_modifier) == -1: # decreased speed modifier
move_component.momentum.x = 0
elif sign(_move_speed_modifier) == +1: # increased speed modifier
##TODO: in most cases this should only be applied once. need to find a way to warn against this.
move_component.momentum.x = abs(move_speed_modifier)
print("momentum applied!")
# Reverse the accelerations if we carry over momentum but the modifier no longer applies.
if move_component.momentum.x > 0 and _move_speed_modifier == 0:
if sign(move_component.acceleration.x) == sign(move_component.momentum.x):
print("Whoh Woah your done.")
# Flip the direction of the acceleration
move_component.acceleration.x *= -1
# We're going to adjust our move speed only to the modifier
move_component.momentum.x += move_component.acceleration.x * delta
jerk += _jerk_factor * delta
var new_move_speed :float = 0
if sign(_move_speed_modifier) == -1: # decreased speed modifier
# MIN_SPEED = _move_speed + _move_speed_modifier
# MAX_SPEED = _move_speed
move_component.momentum.x = clamp(move_component.momentum.x, 0, abs(_move_speed_modifier))
# new_move_speed = (_move_speed + _move_speed_modifier ) + (sign(_move_speed_modifier) * -1 * move_component.momentum.x) # + jerk
new_move_speed = MIN_SPEED + (sign(_move_speed_modifier) * -1 * move_component.momentum.x) # + jerk
elif sign(_move_speed_modifier) == +1: # increased speed modifier
# MIN_SPEED = _move_speed
# MAX_SPEED = _move_speed + _move_speed_modifier
move_component.momentum.x = clamp(move_component.momentum.x, 0, _move_speed_modifier )
new_move_speed = _move_speed + move_component.momentum.x # + jerk
else: # physics won't apply here
# move_component.acceleration.x = 0
# move_component.momentum.x = 0
# new_move_speed = _move_speed
move_component.momentum.x = clamp(move_component.momentum.x, 0, MIN_SPEED )
new_move_speed = _move_speed + move_component.momentum.x # + jerk
#new_move_speed = clamp(new_move_speed, MIN_SPEED, MAX_SPEED)
var sim_move_speed = (MIN_SPEED + (sign(_move_speed_modifier) * -1 * move_component.momentum.x))
# if move_component.momentum.x != 0:
if true:
UiManager.debug_text = ( "Mod(" + str(sign(_move_speed_modifier)) + ") Dir(" + str(move_direction) + ") Vel(" + str(sign(current_x_velocity)) + ") Mov(" + str(sign(move_component.desired_movement_vector.x)) +
")\nNS:" + str(round(sim_move_speed)) + #" Z:" + str(sign(_move_speed_modifier) * -1 * move_component.momentum.x) +
"\nS:" + str(round(_move_speed + _move_speed_modifier)) + ",M" + str(round(move_component.momentum.x)) +
",A" + str(round(move_component.acceleration.x)) +
"\nVel:" + str(round(move_component.velocity.x)) + "Min:" + str(round(MIN_SPEED)) + ",Max:" + str(round(MAX_SPEED))
) # str(round(jerk))
move_component.sim_velocity.x = move_direction * sim_move_speed
#print(adjusted_move_speed, ",", new_move_speed, ",", jerk)
#print(new_move_speed, " ", adjusted_move_speed)
move_component.velocity.y += _gravity * delta
#parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1))
#print(speed_multiplier)
# move_component.velocity.x = move_component.desired_movement_vector.x * _move_speed
move_component.velocity.x = move_direction * new_move_speed
#move_component.velocity = parent.move_and_slide(move_component.velocity, Vector2.UP)
var snap = Vector2.DOWN * 8
if move_component.velocity.y < -8:
snap = Vector2.ZERO
move_component.velocity = parent.move_and_slide_with_snap(move_component.velocity, snap , Vector2.UP, true)

View File

@ -7,36 +7,61 @@ export var debug_state_machine: bool = false
#export (Reference) var states # Doesn't work
#var starting_state: State
signal state_changed(old_state_name, new_state)
var current_state: State
#var state_modifiers: Array
export(Dictionary) var states :Dictionary
export var starting_state_name = 'default'
export(Array,Resource) var states
var states_index :Dictionary
# Initialize the state machine by giving each child state a reference to the
# parent object it belongs to and enter the default starting_state.
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
func _init() -> void:
print ("init state machine.")
for s in states.keys():
var this_state = states.s
func _ready():
print ("ready state machine.")
for s in states:
print ("sname: ", s.name)
var this_state = s
if this_state is State:
if debug_state_machine:
print("Initializing State Node: ", s)
this_state.debug_state = true
print("Adding state ", this_state.name)
#check for empty state name
if this_state.name != '':
#check for unique state name
if !(states_index.has(this_state.name)):
# call setup
this_state.setup()
if debug_state_machine:
print("Initializing State Node: ", s)
this_state.debug_state = true
if this_state.state_timeout != null:
add_child(this_state.state_timeout)
# Add to state index
states_index[this_state.name] = this_state
else:
push_error("Multiple states with same name in: ")
else:
print("State missing name in: " )
if states_index.has(starting_state_name):
change_state(states_index[starting_state_name])
else:
push_error("State machine cannot find starting state: " + starting_state_name)
# Change to the new state by first calling any exit logic on the current state.
func change_state(new_state: State) -> void:
var current_state_name :String
if current_state:
current_state.exit()
current_state_name = current_state.name
current_state = new_state
current_state.enter()
emit_signal("state_changed",current_state_name,current_state)
# if(state_modifiers.size() > 0 and debug_state_machine):
# print("Active Modifiers:")
# for mods in state_modifiers:
@ -44,23 +69,29 @@ func change_state(new_state: State) -> void:
func change_to_known_state(new_state_name: String) -> void:
if new_state_name.empty() == false:
if states.has(new_state_name):
change_state(states[new_state_name])
if states_index.has(new_state_name):
change_state(states_index[new_state_name])
else:
push_warning("Attempt to switch state to unknown: " + new_state_name + get_parent().name)
change_state(states["default"])
push_warning(get_parent().name + ": Attempt to switch state to unknown: " + new_state_name)
change_state(states_index["default"])
# Pass through functions for the Player to call,
# handling state changes as needed.
func process_physics(delta: float) -> void:
change_to_known_state( current_state.process_physics(delta) )
func get_state_reference(state_name: String) -> State:
if states_index.has(state_name):
return states_index[state_name]
return null
func process_input(event: InputEvent) -> void:
var new_state = current_state.process_input(event)
if new_state:
change_state(new_state)
func process_frame(delta: float) -> void:
var new_state = current_state.process_frame(delta)
if new_state:
change_state(new_state)
# Disable to test whether actually needed.
## Pass through functions for the Player to call,
## handling state changes as needed.
#func process_physics(delta: float) -> void:
# change_to_known_state( current_state.process_physics(delta) )
#
#func process_input(event: InputEvent) -> void:
# var new_state = current_state.process_input(event)
# if new_state:
# change_state(new_state)
#
#func process_frame(delta: float) -> void:
# var new_state = current_state.process_frame(delta)
# if new_state:
# change_state(new_state)

View File

@ -1,146 +1,3 @@
class_name StateMachineAnimatedActor extends StateMachine
func change_state(new_state: State) -> void:
if new_state.state_ready == false:
# Don't transition to unready state
return
if current_state:
current_state.exit()
# Set parameters for information
if new_state is StateAnimatedActor and current_state is StateAnimatedActor:
set_previous_animation( current_state, new_state)
if current_state.modifier: # Current state has a modifier
new_state.transfer_modifiers(current_state.modifier)
current_state.modifier = null
if current_state.physics_modifier: # Current state has a physics modifier
new_state.physics_modifier = current_state.physics_modifier
current_state.physics_modifier = null
current_state = new_state
current_state.enter()
# if(state_modifiers.size() > 0 and debug_state_machine):
# print("Active Modifiers:")
# for mods in state_modifiers:
# print(mods.name)
func set_previous_animation( old_state: StateAnimatedActor, new_state: StateAnimatedActor ) -> void:
# added this to help prevent nul index crashes. (Usually because of signal based state changes.)
if old_state.mod_animation_sequence:
new_state.previous_animation_name = old_state.mod_animation_sequence[old_state.current_animation_sequence]
new_state.previous_state_frame_number = old_state.animations.frame
new_state.previous_state_name = old_state.name
new_state.previous_speed_multiplier = old_state.speed_multiplier
#animation_name :String, frame_number : int, animation_sequence :Array
return
# Initialize the state machine by giving each child state a reference to the
# parent object it belongs to and enter the default starting_state.
func init_animated_actor(parent: KinematicBody2D, animations: AnimatedSprite, move_component: MovementComponent) -> void:
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
#states["default"] = StateAnimatedActor.new()
for s in states.keys():
var child = states[s]
if child is StateAnimatedActor:
if debug_state_machine:
print("Initializing State Node for ", parent.name, ": ", s)
child.debug_state = true
child.parent = parent
child.animations = animations
child.move_component = move_component
child.name = s
if states.has("default"):
print("I still haz default state")
change_state(states.default)
# current_state = states.default
# if current_state is StateAnimatedActor:
# current_state.animations = animations
# current_state.parent = parent
# current_state.move_component = move_component
# current_state.enter()
# #current_state.set_script("res://lib/templates/Actor/states/idle.gd")
# Initialize to the default state
#change_state(get_node(starting_state))
#change_state(states.default)
func process_frame(delta: float) -> void:
# Check the state modifiers for timeouts, and maybe more conditions later
# If the modifier is no longer valid, pop it from the stack.
# We could iterate through a whole list of states but I'm not sure i want
# states to be that complex.
# var current_anim_state :StateAnimatedActor = current_state
# if state_modifiers.empty() == false:
# for i in range(state_modifiers.size()):
# # if this modifer is a timer based one
# if state_modifiers[i].state_timeout.time_left == 0 and state_modifiers[i].timeout_seconds !=0:
# # Need to do extra stuff if it's an animation based one
# if state_modifiers[i].modifier_type == "Animation Suffix":
# if debug_state_machine:
# print("State Modifier Timeout: ", state_modifiers[i].name, " -> ", state_modifiers[i].animation_name)
# # Reset animation suffix
# current_anim_state.animation_suffix = ''
# # Get the current frame of animation
# var current_frame = current_anim_state.animations.frame
#
# # Set the animation index to the current one
# current_anim_state.animation_index = current_anim_state.current_animation_sequence
# #current_anim_state.current_animation_sequence
# #current_anim_state.animations.play()
#
# current_anim_state.animations.play(
# current_anim_state.mod_animation_sequence[current_anim_state.animation_index])
# # Try to set the current frame to the same as before.
# current_anim_state.animations.frames.frames.size() >= current_frame
# current_anim_state.animations.frame = current_frame
#
# if debug_state_machine:
# print("Pop State Modifier: ", state_modifiers[i].name)
# state_modifiers.pop_at(i)
if current_state is StateAnimatedActor:
current_state.process_animations()
change_to_known_state( current_state.process_frame(delta) )
func _on_AnimatedSprite_animation_finished():
# if debug_state_machine:
# print("Stop!!!!!")
##TODO:
# It's hard to pop an exit animation off when it's stacked with another kind of animation.
# for i in state_modifiers.size():
# if state_modifiers[i].modifier_type == "Exit Animation":
# #print("Time to pop state modifer: ", state_modifiers[i].animation_name, current_state.animation_suffix, " <-> ", current_state.animations.animation + current_state.animation_suffix)
# if (state_modifiers[i].animation_name + current_state.animation_suffix) == current_state.animations.animation:
# print("Time to pop state modifer: ", state_modifiers[i].animation_name, current_state.animation_suffix, " <-> ", current_state.animations.animation )
# print(current_state.mod_animation_sequence)
# state_modifiers.pop_at(i)
# current_state.animation_index += 1
# break
# if current_state is StateAnimatedActor:
# current_state.animation_finished = true
if current_state.animations.frames.get_animation_loop(
current_state.animations.animation) == false:
#print("Stop!!!!!", current_state.animation_sequence.size(), " - ", current_state.animation_index)
if current_state.animation_sequence.size() > 0:
#print("<-- next anim.")
current_state.animation_index += 1
if current_state.animation_index >= current_state.animation_sequence.size():
#print("Stop!!!!!")
current_state.animation_finished = true
## I'm not sure I need a subtype anymore

View File

@ -1,31 +1,50 @@
[gd_scene load_steps=4 format=2]
[gd_scene load_steps=6 format=2]
[ext_resource path="res://lib/classes/state_machine_animated_actor.gd" type="Script" id=2]
[ext_resource path="res://src/classes/movement_component.gd" type="Script" id=5]
[ext_resource path="res://lib/classes/state_machine.gd" type="Script" id=2]
[ext_resource path="res://lib/classes/state_animated_actor.gd" type="Script" id=4]
[ext_resource path="res://lib/classes/movement_state_receiver.gd" type="Script" id=5]
[ext_resource path="res://lib/classes/actor.gd" type="Script" id=8]
[sub_resource type="Resource" id=1]
script = ExtResource( 4 )
debug_state = false
timeout_seconds = 2.0
name = "idle"
move_speed = 60.0
move_acceleration = 0.0
move_speed_modifier = 0.0
move_modifier_move_acceleration = 0.0
jerk_factor = 0.0
animation_sequence = [ "idle", "Max Height" ]
emitter_frame_subscriptions = {
}
[node name="ActorTemplate" type="KinematicBody2D"]
collision_layer = 2
script = ExtResource( 8 )
[node name="AnimatedSprite" type="AnimatedSprite" parent="."]
[node name="AnimatedSprite_StateReceiver" type="AnimatedSprite" parent="."]
__meta__ = {
"_aseprite_wizard_config_": {
"layer": "",
"o_ex_p": "BG",
"o_folder": "res://assets/actors/players/playerE",
"o_name": "template-jump",
"o_ex_p": "-.*",
"o_folder": "",
"o_name": "",
"only_visible": true,
"op_exp": true,
"sf_name": "",
"slice": "",
"source": "/home/relay01/Assets/Library/Asset Packs 1-5/Asset Packs 1-4 (final)/Asset Pack-V1/Player Jump/player jump 48x48.aseprite"
"source": ""
}
}
[node name="movement_component" type="Node" parent="."]
[node name="Movement_StateReceiver" type="Node" parent="."]
script = ExtResource( 5 )
callable_state_machine = NodePath("../Movement_StateMachine")
[node name="movement_state_machine" type="Node" parent="."]
[node name="Movement_StateMachine" type="Node" parent="."]
script = ExtResource( 2 )
starting_state_name = "idle"
states = [ SubResource( 1 ) ]
[node name="SE_Player" type="AudioStreamPlayer" parent="."]

View File

@ -14,6 +14,11 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://lib/classes/actor.gd"
}, {
"base": "AnimatedSprite",
"class": "AnimatedSprite_StateReceiver",
"language": "GDScript",
"path": "res://lib/classes/animated_sprite_state_receiver.gd"
}, {
"base": "",
"class": "GitAPI",
"language": "NativeScript",
@ -54,6 +59,11 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://src/classes/movement_component.gd"
}, {
"base": "Node",
"class": "Movement_StateReceiver",
"language": "GDScript",
"path": "res://lib/classes/movement_state_receiver.gd"
}, {
"base": "Resource",
"class": "State",
"language": "GDScript",
@ -81,6 +91,7 @@ _global_script_classes=[ {
} ]
_global_script_class_icons={
"Actor": "",
"AnimatedSprite_StateReceiver": "",
"GitAPI": "",
"HealthComponent": "",
"HealthPickup": "",
@ -89,6 +100,7 @@ _global_script_class_icons={
"ModifierProperties": "",
"Modifier_Receiver": "",
"MovementComponent": "",
"Movement_StateReceiver": "",
"State": "",
"StateAnimatedActor": "",
"StateMachine": "",
@ -138,6 +150,30 @@ enabled=PoolStringArray( "res://addons/AsepriteWizard/plugin.cfg" )
common/drop_mouse_on_gui_input_disabled=true
[importer_defaults]
texture={
"compress/bptc_ldr": 0,
"compress/hdr_mode": 0,
"compress/lossy_quality": 0.7,
"compress/mode": 0,
"compress/normal_map": 0,
"detect_3d": true,
"flags/anisotropic": false,
"flags/filter": false,
"flags/mipmaps": false,
"flags/repeat": 0,
"flags/srgb": 2,
"process/HDR_as_SRGB": false,
"process/fix_alpha_border": true,
"process/invert_color": false,
"process/normal_map_invert_y": false,
"process/premult_alpha": false,
"size_limit": 0,
"stream": false,
"svg/scale": 1.0
}
[input]
ui_accept={

View File

@ -1,5 +1,23 @@
[gd_scene load_steps=2 format=2]
[gd_scene load_steps=3 format=2]
[ext_resource path="res://lib/templates/Actor/ActorTemplate.tscn" type="PackedScene" id=1]
[ext_resource path="res://assets/actors/players/playerE/PlayerE_SpriteFrames.tres" type="SpriteFrames" id=2]
[node name="PlayerE" instance=ExtResource( 1 )]
actor_type = "Player"
[node name="AnimatedSprite_StateReceiver" parent="." index="0"]
frames = ExtResource( 2 )
__meta__ = {
"_aseprite_wizard_config_": {
"layer": "",
"o_ex_p": "-.*",
"o_folder": "res://assets/actors/players/playerE",
"o_name": "run",
"only_visible": true,
"op_exp": true,
"sf_name": "PlayerE_SpriteFrames",
"slice": "",
"source": "/home/relay01/Assets/Library/Asset Packs 1-5/Asset Packs 1-4 (final)/Asset Pack-V1/Player Run/player run 48x48.aseprite"
}
}

View File

@ -11,6 +11,8 @@ extends Node
export var debug_component: bool = false
onready var current_state = StateAnimatedActor.new()
onready var desired_movement_vector: Vector2 = Vector2(0,0)
var current_movement_state:String