extends CharacterBody2D @export var speed = 350 @export var gravity = 40 @export var jump_force = 800 @export var fallvelocity_cap = 1000 # How fast the player can get when falling @export var max_air_jumps = 1 # Number of total jumps allowed (1 = normal, 2 = double jump) @export var crouch_mult = 1 @export var sprint_mult = 1 @onready var ap = $AnimationPlayer @onready var sprite = $Sprite2D @onready var cshape = $mainbody @onready var crouch_raycast1 = $crouchrc1 @onready var crouch_raycast2 = $crouchrc2 @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 wallcheck = $wallcheck @onready var floorcheck = $floorcheck var air_jumps_done = 0 var is_crouching = false var stuck_under_object = false 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 wallpushoff_force := 450 # Stärke des Abstoßens var wallpushoff_timer := 0.0 var wallpushoff_time := 0.5 # dauer des pushoffs var wallrunning := false var pushingoffwall := false var wallrun_direction := 0 # -1 = links, 1 = rechts var standing_cshape = preload("res://resources/player standing cshape.tres") var crouching_cshape = preload("res://resources/player crouching cshape.tres") func _process(delta): pass func _physics_process(delta): var horizontal_direction = Input.get_axis("move_left", "move_right") if !is_on_floor(): velocity.y += gravity if velocity.y > fallvelocity_cap: velocity.y = fallvelocity_cap else: air_jumps_done = 0 wallrun_available = true if Input.is_action_just_pressed("jump") && Input.is_action_pressed("move_right") && wall_detected_right() && wallrun_available: start_wallrun(1) elif Input.is_action_just_pressed("jump") && Input.is_action_pressed("move_left") && wall_detected_left() && wallrun_available: start_wallrun(-1) elif Input.is_action_just_pressed("jump"): if is_on_floor(): velocity.y = -jump_force elif air_jumps_done < max_air_jumps: velocity.y = -jump_force air_jumps_done += 1 if wallrunning: wallrun_timer += delta velocity.y = wallrun_speed # Bewegt nach oben if wallrun_direction > 0 && !wallrun_raycast_right2.is_colliding(): ledgedetected() if wallrun_direction < 1 && !wallrun_raycast_left2.is_colliding(): ledgedetected() elif wallrun_timer >= wallrun_time: wallpushoff() elif pushingoffwall: wallpushoff_timer += delta velocity.x = speed * 0.3 * horizontal_direction + (-wallrun_direction * wallpushoff_force) if wallpushoff_timer >= wallpushoff_time: pushingoffwall = false else: velocity.x = speed * horizontal_direction * crouch_mult if horizontal_direction != 0: switchdirection(horizontal_direction) if Input.is_action_just_pressed("crouch"): crouch() elif Input.is_action_just_released("crouch"): if above_head_empty(): stand() else: if stuck_under_object != true: stuck_under_object = true print("player stuck under object") if stuck_under_object && above_head_empty(): if !Input.is_action_pressed("crouch"): stand() stuck_under_object = false move_and_slide() update_animation(horizontal_direction) func above_head_empty() -> bool: var result = !crouch_raycast1.is_colliding() && !crouch_raycast2.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 start_wallrun(direction: int): wallrunning = true wallrun_available = false wallrun_direction = direction velocity.x = 1000 * wallrun_direction # An Wand haften print("start wallrun called") func wallpushoff(): wallrunning = false pushingoffwall = true wallpushoff_timer = 0.0 wallrun_timer = 0.0 print("stop wallrun called") func ledgedetected(): wallrunning = false wallrun_timer = 0.0 func checkledgegrab() -> bool: var result = wallcheck.is_colliding() && !floorcheck.is_colliding() && velocity.y == 0 return result func update_animation(horizontal_direction): if is_on_floor(): if horizontal_direction == 0: if is_crouching: ap.play("crouch idle") else: ap.play("idle") else: if is_crouching: ap.play("crouch walk") else: ap.play("run") else: if velocity.y < 0: if air_jumps_done == 0 : ap.play("jump") elif air_jumps_done == 1: ap.play("double jump") elif velocity.y > 0: ap.play("fall") func crouch(): if is_crouching: return is_crouching = true crouch_mult = 0.4 cshape.shape = crouching_cshape cshape.position.y = -31 func stand(): if is_crouching == false: return is_crouching = false crouch_mult = 1 cshape.shape = standing_cshape cshape.position.y = -44 func switchdirection(horizontal_direction): sprite.flip_h = (horizontal_direction == -1) sprite.position.x = horizontal_direction * 4