newest Version as of right now

This commit is contained in:
2025-06-21 06:25:34 +02:00
parent 35d8ece14f
commit 76da17dfbe
40 changed files with 1104 additions and 156 deletions

View File

@ -0,0 +1,19 @@
extends StaticBody2D
func _ready():
var player = get_tree().get_first_node_in_group("player")
$triggerzone_left.connect("body_entered", Callable(self, "_on_trigger_entered").bind("triggerzone_left", player))
$triggerzone_left.connect("body_exited", Callable(self, "_on_trigger_exited").bind("triggerzone_left", player))
$triggerzone_right.connect("body_entered", Callable(self, "_on_trigger_entered").bind("triggerzone_right", player))
$triggerzone_right.connect("body_exited", Callable(self, "_on_trigger_exited").bind("triggerzone_right", player))
func _on_trigger_entered(body: Node, trigger_name: String, player: Node):
if body.is_in_group("player"):
player._on_vault_trigger_entered(trigger_name)
func _on_trigger_exited(body: Node, trigger_name: String, player: Node):
if body.is_in_group("player"):
player._on_vault_trigger_exited(trigger_name)

View File

@ -0,0 +1 @@
uid://b8ewx8kbbdns1

View File

@ -1,17 +1,34 @@
extends CharacterBody2D
@export var speed = 350
#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 = 1000 # How fast the player can get when falling
@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
@ -33,46 +50,72 @@ var horizontal_direction = 0
var v_mult = 1 #velocity multiplier
var v_push = 0 #velocity push in either direction
var air_jumps_done = 0
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 := 1 # Dauer des Wallruns in Sekunden
var wallrun_speed := -250.0 # Geschwindigkeit nach oben (negativ wegen y-Achse)
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
var climbup_pos1 = Vector2(0, 0)
var climbup_pos2 = Vector2(0, 0)
var climbup_pos1_reached = false
#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()
input_direction = Input.get_axis("move_left", "move_right")
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 ["PlayerWallrun", "PlayerClimbUp"]:
gravity()
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"] 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")
$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
@ -96,13 +139,7 @@ func set_facing_direction(dir: int): #manual flip
if dir in [-1, 1] and dir != facing_direction:
switch_direction(dir)
func lock_direction():
direction_locked = true
func unlock_direction():
direction_locked = false
func gravity():
func gravity(delta):
velocity.y += grav
if velocity.y > fallvelocity_cap:
velocity.y = fallvelocity_cap
@ -118,6 +155,42 @@ func wall_detected_left() -> bool:
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
@ -128,9 +201,13 @@ func transitionidle() -> bool:
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") && is_on_floor()
var result = (Input.is_action_just_pressed("jump") or jump_buffered) and is_on_floor()
return result
func transitiondoublejump() -> bool:
@ -157,3 +234,13 @@ 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

View File

@ -1,18 +0,0 @@
extends State
class_name AccelDecel
@export var acceleration = 2000
@export var deceleration = 1500
func movement(velocity_x, speed, input_direction, v_mult, v_push, delta):
var target_speed = speed * input_direction * v_mult + v_push
if input_direction != 0:
return move_toward(velocity_x, target_speed, acceleration * delta)
return move_toward(velocity_x, 0, deceleration * delta)
func turnmovement(velocity_x, speed, input_direction, v_mult, v_push, delta, direction_locked, facing_direction):
var vx = movement(velocity_x, speed, input_direction, v_mult, v_push, delta)
var fd = facing_direction
if not direction_locked and input_direction != 0 and sign(input_direction) != facing_direction:
fd = sign(input_direction)
return [vx, fd]

View File

@ -1 +0,0 @@
uid://cst40h14xfhjk

View File

