Compare commits

..

20 Commits

Author SHA1 Message Date
fc29c18552 Movement Cleanup. 2025-05-08 21:46:24 -07:00
05580ee50d Vertical application of jump on new range based model. 2025-05-08 21:14:10 -07:00
07f992d729 New model looking good. 2025-05-07 22:40:50 -07:00
7a3318e5f6 Prepping for new model. 2025-05-07 21:07:31 -07:00
c6de01ba1a Oh that pesky impulse control. 2025-05-04 23:32:28 -07:00
061ceb76b9 Deprecated old movement function. 2025-05-04 20:36:16 -07:00
8906b98680 Maybe better impulse apply 2025-05-04 19:17:08 -07:00
f7f5ce1e61 No more bean! Also modifier on grounded seems to be working. 2025-05-04 08:28:55 -07:00
b45272934f Movement modifier has grounded processing directives. 2025-05-04 08:05:27 -07:00
7d7f3dfcd6 Impulse still bad. Modifier doesnt push into negative now. 2025-05-04 00:52:47 -07:00
07e0438341 Kinematic movement process improvements. Hope they stick. 2025-05-03 21:20:08 -07:00
d587eae523 More refactoring of movement 2025-05-03 16:52:47 -07:00
253ffe9641 Modifiers applying for movement! but now I need bodges in the object mover again. 2025-05-01 23:50:38 -07:00
97d7b969da Movement modifier tweaks. Almost there. 2025-04-30 23:48:49 -07:00
2c7a8e64f2 Tired state added to test movement. 2025-04-30 23:39:33 -07:00
d5818f1c17 Lots of work on state modifiers in prep for movement. 2025-04-30 23:09:43 -07:00
6d51eaffb0 Movement Parameters now used to aid fetching and merging of state movements 2025-04-30 19:06:01 -07:00
ec869ed1cc Better movement working. still wip. 2025-04-29 00:19:24 -07:00
7421991e56 New approach for separating accel from friction and using move_toward again. 2025-04-28 23:28:15 -07:00
dff822c6f4 reintroduce calc_velocity variable, allow override for testing. 2025-04-28 20:10:15 -07:00
18 changed files with 824 additions and 423 deletions

View File

@ -39,7 +39,8 @@ func _ready():
# processed
current_state = get_node(callable_state_machine).current_state
#state_machine_modifiers = get_node(callable_state_machine).state_modifiers
modifier = get_node(callable_state_machine).merged_animation_state_modifiers
## Not doing it this way anymore modifier is applied when one arrives by signal.
#modifier = get_node(callable_state_machine).merged_animation_state_modifiers
# Sprites should only have a process function
# but if I have this will the sprite still animate?
@ -89,6 +90,7 @@ func change_animation(enter_frame := 0, index := 0, suffix := ''):
animation_index = index
current_animation_sequence = animation_index
## TODO: this runs everytime since the modifier will apply once and stay referenced.
if modifier:
##TODO: Apply the animation starting frame
#modifier.animation_starting_frame
@ -240,9 +242,14 @@ func _on_state_change(old_state_name:String, new_state :State):
else:
push_warning("Received non animated Actor state.")
func _on_modifiers_updated(_modifier_type :int, _modifier_action :int):
func _on_modifiers_updated(_modifier_type :int, _modifier_action :int, _merged_modifier :StateModifier):
##TODO: There's so many things I could maybe do here but lets target the
## current use case.
# current use case.
##
## If the signalled merged modifier is a Animation one set it
if _merged_modifier is StateModifierAnimatedActor:
modifier = _merged_modifier
print("<<--- >> is active? ", modifier.is_active)
if _modifier_type == StateModifierAnimatedActor.TYPE.ANIMATION_SUFFIX:
print("A: ", animation, " F: ", frame, " -Modifier Changed Signal")
# Wait for frame to finish before doing anything.

View File

@ -0,0 +1,67 @@
class_name MovementParameters
extends Reference
## Vector based ones for x and y
export var base_move_speed :Vector2
export var base_move_acceleration :Vector2
export var move_speed_modifier :Vector2
export var move_speed_modifier_acceleration :Vector2
var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
var jerk: float = 0.0
# export var base_h_move_speed :float
# export var base_h_move_acceleration :float
# export var h_move_speed_modifier :float
# export var h_move_modifier_move_acceleration :float
# export var base_v_move_speed :float
# export var base_v_move_acceleration :float
# export var v_move_speed_modifier :float
# export var v_move_modifier_move_acceleration :float
func modify(_movement_parameters :MovementParameters):
pass
func apply_state_modifier(_modifier :StateModifierMovement, _movement_direction :float):
match _modifier.modifier_type:
StateModifierMovement.SUB_TYPE.NEGATIVE_CONSTRAINT:
var adjusted_move_speed = base_move_speed.x + _modifier.horizontal_speed
## We crossed the zero from the base
if base_move_speed.x == 10:
var foo = 2+2
if sign(adjusted_move_speed) != sign(base_move_speed.x):
base_move_speed.x = 0.0
else:
base_move_speed.x = adjusted_move_speed
var adjusted_accel = base_move_acceleration.x + _modifier.horizontal_acceleration
if sign(adjusted_accel) != sign(base_move_acceleration.x):
base_move_acceleration.x = 0.0
else:
base_move_acceleration.x = adjusted_accel
##TODO: Um, modifiers are a little weirder for this
move_speed_modifier.x += _modifier.horizontal_speed_offset
move_speed_modifier_acceleration.x += _modifier.horizontal_speed_offset_acceleration
move_speed_modifier.y += _modifier.vertical_speed_offset
move_speed_modifier_acceleration.y += _modifier.vertical_speed_offset_acceleration
_:
base_move_speed.x += _modifier.horizontal_speed
base_move_acceleration.x += _modifier.horizontal_acceleration
move_speed_modifier.x += _modifier.horizontal_speed_offset
move_speed_modifier_acceleration.x += _modifier.horizontal_speed_offset_acceleration
base_move_speed.y += _modifier.vertical_speed
base_move_acceleration.y += _modifier.vertical_acceleration
move_speed_modifier.y += _modifier.vertical_speed_offset
move_speed_modifier_acceleration.y += _modifier.vertical_speed_offset_acceleration
# var movement_params :Dictionary = {
# "_base_h_move_speed" : _state.horizontal_speed,
# "_base_h_move_acceleration" : _state.horizontal_acceleration,
# "_base_h_move_speed_modifier" : _state.horizontal_speed_offset,
# "_base_h_move_modifier_move_acceleration" : _state.horizontal_speed_offset_acceleration,
# "_jerk_factor" : _state.jerk_factor,
# "_gravity" : _state.gravity
# }

View File

