diff --git a/Main.tscn b/Main.tscn index 239fc96..bb6227a 100644 --- a/Main.tscn +++ b/Main.tscn @@ -1,4 +1,6 @@ -[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] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 208, 20 ) @@ -15,3 +17,6 @@ margin_bottom = 200.0 [node name="CollisionShape2D" type="CollisionShape2D" parent="ColorRect/StaticBody2D"] position = Vector2( 208, 20 ) shape = SubResource( 1 ) + +[node name="ActorTemplate" parent="." instance=ExtResource( 1 )] +position = Vector2( 168, 32 ) diff --git a/assets/actors/players/playerE/new_spriteframes.tres b/assets/actors/players/playerE/new_spriteframes.tres new file mode 100644 index 0000000..1d1e9ea --- /dev/null +++ b/assets/actors/players/playerE/new_spriteframes.tres @@ -0,0 +1,103 @@ +[gd_resource type="SpriteFrames" load_steps=20 format=2] + +[sub_resource type="StreamTexture" id=1] +load_path = "res://.import/template-jump.png-99a30c82ac7d2ef1ff0cd02512f1ee55.stex" + +[sub_resource type="AtlasTexture" id=2] +atlas = SubResource( 1 ) +region = Rect2( 0, 48, 48, 48 ) + +[sub_resource type="StreamTexture" id=3] +load_path = "res://.import/template-jump.png-99a30c82ac7d2ef1ff0cd02512f1ee55.stex" + +[sub_resource type="AtlasTexture" id=4] +atlas = SubResource( 3 ) +region = Rect2( 0, 48, 48, 48 ) + +[sub_resource type="StreamTexture" id=5] +load_path = "res://.import/template-jump.png-99a30c82ac7d2ef1ff0cd02512f1ee55.stex" + +[sub_resource type="AtlasTexture" id=6] +atlas = SubResource( 5 ) +region = Rect2( 0, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=7] +atlas = SubResource( 1 ) +region = Rect2( 0, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=8] +atlas = SubResource( 3 ) +region = Rect2( 0, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=9] +atlas = SubResource( 5 ) +region = Rect2( 0, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=10] +atlas = SubResource( 1 ) +region = Rect2( 48, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=11] +atlas = SubResource( 3 ) +region = Rect2( 48, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=12] +atlas = SubResource( 5 ) +region = Rect2( 48, 0, 48, 48 ) + +[sub_resource type="StreamTexture" id=13] +flags = 4 +load_path = "res://.import/template.png-4288ca8cd0abcf2db7d00f52e5ba2170.stex" + +[sub_resource type="AtlasTexture" id=14] +flags = 4 +atlas = SubResource( 13 ) +region = Rect2( 0, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=15] +flags = 4 +atlas = SubResource( 13 ) +region = Rect2( 48, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=16] +flags = 4 +atlas = SubResource( 13 ) +region = Rect2( 96, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=17] +flags = 4 +atlas = SubResource( 13 ) +region = Rect2( 0, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=18] +flags = 4 +atlas = SubResource( 13 ) +region = Rect2( 48, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=19] +flags = 4 +atlas = SubResource( 13 ) +region = Rect2( 96, 48, 48, 48 ) + +[resource] +animations = [ { +"frames": [ SubResource( 2 ), SubResource( 4 ), SubResource( 6 ) ], +"loop": true, +"name": "Jump Down", +"speed": 10.0 +}, { +"frames": [ SubResource( 7 ), SubResource( 8 ), SubResource( 9 ) ], +"loop": true, +"name": "Jump up", +"speed": 10.0 +}, { +"frames": [ SubResource( 10 ), SubResource( 11 ), SubResource( 12 ) ], +"loop": true, +"name": "Max Height", +"speed": 10.0 +}, { +"frames": [ SubResource( 14 ), SubResource( 15 ), SubResource( 16 ), SubResource( 17 ), SubResource( 17 ), SubResource( 18 ), SubResource( 14 ), SubResource( 19 ), SubResource( 19 ), SubResource( 19 ) ], +"loop": true, +"name": "default", +"speed": 11.0 +} ] diff --git a/assets/actors/players/playerE/template-jump.png b/assets/actors/players/playerE/template-jump.png new file mode 100644 index 0000000..4c10a98 Binary files /dev/null and b/assets/actors/players/playerE/template-jump.png differ diff --git a/assets/actors/players/playerE/template-jump.png.import b/assets/actors/players/playerE/template-jump.png.import new file mode 100644 index 0000000..58d396d --- /dev/null +++ b/assets/actors/players/playerE/template-jump.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/template-jump.png-99a30c82ac7d2ef1ff0cd02512f1ee55.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/actors/players/playerE/template-jump.png" +dest_files=[ "res://.import/template-jump.png-99a30c82ac7d2ef1ff0cd02512f1ee55.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 diff --git a/assets/actors/players/playerE/template.png b/assets/actors/players/playerE/template.png new file mode 100644 index 0000000..4f33161 Binary files /dev/null and b/assets/actors/players/playerE/template.png differ diff --git a/assets/actors/players/playerE/template.png.import b/assets/actors/players/playerE/template.png.import new file mode 100644 index 0000000..bf2593c --- /dev/null +++ b/assets/actors/players/playerE/template.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/template.png-4288ca8cd0abcf2db7d00f52e5ba2170.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/actors/players/playerE/template.png" +dest_files=[ "res://.import/template.png-4288ca8cd0abcf2db7d00f52e5ba2170.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=true +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 diff --git a/lib/classes/actor.gd b/lib/classes/actor.gd index 6cbad85..81f9781 100644 --- a/lib/classes/actor.gd +++ b/lib/classes/actor.gd @@ -10,13 +10,14 @@ 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_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,7 +28,7 @@ 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_state_machine.init_animated_actor(self) movement_component.attack_function = funcref(self, "attack") # movement_component.player_number = player_number @@ -55,7 +56,7 @@ func _process(delta: float) -> void: movement_component.process(delta) movement_state_machine.process_frame(delta) # PlayerInfo.player_position = global_position - play_sound_frame(movement_animations.animation , movement_animations.frame) + #play_sound_frame(movement_animations.animation , movement_animations.frame) var last_sound_frame_animation: String = '' diff --git a/lib/classes/animated_sprite_state_receiver.gd b/lib/classes/animated_sprite_state_receiver.gd new file mode 100644 index 0000000..e7859d5 --- /dev/null +++ b/lib/classes/animated_sprite_state_receiver.gd @@ -0,0 +1,202 @@ +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") + +# 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') + +# 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 self.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 current_state.debug_state: + print("Warning!: attempting to set to non-existant index ") + animation_index = 0 + current_animation_sequence = animation_index + + if self.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 self.animations.frames.get_frame_count(self.animations.animation) != self.animations.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) + self.animations.play(mod_animation_sequence[animation_index] + animation_suffix) + #TODO: maybe check current animatio has this frame + self.animations.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(self.animations.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 self.animations.frames.get_animation_loop( + self.animations.animation) == false: + #print(animations.animation, " Animation Stopped") + self.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. + self.animations.play(mod_animation_sequence[animation_index] + animation_suffix) + if current_state.debug_state: + print("An animation sequence: ", mod_animation_sequence[animation_index - 1], " -> ", + self.animations.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 +# else: +# push_warning("Received non animated Actor state.") + current_state = new_state + diff --git a/lib/classes/state.gd b/lib/classes/state.gd index 994aede..3ee7924 100644 --- a/lib/classes/state.gd +++ b/lib/classes/state.gd @@ -4,15 +4,15 @@ extends Resource export var debug_state: bool = false export var timeout_seconds: float = 0.0 -signal state_entered() -signal state_exited() +#signal state_entered() +#signal state_exited() # Declare member variables here. Examples: 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,10 +37,18 @@ 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: + print("Got call to enter state ", name) + if state_timeout != null: + print(name, "-Starting Timer") + state_timeout.start() pass func exit() -> void: diff --git a/lib/classes/state_animated_actor.gd b/lib/classes/state_animated_actor.gd index cd5355a..81235b2 100644 --- a/lib/classes/state_animated_actor.gd +++ b/lib/classes/state_animated_actor.gd @@ -28,129 +28,22 @@ 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() + print(" entering State: ", self.name) # Reset movespeed counters #move_component.momentum.x = move_speed_modifier @@ -158,12 +51,6 @@ func enter() -> void: 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 +64,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) diff --git a/lib/classes/state_animated_actor_txt.gd b/lib/classes/state_animated_actor_txt.gd new file mode 100644 index 0000000..7f27899 --- /dev/null +++ b/lib/classes/state_animated_actor_txt.gd @@ -0,0 +1,438 @@ +class_name dmod +extends State +## Animation and movement state class +## +## A state intended to control the movement and animation +## functions of a KinimaticBody2D node. Initialized with a +## player, movement node, and kinematicbody2d +## I think if we also had modifier states that transfered along with the enter and entrance of nodes, that would be helpful. +## +## @WIP + +# export (NodePath) var jump_node + +# onready var jump_state: State = get_node(jump_node) + +## Deprecated +# export var animation_name: String + +# Movement Speed in Pixels Per Second +export var move_speed: float = 60 +export var move_acceleration: float = 0 +export var move_speed_modifier: float = 0 +export var move_modifier_move_acceleration: float = 0 +export var jerk_factor: float = 0 + +#var adjusted_move_speed: float +var jerk: float + +var physics_modifier :StateModifier + +##TODO: Deprecate this useless fool! +var speed_multiplier: float = 1.0 + +export(Array, String) var animation_sequence + +signal frame_reached(state_name, animation_name, frame_number) +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() + + # 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: + exiting_state_modifier.TYPE.ANIMATION_SUFFIX: + if debug_state: + print("Transferring Animation Suffix") + modifier = exiting_state_modifier + exiting_state_modifier.TYPE.EXIT_ANIMATION: + if debug_state: + print("Exit Animation: well this was useless.") + 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) diff --git a/lib/classes/state_machine.gd b/lib/classes/state_machine.gd index 48c7d04..32814ae 100644 --- a/lib/classes/state_machine.gd +++ b/lib/classes/state_machine.gd @@ -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,11 +69,11 @@ 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. diff --git a/lib/classes/state_machine_animated_actor.gd b/lib/classes/state_machine_animated_actor.gd index 3b47d50..34251fd 100644 --- a/lib/classes/state_machine_animated_actor.gd +++ b/lib/classes/state_machine_animated_actor.gd @@ -1,42 +1,31 @@ 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 +#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) # 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") +func init_animated_actor(parent: KinematicBody2D) -> void: # for child in get_children(): # if child is StateAnimatedActor: # if debug_state_machine: @@ -55,8 +44,7 @@ func init_animated_actor(parent: KinematicBody2D, animations: AnimatedSprite, mo print("Initializing State Node for ", parent.name, ": ", s) child.debug_state = true child.parent = parent - child.animations = animations - child.move_component = move_component + #child.move_component = move_component child.name = s if states.has("default"): @@ -112,35 +100,4 @@ func process_frame(delta: float) -> void: 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 - - - diff --git a/lib/templates/Actor/ActorTemplate.tscn b/lib/templates/Actor/ActorTemplate.tscn index 87ced12..31e2720 100644 --- a/lib/templates/Actor/ActorTemplate.tscn +++ b/lib/templates/Actor/ActorTemplate.tscn @@ -1,14 +1,26 @@ -[gd_scene load_steps=4 format=2] +[gd_scene load_steps=8 format=2] -[ext_resource path="res://lib/classes/state_machine_animated_actor.gd" type="Script" id=2] +[ext_resource path="res://lib/classes/animated_sprite_state_receiver.gd" type="Script" id=1] +[ext_resource path="res://lib/classes/state_machine.gd" type="Script" id=2] +[ext_resource path="res://assets/actors/players/playerE/new_spriteframes.tres" type="SpriteFrames" id=3] +[ext_resource path="res://lib/classes/state.gd" type="Script" id=4] [ext_resource path="res://src/classes/movement_component.gd" type="Script" id=5] [ext_resource path="res://lib/classes/actor.gd" type="Script" id=8] +[sub_resource type="Resource" id=1] +resource_local_to_scene = true +script = ExtResource( 4 ) +debug_state = true +timeout_seconds = 2.0 +name = "idle" + [node name="ActorTemplate" type="KinematicBody2D"] collision_layer = 2 script = ExtResource( 8 ) -[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +[node name="AnimatedSprite_StateReceiver" type="AnimatedSprite" parent="."] +frames = ExtResource( 3 ) +script = ExtResource( 1 ) __meta__ = { "_aseprite_wizard_config_": { "layer": "", @@ -21,11 +33,14 @@ __meta__ = { "source": "/home/relay01/Assets/Library/Asset Packs 1-5/Asset Packs 1-4 (final)/Asset Pack-V1/Player Jump/player jump 48x48.aseprite" } } +callable_state_machine = NodePath("../movement_state_machine") [node name="movement_component" type="Node" parent="."] script = ExtResource( 5 ) [node name="movement_state_machine" type="Node" parent="."] script = ExtResource( 2 ) +starting_state_name = "idle" +states = [ SubResource( 1 ) ] [node name="SE_Player" type="AudioStreamPlayer" parent="."] diff --git a/project.godot b/project.godot index 06f6957..09f8df3 100644 --- a/project.godot +++ b/project.godot @@ -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", @@ -78,9 +83,15 @@ _global_script_classes=[ { "class": "StateModifier", "language": "GDScript", "path": "res://lib/classes/state_modifier.gd" +}, { +"base": "State", +"class": "dmod", +"language": "GDScript", +"path": "res://lib/classes/state_animated_actor_txt.gd" } ] _global_script_class_icons={ "Actor": "", +"AnimatedSprite_StateReceiver": "", "GitAPI": "", "HealthComponent": "", "HealthPickup": "", @@ -93,7 +104,8 @@ _global_script_class_icons={ "StateAnimatedActor": "", "StateMachine": "", "StateMachineAnimatedActor": "", -"StateModifier": "" +"StateModifier": "", +"dmod": "" } [application] @@ -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={ diff --git a/src/classes/movement_component.gd b/src/classes/movement_component.gd index c02b49e..147683c 100644 --- a/src/classes/movement_component.gd +++ b/src/classes/movement_component.gd @@ -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