Jam10/Scripts/Units/DownhillAutoscrollerPlayer.gd

169 lines
6.3 KiB
GDScript3
Raw Normal View History

2023-01-27 21:55:12 +00:00
extends Player
class_name DownhillAutoscrollerPlayer
2023-01-27 22:30:20 +00:00
export var min_speed : float = 3
2023-01-28 07:13:06 +00:00
export var max_speed : float = 11
export var player_initiated_acceleration : float = 5
export var boost_per_second : float = 6
2023-01-27 21:55:12 +00:00
var last_contacted_map_elem_type : int = Constants.MapElemType.SQUARE
2023-01-28 01:56:15 +00:00
var boost : float = 0 # to movement speed
func execute_actions(delta):
.execute_actions(delta)
for action_num in Constants.UNIT_TYPE_ACTIONS[Constants.UnitType.PLAYER]:
if !actions[action_num]:
continue
match action_num:
# handle custom actions
Constants.ActionType.SPIN:
spin(delta)
_:
pass
func spin(delta):
set_current_action(Constants.UnitCurrentAction.SPINNING)
boost += boost_per_second * delta
func reset_current_action():
.reset_current_action()
if get_current_action() == Constants.UnitCurrentAction.SPINNING:
if not actions[Constants.ActionType.SPIN]:
set_current_action(Constants.UnitCurrentAction.IDLE)
func custom_inputs():
if scene.input_table[Constants.PlayerInput.GBA_B][scene.I_T_JUST_PRESSED]:
if not get_condition(Constants.UnitCondition.IS_ON_GROUND, true):
set_action(Constants.ActionType.SPIN)
if (get_current_action() == Constants.UnitCurrentAction.SPINNING
and scene.input_table[Constants.PlayerInput.GBA_B][scene.I_T_PRESSED]):
set_action(Constants.ActionType.SPIN)
2023-01-27 21:55:12 +00:00
func process_unit(delta, time_elapsed : float):
# always be movin'
facing = Constants.Direction.RIGHT
actions[Constants.ActionType.MOVE] = true
2023-01-28 09:25:49 +00:00
# Check if fallen off
if last_contacted_map_elem_type == Constants.MapElemType.OOB_LOWER:
oob_lower()
2023-01-27 21:55:12 +00:00
# Fine tune the player's speed
if get_current_action() == Constants.UnitCurrentAction.RECOILING:
target_move_speed = min_speed
else:
# override player input so that leftward movement is deceleration,
# right movement is acceleration
if scene.input_table[Constants.PlayerInput.LEFT][scene.I_T_PRESSED]:
target_move_speed = move_toward(target_move_speed, min_speed, player_initiated_acceleration * delta)
else:
if not get_condition(Constants.UnitCondition.IS_ON_GROUND, true):
if (target_move_speed < Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type]
and scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]):
target_move_speed = move_toward(target_move_speed, Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type], player_initiated_acceleration * delta)
2023-01-28 01:56:15 +00:00
if target_move_speed > max_speed:
target_move_speed = move_toward(target_move_speed, max_speed, player_initiated_acceleration * delta)
2023-01-27 21:55:12 +00:00
else:
# shallow slope: arctan(.5) = 27 degrees, sin(27) = 0.45
# steep slope: sin(45) = 0.71
var ground_influenced_acceleration = 0
var is_decel : bool = false
if (last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_RIGHT_1
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_RIGHT_2
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_1
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_2):
ground_influenced_acceleration = Constants.GRAVITY * 0.45
if (last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_1
or last_contacted_map_elem_type == Constants.MapElemType.SMALL_SLOPE_LEFT_2):
is_decel = true
elif (last_contacted_map_elem_type == Constants.MapElemType.SLOPE_RIGHT
or last_contacted_map_elem_type == Constants.MapElemType.SLOPE_LEFT):
ground_influenced_acceleration = Constants.GRAVITY * 0.71
if last_contacted_map_elem_type == Constants.MapElemType.SLOPE_LEFT:
is_decel = true
if is_decel or ground_influenced_acceleration == 0:
var end_speed
if ground_influenced_acceleration == 0:
# flat ground
if scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]:
2023-01-28 01:56:15 +00:00
end_speed = max(min(target_move_speed, max_speed), Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type])
2023-01-27 21:55:12 +00:00
else:
2023-01-28 01:56:15 +00:00
end_speed = min(target_move_speed, max_speed)
2023-01-27 21:55:12 +00:00
else:
# incline
if scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]:
end_speed = Constants.UNIT_TYPE_MOVE_SPEEDS[unit_type]
else:
end_speed = min_speed
if target_move_speed < end_speed:
target_move_speed = move_toward(target_move_speed, end_speed, player_initiated_acceleration * delta)
else:
2023-01-28 01:56:15 +00:00
if ground_influenced_acceleration > 0:
target_move_speed = move_toward(target_move_speed, end_speed, ground_influenced_acceleration * delta)
else:
target_move_speed = move_toward(target_move_speed, end_speed, player_initiated_acceleration * delta)
2023-01-27 21:55:12 +00:00
else:
var acceleration = ground_influenced_acceleration
if scene.input_table[Constants.PlayerInput.RIGHT][scene.I_T_PRESSED]:
acceleration = max(acceleration, player_initiated_acceleration)
if target_move_speed < max_speed:
target_move_speed = move_toward(target_move_speed, max_speed, acceleration * delta)
2023-01-28 01:56:15 +00:00
else:
target_move_speed = move_toward(target_move_speed, max_speed, player_initiated_acceleration * delta)
2023-01-27 21:55:12 +00:00
.process_unit(delta, time_elapsed)
# treat all collisions as right-side collisions
func hit(dir : int):
# Unit.gd implementation override
hit_queued = true
hit_dir = Constants.Direction.RIGHT
# Player.gd implementation
set_unit_condition_with_timer(Constants.UnitCondition.IS_INVINCIBLE)
start_flash()
set_action(Constants.ActionType.RECOIL)
set_current_action(Constants.UnitCurrentAction.RECOILING)
set_unit_condition(Constants.UnitCondition.MOVING_STATUS, Constants.UnitMovingStatus.IDLE)
# override super class's RECOIL_PUSHBACK
func handle_recoil():
if not hit_queued:
return
hit_queued = false
# skip recoil pushback logic, since target_move_speed is already
# set to min_speed
2023-01-28 01:56:15 +00:00
func landed():
if get_current_action() == Constants.UnitCurrentAction.SPINNING:
hit(Constants.Direction.RIGHT)
boost = 0
return
target_move_speed += boost
boost = 0
2023-01-28 09:25:49 +00:00
func oob_lower():
# Called when the player falls in a hole
# Calculate respawn point
var tilemap : TileMap = get_node("../Stage")
var tile : Vector2 = pos.floor()
tile.y *= -1
while tilemap.get_cellv(tile) == 23 or tilemap.get_cellv(tile) < 0:
tile += Vector2.RIGHT
while tilemap.get_cellv(tile) >= 0:
tile += Vector2.UP
pos = tile
pos.x += 0.5
pos.y *= -1
last_contacted_map_elem_type = Constants.MapElemType.SLOPE_LEFT
# =======================
# reset speed
# should other things be done here?
h_speed = 0