@ -23,16 +23,16 @@ onready var desired_movement_vector: Vector2 = Vector2(0,0)
# 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 inertia = Vector2(0,0)
var acceleration = Vector2(0,0)
#var momentum = Vector2(0,0)
#var inertia = Vector2(0,0)
#var acceleration = Vector2(0,0)
#Removing Probably not used
#var sim_velocity = Vector2(0,0)
var physics_delta:float
var process_delta:float
var modifier: StateModifierAnimatedActor
var modifier: StateModifierMovement
#Removing Probably not used
#var attack_function: FuncRef
@ -47,10 +47,12 @@ func _ready():
request_state_change = funcref(get_node(callable_state_machine), 'change_to_known_state')
## Connect signal to get alerted of state change
get_node(callable_state_machine).connect("state_changed", self,"_on_state_change")
## Get notified when modifiers updated
get_node(callable_state_machine).connect("modifiers_updated",self,"_on_modifiers_updated")
## A reference to the current state machine state
current_state = get_node(callable_state_machine).current_state
## A reference to the state machine merged modifiers
modifier = get_node(callable_state_machine).merged_animation_state_modifiers
#modifier = get_node(callable_state_machine).merged_animation_state_modifiers
############
## These get called by the parent
@ -59,8 +61,8 @@ func process_physics(delta):
physics_delta = delta
if has_method('_state_process_physics_' + current_state.name):
call('_state_process_physics_' + current_state.name)
else:
move_actor_as_desired()
# else:
# move_actor_as_desired()
# more likely needed for Players
func process_physics_input(delta):
@ -136,203 +138,303 @@ func _on_state_change(old_state_name:String, new_state :State):
push_warning("Received non animated Actor state.")
#current_state = new_state
func _on_modifiers_updated(_modifier_type :int, _modifier_action :int, _merged_modifier :StateModifier):
## Get reference (subscribe) to the merged modifier for movement
if _merged_modifier is StateModifierMovement:
print("Registered Modifier Movement: ", _merged_modifier.horizontal_speed)
modifier = _merged_modifier
enum RANGE_PLACEMENT {
BEFORE_RANGE = -1,
WITHIN_RANGE = 0,
PAST_RANGE = 1
}
## Side effects for these variables
# velocity - doesn't change but uses it to set base calculations
# accepts the state to determine movement, the deltatime, and an optional direction
# Update: Actually should just return movement in PPS
##
#var calc_inertia = velocity.abs()
#var calc_inertial_dir :Vector2
var debug_speed_tracker :Vector2
## Could these be datatypes or a class? Sure
var _h_impulse_applied :bool = false
var _h_impulse_speed_tracking :Vector2
var _v_impulse_applied :bool = false
var _v_impulse_speed_tracking :Vector2
func new_move_actor_as_desired(_delta :float,
_state :StateAnimatedActor,
_movement_override_normal := Vector2(0,0),
_velocity_override := Vector2(0,0)) -> Vector2:
## Calculated movement speed.
var movement_params :Dictionary = {
"_base_h_move_speed" : _state.horizontal_speed,
"_base_h_move_acceleration" : _state.horizontal_acceleration,
"_base_h_move_speed_modifier" : _state.horizontal_speed_offset,
"_base_h_move_modifier_move_acceleration" : _state.horizontal_speed_offset_acceleration,
"_jerk_factor" : _state.jerk_factor,
"_gravity" : _state.gravity
}
var calc_velocity = Vector2.ZERO
if _velocity_override.x != 0.0:
calc_velocity.x = _velocity_override.x
else:
calc_velocity.x = velocity.x
if _velocity_override.y != 0.0:
calc_velocity.y = _velocity_override.y
else:
calc_velocity.y = velocity.y
var calc_acceleration = Vector2.ZERO
var calc_inertia :Vector2
##TODO: make sure velocity variable exists since we rely on it
## Calc from the _velocity_override instead of current object velocity
if _velocity_override.x != 0.0:
calc_inertia.x = abs(_velocity_override.x)
else:
calc_inertia.x = abs(velocity.x)
##TODO: Only implemented horizontal so far.
calc_inertia.y = velocity.y
var calc_inertial_dir = Vector2(sign(velocity.x),sign(velocity.y))
var calc_friction :Vector2 = Vector2.ZERO
#calc_inertia.x = abs(calc_velocity.x)
## We're now toing to preserve inertia direction
calc_inertia.x = calc_velocity.x
calc_inertia.y = calc_velocity.y
var calc_inertial_dir = Vector2(sign(calc_velocity.x),sign(calc_velocity.y))
#var calc_friction :Vector2 = Vector2.ZERO
## Determine movement direction
# If there is an inertia direction from existing velocity and
# no desired movement we'll continue to travel in that direction.
##
## If an override has been passed (we're ignoring input direction
var move_direction = Vector2.ZERO
if _movement_override_normal != Vector2.ZERO:
move_direction = resolve_move_direction(calc_inertia, _movement_override_normal)
else:
move_direction = resolve_move_direction(calc_inertia, desired_movement_vector)
var modifier_indicator := ''
var movement_parameters :MovementParameters = _state.get_movement_parameters()
if modifier and modifier.is_active:
if (_state.is_grounded and modifier.only_grounded): # Should we skip
modifier_indicator = '*'
if _state.name == 'jump':
var foo = 2+2 # break
movement_parameters.apply_state_modifier(modifier, move_direction.x)
## Inertia only applies if there is a difference between the
# base move speed and a derived move speed. This makes it so all you
# have to do is provide a move speed and that is the speed we will travel.
# but if a modifier applies, or an accelleration is given.
# an entirely differant process occurs.
# h_speed.x can be thought of as impulse speed. While h_speed.y
# is the destination speed.
# We move towards h_speed.y at the acceleration rate
##
var h_speed = resolve_h_speed(movement_params)
#if h_speed != Vector2.ZERO:
# pass
## If an override has been passed (we're ignoring input direction
var move_direction = Vector2.ZERO
if _movement_override_normal != Vector2.ZERO:
move_direction = resolve_move_direction(calc_inertial_dir, _movement_override_normal)
else:
move_direction = resolve_move_direction(calc_inertial_dir, desired_movement_vector)
var h_speed = resolve_h_speed(movement_parameters)
var v_speed = resolve_v_speed(movement_parameters)
## Speed will now be expected to move in the direction of travel
h_speed *= move_direction.x
v_speed *= move_direction.y
## Now determine placement of current velocity to speed range
var h_range_placement = placement_to_speed_range(calc_velocity.x, h_speed)
var v_range_placement = placement_to_speed_range(calc_velocity.y, v_speed)
## Which direction will acceleration be applied.
calc_acceleration.x = resolve_h_acceleration(movement_params, velocity, move_direction.x)
## We don't want to be able to scoot our impulse speed to cheat the movement
# Any non zero speed that goes opposite to our inertial direction
# should only be allowed once.
## Reset the impulse when back in range
# may also want to reset when hspeed is static
if (h_range_placement == RANGE_PLACEMENT.WITHIN_RANGE and
_h_impulse_applied == true ):
print("resetting H impulse")
_h_impulse_applied = false
if (v_range_placement == RANGE_PLACEMENT.WITHIN_RANGE and
_v_impulse_applied == true ):
print("resetting V impulse")
_v_impulse_applied = false
## Direction of inertia not equal to move direction
## If inertia is applying in a direction
# if calc_inertial_dir.x:
# ## And it doesn't apply in the same direction as our movement direction
# if calc_inertial_dir.x != sign(move_direction.x):
# ## Apply the direction of acceleration and apply as friction
# # Friction allows the inertia to trend toward 0 instead of the
# # 'To' direction of speed.
# ##
# #calc_friction.x = calc_acceleration.x * -1
# calc_friction.x = calc_acceleration.x
# calc_acceleration.x = 0.0
## Acceleration is always postive because we use the
# move toward functions.
calc_acceleration.x = abs(resolve_h_acceleration(movement_parameters, move_direction.x))
## We are always moving from h_speed.x towards y at a given rate
## if we have a difference of speed
if h_speed.x != h_speed.y:
debug_speed_tracker = h_speed
## Clamp inertia to in between speed.
# Problem is that we can suddenly gain or lose inertia.
##
# calc_inertia.x = clamp( calc_inertia.x + (calc_acceleration.x * _delta),
# h_speed.x , h_speed.y)
## If there is currently no inertia apply the base h_speed
if calc_inertia.x == 0.0:
calc_inertia.x = h_speed.x
## Apply acceleration
if h_speed.y > h_speed.x:
calc_inertia.x = move_toward(calc_inertia.x, h_speed.y, (calc_acceleration.x * _delta))
else:
## use of move_toward forcing need to apply negative accel as postitive.
#calc_inertia.x = move_toward(calc_inertia.x, h_speed.y, abs(calc_acceleration.x * _delta))
calc_inertia.x = clamp( calc_inertia.x + (calc_acceleration.x * _delta),
h_speed.y , h_speed.x)
var foo = 3
## if we have a difference of speed and an acceleration
##TODO: The Min Max could be augmented to just be h_speed.x and prevent the sliding.
if h_speed.x != h_speed.y and calc_acceleration.x != 0.0:
var direction_accel :float = calc_acceleration.x * _delta #* move_direction.x
if h_speed.x > h_speed.y:
direction_accel *= -1
match h_range_placement:
RANGE_PLACEMENT.BEFORE_RANGE:
## Also apply impulse here
if _h_impulse_applied == false:
calc_inertia.x += h_speed.x
_h_impulse_applied = true
#impulse_applied_dir = move_direction.x
calc_inertia.x = clamp(calc_inertia.x + direction_accel,
min(calc_inertia.x, h_speed.y),
max(calc_inertia.x, h_speed.y))
RANGE_PLACEMENT.WITHIN_RANGE:
## If we're within the range but our speed has just changed
if _h_impulse_applied == false and _h_impulse_speed_tracking != h_speed:
## Set inertia to starting speed, we're already in range
calc_inertia.x = h_speed.x
_h_impulse_applied = true
calc_inertia.x = clamp(calc_inertia.x + direction_accel,
min(h_speed.x, h_speed.y),
max(h_speed.x, h_speed.y))
RANGE_PLACEMENT.PAST_RANGE:
calc_inertia.x = clamp(calc_inertia.x - direction_accel, # Friction
min(calc_inertia.x, h_speed.y),
max(calc_inertia.x, h_speed.y))
elif calc_inertia.x != 0.0: ## We still have inertia but no difference in movement
if calc_acceleration.x != 0.0: # We are applying acceleration
## Move back towards the base speed
if calc_inertia.x < h_speed.x:
calc_inertia.x = clamp( calc_inertia.x + ( calc_acceleration.x * _delta),
calc_inertia.x, h_speed.x)
else:
calc_inertia.x = clamp( calc_inertia.x + ( calc_acceleration.x * _delta),
h_speed.x, calc_inertia.x)
else: ## No longer applying acceleration
## Neutralize the inertia? but how?
## Recalc the acceleration with inertia
#var friction :Vector2
calc_friction.x = resolve_h_acceleration(movement_params,Vector2(calc_inertia.x, h_speed.x), move_direction.x)
if calc_friction.x != 0.0: ## No dapening acceleration applies
calc_inertia.x = move_toward(calc_inertia.x, h_speed.x, ( calc_friction.x * _delta))
elif calc_inertia.x != 0.0 and calc_acceleration.x != 0.0: ## We still have inertia but no difference in movement
if h_speed.x < h_speed.y:
h_speed.x = clamp(h_speed.x,0.0,h_speed.y)
else:
## no residual acceleration (friction) applies, kill the momentum
calc_inertia.x = 0.0
calc_inertial_dir.x = 0.0
# if (h_speed != debug_speed_tracker):
# print("Inertia SpeedShift: ", debug_speed_tracker, h_speed, (0.0 == -0.0))
# debug_speed_tracker = h_speed
## Move back towards the base speed
calc_inertia.x = move_toward(calc_inertia.x, h_speed.x, calc_acceleration.x * _delta)
else:
## inertia is just base speed
calc_inertia.x = h_speed.x
calc_inertial_dir.x = 0.0
calc_inertial_dir.x = 0.0 # sign(calc_inertia.x)
## Another idea, just return the calculated velocity in PPS
## For now, y component of velocity is just gravity
#calc_velocity.y = movement_params["_gravity"] * Vector2.DOWN.y
if v_speed.x != v_speed.y: ## For now gravity is just the default acceleration
var direction_accel :float = movement_parameters.gravity * _delta #* move_direction.x
if v_speed.x > v_speed.y:
direction_accel *= -1
match v_range_placement:
RANGE_PLACEMENT.BEFORE_RANGE:
## Also apply impulse here
if _v_impulse_applied == false:
calc_inertia.y += v_speed.x
_v_impulse_applied = true
#impulse_applied_dir = move_direction.x
calc_inertia.y = clamp(calc_inertia.y + direction_accel,
min(calc_inertia.x, v_speed.y),
max(calc_inertia.x, v_speed.y))
RANGE_PLACEMENT.WITHIN_RANGE:
## If we're within the range but our speed has just changed
if _v_impulse_applied == false and _v_impulse_speed_tracking != v_speed:
## Set inertia to starting speed, we're already in range
calc_inertia.y = v_speed.x
_v_impulse_applied = true
calc_inertia.y = clamp(calc_inertia.y + direction_accel,
min(v_speed.x, v_speed.y),
max(v_speed.x, v_speed.y))
RANGE_PLACEMENT.PAST_RANGE:
calc_inertia.y = clamp(calc_inertia.y - direction_accel, # Friction
min(calc_inertia.y, v_speed.y),
max(calc_inertia.y, v_speed.y))
calc_inertia.y += movement_params["_gravity"] * _delta
calc_velocity.y = calc_inertia.y
## calc x component of felicty
## Can't do it this way when we have initia
#calc_velocity.x = calc_inertia.x * move_direction.x
## Control, direction can only be controlled when overcome inertia direction.
if calc_inertial_dir.x != 0:
calc_velocity.x = calc_inertia.x * calc_inertial_dir.x
else:
calc_velocity.x = calc_inertia.x * move_direction.x
## The previous vertical movement methods
calc_inertia.y += movement_parameters.gravity * _delta
## Track or last speed for in range impulses
_h_impulse_speed_tracking = h_speed
_v_impulse_speed_tracking = v_speed
calc_velocity.y = calc_inertia.y
calc_velocity.x = calc_inertia.x
## Attempting to move this to the top
#calc_inertial_dir = Vector2(sign(calc_velocity.x),sign(calc_velocity.y))
UiManager.debug_text = ( #"H_Speed x Dir: " + str(h_speed) + str('duh') +
"H_Speed Fm:{0} To:{1}".format({"0":"%5.2f" % h_speed.x, "1":"%5.2f" % h_speed.y}) +
"\nVelocity_Calc: {0}, {1}".format({"0":"%5.2f" % calc_velocity.x, "1":"%5.2f" % calc_velocity.y}) +
"\nInertia_Calc: {0}, {1}".format({"0":"%5.2f" % calc_inertia.x, "1":"%5.2f" % calc_inertia.y}) +
"\nVelocity_Real: {0}, {1}".format({"0":"%5.2f" % velocity.x, "1":"%5.2f" % velocity.y}) +
"\nFriction: {0}, {1}".format({"0":"%5.2f" % calc_friction.x, "1":"%5.2f" % calc_friction.y}) +
"\nAccelCalc : {0}, {1}".format({"0":"%5.2f" % calc_acceleration.x, "1":"%5.2f" % calc_acceleration.y}) +
#"\nLength: " + str(velocity.length()) +
"\nMoveDir: {0}, {1}".format({"0":"%4.1f" % move_direction.x, "1":"%4.1f" % move_direction.y})
)
if debug_component:
UiManager.debug_text = ( #"H_Speed x Dir: " + str(h_speed) + str('duh') +
modifier_indicator + "H_Speed Fm:{0} To:{1}".format({"0":"%5.2f" % h_speed.x, "1":"%5.2f" % h_speed.y}) +
"\nV_Speed Fm:{0} To:{1}".format({"0":"%5.2f" % v_speed.x, "1":"%5.2f" % v_speed.y}) +
"\nSpeedRange : {0}, {1}".format({"0":"%5.2f" % h_range_placement, "1":"%5.2f" % v_range_placement}) +
"\nVelocity_Calc: {0}, {1}".format({"0":"%5.2f" % calc_velocity.x, "1":"%5.2f" % calc_velocity.y}) +
"\nInertia_Calc: {0}, {1}".format({"0":"%5.2f" % calc_inertia.x, "1":"%5.2f" % calc_inertia.y}) +
"\nVelocity_Real: {0}, {1}".format({"0":"%5.2f" % velocity.x, "1":"%5.2f" % velocity.y}) +
#"\nFriction: {0}, {1}".format({"0":"%5.2f" % calc_friction.x, "1":"%5.2f" % calc_friction.y}) +
"\nAccelCalc : {0}, {1}".format({"0":"%5.2f" % calc_acceleration.x, "1":"%5.2f" % calc_acceleration.y}) +
# h_range_placement
#"\nLength: " + str(velocity.length()) +
"\nMoveDir: {0}, {1}".format({"0":"%4.1f" % move_direction.x, "1":"%4.1f" % move_direction.y})
)
return calc_velocity
func is_out_of_range(value: float, a: float, b: float) -> bool:
var lower = min(a, b)
var upper = max(a, b)
return value <= lower or value >= upper
## Determine the trend of direction and where our current speed is
# in relation to it. This should help determine the direction of
# acceleration and whether we speed up or slow down.
##
func placement_to_speed_range(speed: float, speed_range: Vector2) -> int:
## Actually we don't care about mix or min
#var range_start :float = min(speed_range.x, speed_range.y)
#var range_end :float = max(speed_range.x, speed_range.y)
## We can be at the base range to ensure impulse can happen
## Direction <-- that way
if speed_range.x > speed_range.y:
if speed < speed_range.x and speed >= speed_range.y:
return RANGE_PLACEMENT.WITHIN_RANGE
elif speed < speed_range.y:
return RANGE_PLACEMENT.PAST_RANGE
else:
return RANGE_PLACEMENT.BEFORE_RANGE
else: ## Direction --> that way
if speed > speed_range.x and speed <= speed_range.y:
return RANGE_PLACEMENT.WITHIN_RANGE
elif speed > speed_range.y:
return RANGE_PLACEMENT.PAST_RANGE
else:
return RANGE_PLACEMENT.BEFORE_RANGE
return 0
## Passed in acceleration, vel, etc is applied to whatever
## the parent is. If Kinematic then move_and_slide, otherwise manually adjusted
func apply_movement_to_parent( _velocity :Vector2) -> void:
var snap = Vector2.DOWN * 8
## Disable snap when trying to jump (hacky?)
if _velocity.y < -8:
snap = Vector2.ZERO
if parent is KinematicBody2D:
velocity = parent.move_and_slide_with_snap(_velocity, snap , Vector2.UP, true)
## Returns an Vector where x is MIN_SPEED and y is MAX_SPEED
func resolve_h_speed(_params :Dictionary) -> Vector2:
var base_speed :float = _params["_base_h_move_speed"]
func resolve_h_speed(_params :MovementParameters) -> Vector2:
var base_speed :float = _params.base_move_speed.x
## if a speed difference applies
if _params["_base_h_move_speed_modifier"] != 0:
var speed_differance = base_speed + _params["_base_h_move_speed_modifier"]
if _params.move_speed_modifier.x != 0:
var speed_differance = base_speed + _params.move_speed_modifier.x
return(Vector2(base_speed, speed_differance))
return Vector2(base_speed,base_speed)
func resolve_h_acceleration(_params :Dictionary, _inertia :Vector2, _move_direction :float) -> float:
func resolve_v_speed(_params :MovementParameters) -> Vector2:
var base_speed :float = _params.base_move_speed.y
## if a speed difference applies
if _params.move_speed_modifier.y != 0:
var speed_differance = base_speed + _params.move_speed_modifier.y
return(Vector2(base_speed, speed_differance))
return Vector2(base_speed,base_speed)
func resolve_h_acceleration(_params :MovementParameters, _move_direction :float) -> float:
## TODO: Adjust for jerk, determine if we're currently experiencing accel
## if a speed difference applies
var _acceleration :float = 0.0
var base_speed :float = _params["_base_h_move_speed"]
if _params["_base_h_move_speed_modifier"] != 0:
var speed_differance = base_speed + _params["_base_h_move_speed_modifier"]
_acceleration = _params["_base_h_move_acceleration"] #+ _params["_base_h_move_modifier_move_acceleration"]
var base_speed :float = _params.base_move_speed.x
if _params.move_speed_modifier.x != 0:
var speed_differance = base_speed + _params.move_speed_modifier.x
_acceleration = _params.base_move_acceleration.x + _params.move_speed_modifier_acceleration.x
##WIP: Add part where offset acceleration only applies until the inertia equals the offset or whatever
if sign(_params["_base_h_move_modifier_move_acceleration"]) == -1 and abs(_inertia.x) >= speed_differance:
#print("I should add the modifier acceleration maybe?")
_acceleration += _params["_base_h_move_modifier_move_acceleration"]
# if sign(_params["_base_h_move_modifier_move_acceleration"]) == -1 and abs(_inertia.x) >= speed_differance:
# #print("I should add the modifier acceleration maybe?")
# _acceleration += _params["_base_h_move_modifier_move_acceleration"]
# else:
# print ("not yet.")
else:
_acceleration = _params["_base_h_move_acceleration"]
_acceleration = _params.base_move_acceleration.x
if _inertia.x != 0.0 and sign(_inertia.x) != sign(_move_direction):
return _acceleration * -1
elif sign(_move_direction) != 0:
## If no velocity or it matches just return as is.
return _acceleration
## This works but I want to try something differant.
# if _inertia.x != 0.0 and sign(_inertia.x) != sign(_move_direction):
# return _acceleration * -1
# elif sign(_move_direction) != 0:
# ## If no velocity or it matches just return as is.
# return _acceleration
if sign(_move_direction) != 0:
return _acceleration
# No accel returned unless intended
return 0.0
@ -345,198 +447,204 @@ func resolve_move_direction(_momentum :Vector2,
elif sign(_momentum.x): ## We still have momentum but not trying to move
horizontal_movement_direction = sign(_momentum.x)
return Vector2(horizontal_movement_direction,0)
var vertical_movement_direction:float
if sign(_movement_direction.y):
vertical_movement_direction = sign(_movement_direction.y)
elif sign(_momentum.y):
vertical_movement_direction = sign(_momentum.y)
return Vector2(horizontal_movement_direction, vertical_movement_direction)
## About to DEPR this one for redesigned one above
func move_actor_as_desired( x_move_direction_override: float = 0):
var delta:float = physics_delta
var _move_speed = current_state.horizontal_speed
var _move_acceleration = current_state.horizontal_acceleration
var _move_speed_modifier = current_state.horizontal_speed_offset
var _move_modifier_move_acceleration = current_state.horizontal_speed_offset_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):
acceleration.x *= -1
# print("Whoh Woah")
# Flip the direction of the acceleration
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_debug("be more opposite")
elif (sign(desired_movement_vector.x) == sign(current_x_velocity) and momentum.x != 0):
print('why')
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(_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
##TODO: Apparently I disabled jerk some time ago for some reason.
current_state.jerk += _jerk_factor * delta
var new_move_speed :float = 0
if sign(_move_speed_modifier) == -1: # decreased speed modifier
#func move_actor_as_desired( x_move_direction_override: float = 0):
# var delta:float = physics_delta
# var _move_speed = current_state.horizontal_speed
# var _move_acceleration = current_state.horizontal_acceleration
# var _move_speed_modifier = current_state.horizontal_speed_offset
# var _move_modifier_move_acceleration = current_state.horizontal_speed_offset_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
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
# 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
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 debug_component == 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)
# 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):
# acceleration.x *= -1
# # print("Whoh Woah")
# # Flip the direction of the acceleration
# 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_debug("be more opposite")
#
# elif (sign(desired_movement_vector.x) == sign(current_x_velocity) and momentum.x != 0):
# print('why')
# 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(_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
# ##TODO: Apparently I disabled jerk some time ago for some reason.
# 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 debug_component == 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