@ -9,38 +9,57 @@ var standing_cshape = preload("res://resources/player standing cshape.tres")
func enter():
player.climbup_pos1 = player.position + Vector2(0, -52)
player.climbup_pos2 = player.position + Vector2(player.facing_direction * 40, -52)
print(player.position)
print (player.climbup_pos1)
player.ap.play("climb up")
player.ap.playback_process_mode = AnimationPlayer.ANIMATION_PROCESS_MANUAL #rootmotion
var root_node := player.get_node("RootMotion") #rootmotion
player.rootmotion_prev = root_node.position #rootmotion
player.sprite.position.x = player.facing_direction * 11
player.sprite.position.y = -60
player.cshape.shape = ledge_cshape
player.cshape.position.y = -69
player.z_index = 10
func exit():
player.cshape.shape = standing_cshape
player.cshape.position.y = -43
player.ap.playback_process_mode = AnimationPlayer.ANIMATION_PROCESS_IDLE #rootmotion
player.RootMotion.position = Vector2(11, -60) #rootmotion
player.rootmotion_prev = Vector2(11, -60) #rootmotion
player.sprite.position.x = 0
player.sprite.position.y = -48
player.climbup_pos1_reached = false
player.cshape.shape = standing_cshape
player.cshape.position.y = -43
player.z_index = 0
func update(delta):
pass
func physics_update(delta):
if player.position != player.climbup_pos1 && !player.climbup_pos1_reached:
player.position = player.position.move_toward(player.climbup_pos1, player.climbup_speed_y * delta)
if player.position == player.climbup_pos1:
player.climbup_pos1_reached = true
elif player.position != player.climbup_pos2 && player.climbup_pos1_reached:
player.position = player.position.move_toward(player.climbup_pos2, player.climbup_speed_x * delta)
elif player.position == player.climbup_pos2:
Transitioned.emit(self, "PlayerFall")
player.jumpbuffer(delta)
player.ap.advance(delta)
var current_root_pos = player.RootMotion.position #rootmotion
var root_delta = current_root_pos - player.rootmotion_prev #rootmotion
player.position += Vector2(root_delta.x * player.facing_direction, root_delta.y)
player.rootmotion_prev = current_root_pos #rootmotion
if not player.ap.is_playing():
Transitioned.emit(self, "PlayerFall")
#ursprüngliches manuelles bewegen des players während dem Climb up:
#if player.position != player.climbup_pos1 && !player.climbup_pos1_reached:
#player.position = player.position.move_toward(player.climbup_pos1, player.climbup_speed_y * delta)
#if player.position == player.climbup_pos1:
#player.climbup_pos1_reached = true
#elif player.position != player.climbup_pos2 && player.climbup_pos1_reached:
#player.position = player.position.move_toward(player.climbup_pos2, player.climbup_speed_x * delta)
#elif player.position == player.climbup_pos2:
#Transitioned.emit(self, "PlayerFall")

View File

@ -13,7 +13,7 @@ func enter():
func exit():
player.cshape.shape = standing_cshape
player.cshape.position.y = -44
player.cshape.position.y = -43
func update(delta):

View File

@ -0,0 +1,25 @@
extends State
class_name PlayerDash
func get_state_name():
return str(self).split(":")[0]
func enter():
player.dash_available = false
player.direction_locked = true
player.v_mult = player.dash_mult
player.velocity.y = 0
func exit():
player.direction_locked = false
player.v_mult = 1
player.dash_timer = 0
func update(delta):
pass
func physics_update(delta):
player.dash_timer += delta
if player.dash_timer >= player.dash_time:
Transitioned.emit(self, "PlayerFall")

View File

@ -0,0 +1 @@
uid://qf4kjhw6b8ip

View File

@ -19,6 +19,8 @@ func update(delta):
Transitioned.emit(self, "PlayerDoubleJump")
elif player.is_on_floor() && player.velocity.x != 0:
Transitioned.emit(self, "PlayerRun")
elif player.transitiondash():
Transitioned.emit(self, "PlayerDash")
elif player.is_on_floor():
Transitioned.emit(self, "PlayerIdle")

View File

