247 lines
7.8 KiB
GDScript
247 lines
7.8 KiB
GDScript
extends CharacterBody2D
|
|
|
|
#Rootmotion
|
|
var rootmotion_prev := Vector2.ZERO
|
|
@onready var RootMotion := $RootMotion
|
|
@onready var mainbody := $mainbody
|
|
|
|
@export var speed = 400 #350 init
|
|
@export var grav = 40
|
|
@export var fallgrav = 60 #gravity only applied when falling
|
|
@export var jump_force = 800
|
|
@export var fallvelocity_cap = 1500 # How fast the player can get when falling
|
|
@export var max_air_jumps = 1 # Number of total jumps allowed (1 = normal, 2 = double jump)
|
|
|
|
var jumps_done = 0
|
|
var air_jumps_done = 0
|
|
|
|
var coyote_timer = 0.0
|
|
var coyote_time = 0.2
|
|
var jump_buffered := false
|
|
var jump_buffer_timer = 0.0
|
|
var jump_buffer_time = 0.2
|
|
|
|
var input_direction = 0
|
|
var direction_locked = false
|
|
var facing_direction = 1 # 1 = right, -1 = left
|
|
|
|
@export var sprint_mult = 1.5
|
|
@export var crouch_mult = 0.4
|
|
@export var roll_mult = 1.5
|
|
@export var jump_mult = 1.3
|
|
|
|
@onready var ap = $AnimationPlayer
|
|
@onready var sprite = $Sprite2D
|
|
@onready var cshape = $mainbody
|
|
@onready var topcheck1 = $topcheck1
|
|
@onready var topcheck2 = $topcheck2
|
|
|
|
@onready var statemachine = $StateMachine
|
|
|
|
@onready var wallrun_raycast_left1 = $wallrunrcleft1
|
|
@onready var wallrun_raycast_left2 = $wallrunrcleft2
|
|
@onready var wallrun_raycast_right1 = $wallrunrcright1
|
|
@onready var wallrun_raycast_right2 = $wallrunrcright2
|
|
@onready var wallcheckright = $wallcheckright
|
|
@onready var wallcheckleft = $wallcheckleft
|
|
@onready var floorcheck = $floorcheck
|
|
|
|
var horizontal_direction = 0
|
|
var v_mult = 1 #velocity multiplier
|
|
var v_push = 0 #velocity push in either direction
|
|
|
|
var stuck_under_object = false
|
|
|
|
#wallrun and pushoff
|
|
var wallrun_available := true
|
|
var wallrun_timer := 0.0 #:= bedeutet, dass der Typ fest festgelegt ist (z.B int, bool etc.)
|
|
var wallrun_time := 0.7 # Dauer des Wallruns in Sekunden
|
|
var wallrun_speed := -400.0 # Geschwindigkeit nach oben (negativ wegen y-Achse)
|
|
|
|
var wallpushoff_force := 450 # Stärke des Abstoßens
|
|
var wallpushoff_mult := 0.3 # schränkt die velocity.x Kontrolle des Spielers ein.
|
|
var wallpushoff_timer := 0.0
|
|
var wallpushoff_time := 0.5 # dauer des pushoffs
|
|
|
|
#dash
|
|
var dash_available := false
|
|
var dash_timer := 0.0
|
|
var dash_time := 0.2
|
|
var dash_mult := 2
|
|
|
|
#climbup
|
|
var climbup_speed_y = 100
|
|
var climbup_speed_x = 500
|
|
|
|
#obstacle vault
|
|
var can_vault := false
|
|
var vault_direction := Vector2.ZERO
|
|
var vault_mult := 1.3
|
|
|
|
#fallroll
|
|
var fallroll_timer := 0.0
|
|
var fallroll_input_timer := 0.0
|
|
var fallroll_time := 0.5 #time till you need to fallroll
|
|
var fallroll_input_time := 0.5 #timewindow in which the fallroll works
|
|
var fallrolling := false
|
|
var can_fallroll := true
|
|
var fallroll_mult := 0.8 #velocity mult of fallroll differs from roll
|
|
var land_delay_timer := 0.0
|
|
var land_delay_time := 0.1 #time in which player will stay in falling state after hitting the ground
|
|
|
|
func _process(delta):
|
|
#turnmovement()
|
|
pass
|
|
|
|
|
|
func _physics_process(delta):
|
|
|
|
#print("jump buffered: ", jump_buffered)
|
|
|
|
#move_and_collide()
|
|
move_and_slide()
|
|
if !direction_locked:
|
|
input_direction = Input.get_axis("move_left", "move_right")
|
|
else:
|
|
input_direction = facing_direction
|
|
|
|
#print(statemachine.current_state.get_state_name()) # zum debuggen aktivieren
|
|
|
|
if statemachine.current_state.get_state_name() not in ["PlayerClimbUp", "PlayerVault", "PlayerDash"]:
|
|
gravity(delta)
|
|
|
|
if statemachine.current_state.get_state_name() not in ["PlayerWallrun", "PlayerWallrunPushoff", "PlayerLedgeGrab", "PlayerClimbUp"]:
|
|
turnmovement()
|
|
|
|
|
|
$ledgecollision.disabled = statemachine.current_state.get_state_name() in ["PlayerIdle", "PlayerRun", "PlayerCrouch", "PlayerCrouchWalk", "PlayerJump", "PlayerWallrun", "PlayerClimbUp", "PlayerRoll", "PlayerVault"] or velocity.y < 0 or Input.is_action_pressed("crouch") or(topcheck1.is_colliding() and topcheck2.is_colliding() and statemachine.current_state.get_state_name() != "PlayerLedgeGrab")
|
|
$mainbody.disabled = statemachine.current_state.get_state_name() in ["PlayerClimbUp"]
|
|
|
|
func movement():
|
|
velocity.x = speed * input_direction * v_mult + v_push
|
|
|
|
func turnmovement():
|
|
movement()
|
|
|
|
if direction_locked:
|
|
return
|
|
|
|
if input_direction != 0 and sign(input_direction) != facing_direction:
|
|
switch_direction(sign(input_direction))
|
|
|
|
func switch_direction(new_direction):
|
|
facing_direction = new_direction
|
|
sprite.flip_h = (facing_direction == -1)
|
|
|
|
func set_facing_direction(dir: int): #manual flip
|
|
if direction_locked:
|
|
return
|
|
if dir in [-1, 1] and dir != facing_direction:
|
|
switch_direction(dir)
|
|
|
|
func gravity(delta):
|
|
velocity.y += grav
|
|
if velocity.y > fallvelocity_cap:
|
|
velocity.y = fallvelocity_cap
|
|
|
|
func head_clear() -> bool:
|
|
var result = !topcheck1.is_colliding() && !topcheck2.is_colliding()
|
|
return result
|
|
|
|
func wall_detected_left() -> bool:
|
|
var result = wallrun_raycast_left1.is_colliding() && wallrun_raycast_left2.is_colliding()
|
|
return result
|
|
|
|
func wall_detected_right() -> bool:
|
|
var result = wallrun_raycast_right1.is_colliding() && wallrun_raycast_right2.is_colliding()
|
|
return result
|
|
|
|
func _on_vault_trigger_entered(trigger_name: String) -> void:
|
|
print("vault trigger entered:", trigger_name)
|
|
can_vault = true
|
|
if trigger_name == "triggerzone_left":
|
|
vault_direction = Vector2.RIGHT
|
|
elif trigger_name == "triggerzone_right":
|
|
vault_direction = Vector2.LEFT
|
|
else:
|
|
vault_direction = Vector2.ZERO
|
|
|
|
func _on_vault_trigger_exited(trigger_name: String) -> void:
|
|
print("vault trigger exited:", trigger_name)
|
|
can_vault = false
|
|
vault_direction = Vector2.ZERO
|
|
|
|
func is_facing_vault_direction() -> bool:
|
|
var input_dir := Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
|
|
|
|
# only allow vault if input matches vault_direction
|
|
if vault_direction == Vector2.RIGHT and input_dir > 0:
|
|
return true
|
|
elif vault_direction == Vector2.LEFT and input_dir < 0:
|
|
return true
|
|
return false
|
|
|
|
func jumpbuffer(delta):
|
|
|
|
if Input.is_action_just_pressed("jump"):
|
|
jump_buffered = true
|
|
jump_buffer_timer = 0.0
|
|
|
|
if jump_buffered:
|
|
jump_buffer_timer += delta
|
|
if jump_buffer_timer >= jump_buffer_time:
|
|
jump_buffered = false
|
|
|
|
# transition functions
|
|
|
|
func transitionidle() -> bool:
|
|
var result = Input.get_axis("move_left", "move_right") == 0 && is_on_floor()
|
|
return result
|
|
|
|
func transitionrun() -> bool:
|
|
var result = Input.get_axis("move_left", "move_right") != 0 && is_on_floor()
|
|
return result
|
|
|
|
func transitioncoyotejump() -> bool:
|
|
var result = coyote_time >= coyote_timer and Input.is_action_just_pressed("jump") and (jumps_done == 0)
|
|
return result
|
|
|
|
func transitionjump() -> bool:
|
|
var result = (Input.is_action_just_pressed("jump") or jump_buffered) and is_on_floor()
|
|
return result
|
|
|
|
func transitiondoublejump() -> bool:
|
|
var result = Input.is_action_just_pressed("jump") && !is_on_floor() && (air_jumps_done < max_air_jumps)
|
|
return result
|
|
|
|
func transitionfall() -> bool:
|
|
var result = velocity.y > 0 && !is_on_floor()
|
|
return result
|
|
|
|
func transitionledgegrab() -> bool:
|
|
var result = !floorcheck.is_colliding() && velocity.y - grav == 0 && (wallcheckright.is_colliding() or wallcheckleft.is_colliding())
|
|
return result
|
|
|
|
func transitioncrouch() -> bool:
|
|
var result = is_on_floor() && Input.is_action_pressed("crouch")
|
|
return result
|
|
|
|
func transitioncrouchwalk() -> bool:
|
|
var result = is_on_floor() && Input.is_action_pressed("crouch") && Input.get_axis("move_left", "move_right") != 0
|
|
return result
|
|
|
|
func transitionwallrun() -> bool:
|
|
var result = Input.is_action_just_pressed("jump") and ((Input.is_action_pressed("move_right") && wall_detected_right()) or (Input.is_action_pressed("move_left") && wall_detected_left())) and wallrun_available
|
|
return result
|
|
|
|
func transitionroll() -> bool:
|
|
var result = Input.is_action_just_pressed("sprint") and is_on_floor()
|
|
return result
|
|
|
|
#func transitionfallroll() -> bool:
|
|
#func transitionhardlanding() -> bool:
|
|
|
|
func transitiondash() -> bool:
|
|
var result = Input.is_action_just_pressed("sprint") and !is_on_floor() and dash_available and fallroll_timer < fallroll_time
|
|
return result
|