@ -15,7 +15,20 @@ export var horizontal_acceleration: float = 0
export var horizontal_speed_offset: float = 0
## Applies only if offset applies
export var horizontal_speed_offset_acceleration: float = 0
export var jerk_factor: float = 0
export var jerk_factor: float = 1.0
export var vertical_speed: float = 0
export var vertical_acceleration: float = 0
## Movement Speed Offsets (Positive or Negative)
export var vertical_speed_offset: float = 0
## Applies only if offset applies
export var vertical_speed_offset_acceleration: float = 0
## Should this state keep the inertia from previous states
export var preserve_inertia :bool = true
## Whether this state should be considered a grounded state
export var is_grounded :bool = true
## Default state gravity is the project's gravity
var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity")
@ -41,3 +54,17 @@ func enter() -> void:
return
func get_movement_parameters() -> MovementParameters:
var movement_parameters = MovementParameters.new()
movement_parameters.base_move_speed.x = horizontal_speed
movement_parameters.base_move_acceleration.x = horizontal_acceleration
movement_parameters.move_speed_modifier.x = horizontal_speed_offset
movement_parameters.move_speed_modifier_acceleration.x = horizontal_speed_offset_acceleration
movement_parameters.base_move_speed.y = vertical_speed
movement_parameters.base_move_acceleration.y = vertical_acceleration
movement_parameters.move_speed_modifier.y = vertical_speed_offset
movement_parameters.move_speed_modifier_acceleration.y = vertical_speed_offset_acceleration
return movement_parameters