@ -1,30 +1,65 @@
extends State
class_name PlayerFall
var initgrav = 0
func get_state_name():
return str(self).split(":")[0]
func enter():
pass
initgrav = player.grav
player.grav = player.fallgrav
func exit():
pass
player.grav = initgrav
player.fallroll_timer = 0.0
player.fallroll_input_timer = 0.0
player.land_delay_timer = 0.0
player.can_fallroll = true
player.fallrolling = false
player.jump_buffered = false
func update(delta):
player.ap.play("fall")
player.coyote_timer += delta
fallrollcheck(delta)
player.jumpbuffer(delta)
if player.transitionledgegrab():
Transitioned.emit(self, "PlayerLedgeGrab")
elif player.transitiondoublejump():
Transitioned.emit(self, "PlayerDoubleJump")
elif player.transitionidle():
Transitioned.emit(self, "PlayerIdle")
elif player.transitionrun():
Transitioned.emit(self, "PlayerRun")
player.gravity()
if player.fallroll_timer <= player.fallroll_time or player.land_delay_timer >= player.land_delay_time:
if player.transitioncoyotejump() or player.transitionjump():
Transitioned.emit(self, "PlayerJump")
elif player.transitiondoublejump():
Transitioned.emit(self, "PlayerDoubleJump")
elif player.is_on_floor() and player.fallroll_timer >= player.fallroll_time and player.fallrolling:
print("fallroll")
Transitioned.emit(self, "PlayerFallRoll") #ersetzen durch state: PlayerFallRoll
elif player.transitionidle():
Transitioned.emit(self, "PlayerIdle")
elif player.transitionrun():
Transitioned.emit(self, "PlayerRun")
#elif player.transitiondash():
#Transitioned.emit(self, "PlayerDash")
func physics_update(delta):
pass
#player.turnmovement()
func fallrollcheck(delta):
player.fallroll_timer += delta
if Input.is_action_just_pressed("sprint") and player.can_fallroll:
player.fallrolling = true
player.can_fallroll = false
if player.fallrolling == true:
player.fallroll_input_timer += delta
if player.fallroll_input_timer >= player.fallroll_input_time:
player.fallrolling = false
if player.is_on_floor():
player.land_delay_timer += delta

View File

@ -0,0 +1,29 @@
extends State
class_name PlayerFallRoll
var crouching_cshape = preload("res://resources/player crouching cshape.tres")
var standing_cshape = preload("res://resources/player standing cshape.tres")
func get_state_name():
return str(self).split(":")[0]
func enter():
player.ap.play("roll")
player.direction_locked = true
player.cshape.shape = crouching_cshape
player.cshape.position.y = -31
player.v_mult = player.fallroll_mult
func exit():
player.cshape.shape = standing_cshape
player.cshape.position.y = -44
player.v_mult = 1
player.direction_locked = false
func update(delta):
pass
func physics_update(delta):
if not player.ap.is_playing():
Transitioned.emit(self, "PlayerCrouch")

View File

@ -0,0 +1 @@
uid://bjln8dh5ajphf

View File

@ -6,7 +6,10 @@ func get_state_name():
func enter():
player.air_jumps_done = 0
player.jumps_done = 0
player.coyote_timer = 0.0
player.wallrun_available = true
player.dash_available = true
func exit():
pass
@ -24,4 +27,4 @@ func update(delta):
Transitioned.emit(self, "PlayerJump")
func physics_update(delta):
player.gravity()
player.gravity(delta)

View File

@ -7,12 +7,20 @@ func get_state_name():
func enter():
player.ap.play("jump")
player.velocity.y = -player.jump_force
player.jumps_done += 1
player.v_mult = player.jump_mult
func exit():
pass
player.v_mult = 1
func update(delta):
player.jumpbuffer(delta)
if player.transitionledgegrab():
Transitioned.emit(self, "PlayerLedgeGrab")
elif player.transitiondash():
Transitioned.emit(self, "PlayerDash")
elif player.transitionfall():
Transitioned.emit(self, "PlayerFall")
elif !player.is_on_floor() and Input.is_action_just_pressed("jump") and (player.air_jumps_done < player.max_air_jumps):

View File

@ -0,0 +1,29 @@
extends State
class_name PlayerRoll
var crouching_cshape = preload("res://resources/player crouching cshape.tres")
var standing_cshape = preload("res://resources/player standing cshape.tres")
func get_state_name():
return str(self).split(":")[0]
func enter():
player.ap.play("roll")
player.direction_locked = true
player.cshape.shape = crouching_cshape
player.cshape.position.y = -31
player.v_mult = player.roll_mult
func exit():
player.cshape.shape = standing_cshape
player.cshape.position.y = -44
player.v_mult = 1
player.direction_locked = false
func update(delta):
pass
func physics_update(delta):
if not player.ap.is_playing():
Transitioned.emit(self, "PlayerCrouch")