View File

@ -3,12 +3,13 @@ class_name StateMachine extends Node
export var debug_state_machine: bool = false
signal state_changed(old_state_name, new_state)
signal modifiers_updated(modifier_type, modifier_eventid)
signal modifiers_updated(modifier_type, modifier_eventid, _merged_modifier)
var current_state: State
var state_modifiers: Array
onready var merged_animation_state_modifiers :StateModifierAnimatedActor = StateModifierAnimatedActor.new()
var merged_modifiers : Dictionary
#onready var merged_animation_state_modifiers :StateModifierAnimatedActor = StateModifierAnimatedActor.new()
export var starting_state_name = 'default'
export(Array,Resource) var states
@ -48,19 +49,32 @@ func _ready():
push_error("State machine cannot find starting state: " + starting_state_name)
func _physics_process(delta):
if(state_modifiers.size() > 0):
merged_animation_state_modifiers.reset()
merged_animation_state_modifiers.animation_name = 'floopy doo,'
merge_modifiers()
#func _physics_process(delta):
# if(state_modifiers.size() > 0):
# merged_animation_state_modifiers.reset()
# merged_animation_state_modifiers.animation_name = 'floopy doo,'
# #merge_modifiers()
func merge_modifiers():
merged_animation_state_modifiers.reset()
#merged_animation_state_modifiers.reset()
for modgroup in merged_modifiers.keys():
merged_modifiers[modgroup].reset()
for m in state_modifiers:
if m is StateModifierAnimatedActor:
if merged_modifiers.has("StateModifierAnimatedActor") == false:
merged_modifiers["StateModifierAnimatedActor"] = StateModifierAnimatedActor.new()
#print(m.name)
var this_mod_type :StateModifierAnimatedActor = merged_modifiers["StateModifierAnimatedActor"]
if m.is_active:
merged_animation_state_modifiers.merge_StateModifierAnimatedActor(m)
#merged_animation_state_modifiers.merge(m)
this_mod_type.merge(m)
if m is StateModifierMovement:
if merged_modifiers.has("StateModifierMovement") == false:
merged_modifiers["StateModifierMovement"] = StateModifierMovement.new()
#print(m.name)
var this_mod_type :StateModifierMovement = merged_modifiers["StateModifierMovement"]
if m.is_active:
this_mod_type.merge(m)
# Change to the new state by first calling any exit logic on the current state.
func change_state(new_state: State) -> void:
@ -113,13 +127,16 @@ func push_state_modifier(_state_modifier: StateModifier) -> void:
if debug_state_machine:
print("Add State Modifier: ", _state_modifier.name, " now size ", state_modifiers.size())
func handle_modifier_events(eventID :int):
func handle_modifier_events(eventID :int, modifier_class_name :String):
##TODO: why did I care about the events? they both do the same thing
if eventID == StateModifier.EVENT_ID.ACTIVATED:
if debug_state_machine:
print ("A mod activated! Which one though?")
print ("A mod activated! Which one though?", modifier_class_name)
merge_modifiers()
emit_signal("modifiers_updated",merged_animation_state_modifiers.modifier_type, eventID)
emit_signal("modifiers_updated",merged_modifiers[modifier_class_name].modifier_type,
eventID,
merged_modifiers[modifier_class_name] )
elif eventID == StateModifier.EVENT_ID.DEACTIVATED:
merge_modifiers()
emit_signal("modifiers_updated",merged_animation_state_modifiers.modifier_type, eventID)
emit_signal("modifiers_updated",merged_modifiers[modifier_class_name].modifier_type, eventID, merged_modifiers[modifier_class_name])

View File

@ -10,6 +10,7 @@ extends Reference
##
## @WIP
## Deprecated, should use modifier level
# Used for mutually exclusive modifiers to aid merging
enum TYPE {
NONE, # Usually just a physics modifier
@ -86,6 +87,10 @@ var state_call_function: FuncRef
# mp.directional_modifier = modifier_properties.directional_modifier
# return mp
## Because I've tried a few ways to identify the object without a CR error
func _to_string():
return "StateModifier"
func setup(modifier_name:String, type = TYPE.NONE,_timeout_seconds : float = 0):
name = modifier_name
modifier_type = type
@ -100,10 +105,14 @@ func setup(modifier_name:String, type = TYPE.NONE,_timeout_seconds : float = 0):
func reset():
name = ''
modifier_type = TYPE.NONE
is_active = false
func copy(_copy_state: StateModifier):
_copy_state.name = name
_copy_state.modifier_type = modifier_type
## This should really be the other way.
# _copy_state.name = name
# _copy_state.modifier_type = modifier_type
name = _copy_state.name
modifier_type = _copy_state.modifier_type
func merge(_merge_from_modifier: StateModifier):
@ -113,12 +122,12 @@ func activate():
is_active = true
if timeout != null:
timeout.start()
emit_signal("modifier_event",EVENT_ID.ACTIVATED)
emit_signal("modifier_event",EVENT_ID.ACTIVATED, to_string())
func deactivate():
is_active = false
print(name," <- Got call to deactivate.")
emit_signal("modifier_event",EVENT_ID.DEACTIVATED)
emit_signal("modifier_event",EVENT_ID.DEACTIVATED, to_string())
#func ready(modifier_name:String, anim_name:String = '', type = TYPE.NONE, timeout : float = 0, parent:Node = null, function_name : String = "") -> Timer:
# name = modifier_name

View File

@ -8,15 +8,15 @@ var animation_suffix: String = ''
var animation_starting_frame: int = 0
var animation_speed: float
var horizontal_speed: float = 0
var horizontal_acceleration: float = 0
## Movement Speed Offsets (Positive or Negative)
var horizontal_speed_offset: float = 0
## Applies only if offset applies
var horizontal_speed_offset_acceleration: float = 0
var jerk_factor: float = 0
enum SUB_TYPE {
NONE, # Usually just a physics modifier
EXIT_ANIMATION # Adds an animation at the end? Not really sure anymore
ANIMATION_SUFFIX, # Adds an animation suffix to aid slightly modified animations
REPLACE_ANIMATION # Completely replaces a state animation.
}
var gravity: int = 0
func _to_string():
return "StateModifierAnimatedActor"
func reset():
.reset()
@ -24,45 +24,65 @@ func reset():
animation_suffix = ''
animation_starting_frame = 0
horizontal_speed = 0
horizontal_acceleration = 0
## Movement Speed Offsets (Positive or Negative)
horizontal_speed_offset = 0
## Applies only if offset applies
horizontal_speed_offset_acceleration = 0
jerk_factor = 0
func copy_StateModifierAnimatedActor(_copy_state: StateModifierAnimatedActor):
func copy(_copy_state: StateModifier):
.copy(_copy_state)
_copy_state.animation_name = animation_name
_copy_state.animation_starting_frame = animation_starting_frame
_copy_state.animation_speed = animation_speed
##TODO: finish these
_copy_state.horizontal_speed = horizontal_speed
_copy_state.horizontal_acceleration = horizontal_acceleration
## Using is gives me cyclic redundancy problems
#if _copy_state is StateModifierAnimatedActor:
#if _copy_state.is_class("StateModifierAnimatedActor"):
if _copy_state.to_string() == "StateModifierAnimatedActor":
_copy_state.animation_name = animation_name
_copy_state.animation_starting_frame = animation_starting_frame
_copy_state.animation_speed = animation_speed
else:
print_debug("Non AnimatedActor modifier passed into this modifier")
func merge_StateModifierAnimatedActor(_merge_from_modifier: StateModifierAnimatedActor):
##DEPR: Need to remove this
#func copy_StateModifierAnimatedActor(_copy_state: StateModifierAnimatedActor):
# .copy(_copy_state)
# _copy_state.animation_name = animation_name
# _copy_state.animation_starting_frame = animation_starting_frame
# _copy_state.animation_speed = animation_speed
func merge(_merge_from_modifier: StateModifier):
.merge(_merge_from_modifier)
if modifier_type == TYPE.NONE and _merge_from_modifier.modifier_type != TYPE.NONE:
modifier_type = _merge_from_modifier.modifier_type
#_copy_state.animation_name += animation_name
match _merge_from_modifier.modifier_type:
TYPE.ANIMATION_SUFFIX:
# Attempt to seemlessly transition animations.
if _merge_from_modifier.animation_suffix != '':
animation_suffix = _merge_from_modifier.animation_suffix
TYPE.REPLACE_ANIMATION:
if _merge_from_modifier.animation_name != '':
animation_name = _merge_from_modifier.animation_name
_: # None
#print ('physics?')
horizontal_speed += _merge_from_modifier.horizontal_speed
horizontal_acceleration += _merge_from_modifier.horizontal_acceleration
horizontal_speed_offset += _merge_from_modifier.horizontal_speed_offset
horizontal_speed_offset_acceleration += _merge_from_modifier.horizontal_speed_offset_acceleration
is_active = _merge_from_modifier.is_active
#print(_merge_from_modifier.to_string(), " I'm a mod named: ", _merge_from_modifier.get_class())
#if _merge_from_modifier is StateModifierAnimatedActor:
if _merge_from_modifier.to_string() == "StateModifierAnimatedActor":
if modifier_type == TYPE.NONE and _merge_from_modifier.modifier_type != TYPE.NONE:
modifier_type = _merge_from_modifier.modifier_type
#_copy_state.animation_name += animation_name
match _merge_from_modifier.modifier_type:
TYPE.ANIMATION_SUFFIX:
# Attempt to seemlessly transition animations.
if _merge_from_modifier.animation_suffix != '':
animation_suffix = _merge_from_modifier.animation_suffix
TYPE.REPLACE_ANIMATION:
if _merge_from_modifier.animation_name != '':
animation_name = _merge_from_modifier.animation_name
# _: # None
# print ('physics?')
##DEPR: Need to remove this
#func merge_StateModifierAnimatedActor(_merge_from_modifier: StateModifierAnimatedActor):
# .merge(_merge_from_modifier)
# if modifier_type == TYPE.NONE and _merge_from_modifier.modifier_type != TYPE.NONE:
# modifier_type = _merge_from_modifier.modifier_type
#
# #_copy_state.animation_name += animation_name
# match _merge_from_modifier.modifier_type:
# TYPE.ANIMATION_SUFFIX:
# # Attempt to seemlessly transition animations.
# if _merge_from_modifier.animation_suffix != '':
# animation_suffix = _merge_from_modifier.animation_suffix
# TYPE.REPLACE_ANIMATION:
# if _merge_from_modifier.animation_name != '':
# animation_name = _merge_from_modifier.animation_name
# _: # None
# print ('physics?')
#
#
#_copy_state.animation_starting_frame = animation_starting_frame
#_copy_state.animation_speed = animation_speed

View File

@ -0,0 +1,75 @@
class_name StateModifierMovement
extends StateModifier
## Movement Modifiers
var horizontal_speed: float = 0
var horizontal_acceleration: float = 0
## Movement Speed Offsets (Positive or Negative)
var horizontal_speed_offset: float = 0
## Applies only if offset applies
var horizontal_speed_offset_acceleration: float = 0
var jerk_factor: float = 0
var vertical_speed: float = 0
var vertical_acceleration: float = 0
## Movement Speed Offsets (Positive or Negative)
var vertical_speed_offset: float = 0
## Applies only if offset applies
var vertical_speed_offset_acceleration: float = 0
var gravity: int = 0
## Processing Directives (help determine how the merge function works)
var direction :float = 0.0 # -1, 0, 1
var only_grounded :float = false
enum SUB_TYPE {
NONE, # Basic physics modifier just adds numbers
## Disallows ability to surpass zero when applied to state kinematic values
NEGATIVE_CONSTRAINT
}
func _to_string():
return "StateModifierMovement"
func reset():
.reset()
modifier_type = SUB_TYPE.NONE
direction = 0.0
horizontal_speed = 0
horizontal_acceleration = 0
## Movement Speed Offsets (Positive or Negative)
horizontal_speed_offset = 0
## Applies only if offset applies
horizontal_speed_offset_acceleration = 0
jerk_factor = 0
func copy(_copy_state: StateModifier):
.copy(_copy_state)
modifier_type = _copy_state.modifier_type
if _copy_state.to_string() == "StateModifierMovement":
_copy_state.horizontal_speed = horizontal_speed
_copy_state.horizontal_acceleration = horizontal_acceleration
func merge(_merge_from_modifier: StateModifier):
.merge(_merge_from_modifier)
is_active = _merge_from_modifier.is_active
if modifier_type != SUB_TYPE.NONE and _merge_from_modifier.modifier_type != SUB_TYPE.NONE:
push_warning( "Attempt to push modifier type over existing one. Wut du?" )
if _merge_from_modifier.to_string() == "StateModifierMovement":
if modifier_type == SUB_TYPE.NONE and _merge_from_modifier.modifier_type != SUB_TYPE.NONE:
modifier_type = _merge_from_modifier.modifier_type
##TODO: I don't really need merge functions here?
match _merge_from_modifier.modifier_type:
_:
horizontal_speed += _merge_from_modifier.horizontal_speed
horizontal_acceleration += _merge_from_modifier.horizontal_acceleration
horizontal_speed_offset += _merge_from_modifier.horizontal_speed_offset
horizontal_speed_offset_acceleration += _merge_from_modifier.horizontal_speed_offset_acceleration
vertical_speed += _merge_from_modifier.vertical_speed
vertical_acceleration += _merge_from_modifier.vertical_acceleration
vertical_speed_offset += _merge_from_modifier.vertical_speed_offset
vertical_speed_offset_acceleration += _merge_from_modifier.vertical_speed_offset_acceleration
direction = _merge_from_modifier.direction
only_grounded = _merge_from_modifier.only_grounded

View File

@ -89,6 +89,11 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://src/classes/movement_component.gd"
}, {
"base": "Reference",
"class": "MovementParameters",
"language": "GDScript",
"path": "res://lib/classes/movement_parameters.gd"
}, {
"base": "Node",
"class": "Movement_StateReceiver",
"language": "GDScript",
@ -149,6 +154,11 @@ _global_script_classes=[ {
"language": "GDScript",
"path": "res://lib/classes/state_modifier_animation.gd"
}, {
"base": "StateModifier",
"class": "StateModifierMovement",
"language": "GDScript",
"path": "res://lib/classes/state_modifier_movement.gd"
}, {
"base": "CanvasLayer",
"class": "UIComponent",
"language": "GDScript",
@ -171,6 +181,7 @@ _global_script_class_icons={
"LevelTransition": "",
"Modifier_Receiver": "",
"MovementComponent": "",
"MovementParameters": "",
"Movement_StateReceiver": "",
"PlayerData": "",
"Projectile": "",
@ -183,6 +194,7 @@ _global_script_class_icons={
"StateMachineAnimatedActor": "",
"StateModifier": "",
"StateModifierAnimatedActor": "",
"StateModifierMovement": "",
"UIComponent": ""
}
@ -401,6 +413,10 @@ dash_2={
common/enable_pause_aware_picking=true
2d/default_gravity=600
[mono]
project/assembly_name="Attempt 2"
[physics]
2d/default_gravity=280

View File

@ -76,5 +76,5 @@ func _on_state_exited_attack_sword():
print("you just swung your sword, you should get a modifier.")
#attack_sword.timeout.start()
attack_sword.activate()
print ("you has merged as? :" ,modifier.animation_name)
print ("you has merged as? :" ,modifier.animation_suffix)

View File

@ -11,12 +11,12 @@ onready var stamina_component = $"%Stamina_Component"
var state_stamina_cost :Dictionary
func _ready():
var state_ref :State
var state_name :String
state_name = 'jump'
state_ref = get_node(callable_state_machine).get_state_reference(state_name)
#var state_ref :State
#var state_name :String
#state_name = 'jump'
#state_ref = get_node(callable_state_machine).get_state_reference(state_name)
##TODO Should probably assert here or something.
state_ref.connect("state_entered", self, "_on_state_entered_" + state_name)
#state_ref.connect("state_entered", self, "_on_state_entered_" + state_name)
parent_request_state_change = funcref(get_node(callable_state_machine), 'check_parent_before_state_change')
if parent.has_method("use_primary_item"):
@ -33,8 +33,8 @@ func _ready():
func get_movement_direction() -> float:
#return Input.get_axis('move_left', 'move_right')
desired_movement_vector.x = Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number))
return Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number))
desired_movement_vector.x = sign(Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number)))
return desired_movement_vector.x # sign(Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number)))
var _wants_jump :bool
func wants_jump() -> bool:
@ -42,6 +42,7 @@ func wants_jump() -> bool:
##Bugfix: Both players jump.
#desired_movement_vector.y = UP
_wants_jump = true
desired_movement_vector.y = UP
return true
else:
_wants_jump = false
@ -249,7 +250,8 @@ func _state_process_physics_enter_right():
# Force role in facing direction
# instead of movement direction
move_actor_as_desired(parent.transform.x.x)
#move_actor_as_desired(parent.transform.x.x)
apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state, parent.transform.x ))
func _state_process_physics_land():
$"%LedgeDetector".set_enabled(true)
@ -259,7 +261,8 @@ func _state_process_physics_land():
if !parent.is_on_floor():
#return fall_state
request_state_change.call_func('fall')
move_actor_as_desired()
#move_actor_as_desired()
apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state ))
func _state_process_physics_hurt():
if current_state.state_timeout.time_left == 0:
@ -292,7 +295,8 @@ func _state_process_physics_fall():
#idle_state.modifier = landing_modifier
request_state_change.call_func('land')
move_actor_as_desired()
#move_actor_as_desired()
apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state ))
func _state_process_physics_jump():
@ -305,7 +309,9 @@ func _state_process_physics_jump():
# request_state_change.call_func('idle')
if velocity.y > 0:
request_state_change.call_func('fall')
move_actor_as_desired()
desired_movement_vector.y = UP
#move_actor_as_desired()
apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state ))
func _state_process_physics_move():
# flip sprite in direction
@ -437,15 +443,15 @@ func _state_process_physics_crouch_move():
elif _wants_crouch != true and desired_movement_vector.x != 0:
request_state_change.call_func('move')
move_actor_as_desired()
#move_actor_as_desired()
apply_movement_to_parent(new_move_actor_as_desired( physics_delta , current_state ))
#func _on_state_entered_idle():
# print("Movement State Idle State Entered!")
func _on_state_entered_jump():
print ("how many times do I get called?")
##TODO: Make this a state export variable
# I used to call it 'jump_force' like an idiot.
velocity.y = -200
##WIP: Make this a state export variable
#func _on_state_entered_jump():
# # I used to call it 'jump_force' like an idiot.
# velocity.y = -200