View File

@ -0,0 +1 @@
uid://clru46wbu1bi1

View File

@ -6,7 +6,10 @@ func get_state_name():
func enter():
player.air_jumps_done = 0
player.jumps_done = 0
player.coyote_timer = 0.0
player.wallrun_available = true
player.dash_available = true
player.v_mult = 1
func exit():
pass
@ -15,10 +18,15 @@ func update(delta):
if player.transitionidle():
Transitioned.emit(self, "PlayerIdle")
elif player.transitionroll():
Transitioned.emit(self, "PlayerRoll")
elif player.transitioncrouch():
Transitioned.emit(self, "PlayerCrouchwalk")
elif player.transitionwallrun():
Transitioned.emit(self, "PlayerWallrun")
elif Input.is_action_just_pressed("jump") and player.can_vault and player.is_facing_vault_direction():
Transitioned.emit(self, "PlayerVault")
Transitioned.emit(self, "PlayerVault")
elif player.transitionjump():
Transitioned.emit(self, "PlayerJump")
elif player.transitionfall():

View File

@ -0,0 +1,58 @@
extends State
class_name PlayerVault
var crouching_cshape = preload("res://resources/player crouching cshape.tres")
var standing_cshape = preload("res://resources/player standing cshape.tres")
func get_state_name():
return str(self).split(":")[0]
func enter():
player.direction_locked = true
#player.cshape.shape = crouching_cshape
#player.cshape.position.y = -74
player.ap.play("reverse vault")
player.v_mult = player.vault_mult
player.ap.playback_process_mode = AnimationPlayer.ANIMATION_PROCESS_MANUAL #rootmotion
var root_node := player.get_node("RootMotion") #rootmotion
player.rootmotion_prev = root_node.position #rootmotion
#player.z_index = 10
func exit():
player.direction_locked = false
player.cshape.shape = standing_cshape
player.cshape.position.y = -43
player.sprite.position.y = -48
player.v_mult = 1
player.ap.playback_process_mode = AnimationPlayer.ANIMATION_PROCESS_IDLE #rootmotion
player.RootMotion.position = Vector2(11, -60) #rootmotion
player.rootmotion_prev = Vector2(11, -60) #rootmotion
#player.z_index = 0
func update(delta):
if player.wallcheckleft.is_colliding() or player.wallcheckright.is_colliding():
player.cshape.shape = crouching_cshape
player.cshape.position.y = -66
player.sprite.position.y = -42
else:
player.cshape.shape = standing_cshape
player.cshape.position.y = -30
player.sprite.position.y = -44
player.ap.advance(delta)
var current_root_pos = player.RootMotion.position #rootmotion
var root_delta = current_root_pos - player.rootmotion_prev #rootmotion
player.position += Vector2(root_delta.x * player.facing_direction, root_delta.y)
player.rootmotion_prev = current_root_pos #rootmotion
func physics_update(delta):
if not player.ap.is_playing():
Transitioned.emit(self, "PlayerFall")

View File

@ -0,0 +1 @@
uid://dq3g3qck2e0wv

View File

@ -9,8 +9,13 @@ func enter():
player.velocity.x = 2000 * player.facing_direction # An Wand haften
player.ap.play("wallrun")
player.sprite.position.x = player.facing_direction * -10
func exit():
player.wallrun_timer = 0.0
player.sprite.position.x = 0
player.velocity.y = 0
func update(delta):
pass
@ -21,7 +26,7 @@ func physics_update(delta):
if player.facing_direction > 0 && !player.wallrun_raycast_right2.is_colliding():
Transitioned.emit(self, "PlayerFall")
if player.facing_direction < 1 && !player.wallrun_raycast_left2.is_colliding():
elif player.facing_direction < 1 && !player.wallrun_raycast_left2.is_colliding():
Transitioned.emit(self, "PlayerFall")
elif player.wallrun_timer >= player.wallrun_time:
Transitioned.emit(self, "PlayerWallrunPushoff")