View File

@ -16,6 +16,7 @@ const state_stamina_cost :Dictionary = {
"attack_sword":20,
"attack_punch":10,
"roll":40,
#"roll":4,
"ledge_climb":10
}
@ -34,6 +35,15 @@ const state_to_item_map :Dictionary = {
var player_info_index :int
var player_data :PlayerData
## Temp Modifier to test movement modifier (getting tired)
var tired_debuff_modifier = StateModifierMovement.new()
# attack_sword = StateModifierAnimatedActor.new()
# attack_sword.setup('sword_drawn',StateModifier.TYPE.ANIMATION_SUFFIX,2.0)
# add_child(attack_sword.timeout)
# #attack_sword.animation_name = 'PoopenStein'
# attack_sword.animation_suffix = 'attack-sword'
# add_state_modifier.call_func(attack_sword)
# Called when the node enters the scene tree for the first time.
func _ready():
@ -59,6 +69,11 @@ func _ready():
player_inventory.select_primary(punch_item)
movement_component.state_stamina_cost = state_stamina_cost
tired_debuff_modifier.setup('so_tired', StateModifierMovement.SUB_TYPE.NEGATIVE_CONSTRAINT)
tired_debuff_modifier.horizontal_speed = -40
tired_debuff_modifier.only_grounded = true
movement_state_machine.push_state_modifier(tired_debuff_modifier)
#var stamina_recovery :float = 0.0
@ -86,7 +101,11 @@ func _process(delta):
hitbox_component.damage_amount = state_damage_amount[movement_state_machine.current_state.name]
else:
hitbox_component.damage_amount = 10
if stamina_component.stamina < 20 and tired_debuff_modifier.is_active == false:
tired_debuff_modifier.activate()
if stamina_component.stamina > 20 and tired_debuff_modifier.is_active == true:
tired_debuff_modifier.deactivate()
func hit_Receiver(damage):

View File

@ -148,7 +148,7 @@ max_health = 100
[node name="Stamina_Component" parent="." index="9" instance=ExtResource( 29 )]
unique_name_in_owner = true
max_stamina = 50
recovery_rate = 12
recovery_rate = 2
[node name="Hurtbox_Component" parent="." index="10" instance=ExtResource( 16 )]
collision_layer = 16

View File

@ -13,5 +13,11 @@ horizontal_speed = 90.0
horizontal_acceleration = 0.0
horizontal_speed_offset = 0.0
horizontal_speed_offset_acceleration = 0.0
jerk_factor = 0.0
jerk_factor = 1.0
vertical_speed = 0.0
vertical_acceleration = 0.0
vertical_speed_offset = 0.0
vertical_speed_offset_acceleration = 0.0
preserve_inertia = true
is_grounded = false
animation_sequence = [ "jump" ]

View File

@ -10,8 +10,14 @@ debug_state = false
timeout_seconds = 0.0
name = "idle"
horizontal_speed = 1.36422e-12
horizontal_acceleration = -2.0
horizontal_acceleration = 300.0
horizontal_speed_offset = 0.0
horizontal_speed_offset_acceleration = 0.0
jerk_factor = 0.0
jerk_factor = 1.0
vertical_speed = 0.0
vertical_acceleration = 0.0
vertical_speed_offset = 0.0
vertical_speed_offset_acceleration = 0.0
preserve_inertia = true
is_grounded = true
animation_sequence = [ "idle" ]

View File

@ -13,5 +13,11 @@ horizontal_speed = 90.0
horizontal_acceleration = 0.0
horizontal_speed_offset = 0.0
horizontal_speed_offset_acceleration = 0.0
jerk_factor = 0.0
jerk_factor = 1.0
vertical_speed = 200.0
vertical_acceleration = 0.0
vertical_speed_offset = -208.0
vertical_speed_offset_acceleration = 0.0
preserve_inertia = true
is_grounded = false
animation_sequence = [ "jump" ]

View File

@ -10,8 +10,14 @@ debug_state = false
timeout_seconds = 0.0
name = "move"
horizontal_speed = 10.0
horizontal_acceleration = 20.0
horizontal_acceleration = 70.0
horizontal_speed_offset = 80.0
horizontal_speed_offset_acceleration = 0.0
jerk_factor = 0.0
vertical_speed = 0.0
vertical_acceleration = 0.0
vertical_speed_offset = 0.0
vertical_speed_offset_acceleration = 0.0
preserve_inertia = true
is_grounded = true
animation_sequence = [ "run" ]

View File

@ -13,5 +13,11 @@ horizontal_speed = 150.0
horizontal_acceleration = 1.36422e-12
horizontal_speed_offset = -140.0
horizontal_speed_offset_acceleration = -300.0
jerk_factor = 0.0
jerk_factor = 1.0
vertical_speed = 0.0
vertical_acceleration = 0.0
vertical_speed_offset = 0.0
vertical_speed_offset_acceleration = 0.0
preserve_inertia = false
is_grounded = true
animation_sequence = [ "roll" ]