This commit is contained in:
2026-09-10 07:47:15 -04:00
parent 1f555ed3e4
commit 1c4d0ecbfe
39 changed files with 1499 additions and 2357 deletions
+128 -64
View File
@@ -1,97 +1,161 @@
extends CharacterBody3D
const SPEED := 5.0
const JUMP_VELOCITY := 4.5
const MOUSE_SENSITIVITY := 0.003
# Acceleration and deceleration are m/s².
# max_speed is m/s.
@export var accel := 6.7
@export var deccel := 8.5
@export var max_speed := 6.2
const ACCEL := 20.0
const DECEL := 15.0
@export var has_suit := true
@export var has_hvms2 := true
@export var gravity := 9.8
@export var jump_velocity := 4.5
# Mouse sensitivity
@export var mouse_sensitivity := 0.003
# Maximum camera pitch in degrees
@export var max_pitch := 89.0
var movement_vec := Vector3.ZERO
var input_vec := Vector4.ZERO
var jump := false
var air_jumps := 0
func _ready() -> void:
if not has_suit:
$yaw/pitch/Camera/Hud.visible = false
if has_hvms2:
max_speed = 30.0
accel = 10
deccel = 20
jump_velocity = 10
# Capture the mouse when the game starts
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _input(event: InputEvent) -> void:
# Mouse-look
if event is InputEventMouseMotion:
if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
# Horizontal rotation: rotate the player
$yaw.rotate_y(-event.relative.x * mouse_sensitivity)
# Vertical rotation: rotate the camera
$yaw/pitch.rotate_x(-event.relative.y * mouse_sensitivity)
# Clamp pitch so the camera cannot flip upside down
$yaw/pitch.rotation.x = clamp(
$yaw/pitch.rotation.x,
deg_to_rad(-max_pitch),
deg_to_rad(max_pitch)
)
return
# Mouse click captures the mouse again
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
return
# Keyboard input
if event is InputEventKey:
if event.keycode == KEY_ESCAPE and event.pressed:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
return
var pressed: bool = event.pressed
if event.keycode == KEY_SPACE and event.pressed and is_on_floor():
velocity.y = JUMP_VELOCITY
match event.keycode:
KEY_W:
input_vec.w = 1.0 if pressed else 0.0
if event.keycode == KEY_E and event.pressed and not event.echo:
var node = $yaw/pitch/Facing.get_collider()
KEY_S:
input_vec.x = 1.0 if pressed else 0.0
if node and node.has_method("interact"):
node.interact(self)
KEY_A:
input_vec.y = 1.0 if pressed else 0.0
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
$yaw.rotate_y(-event.relative.x * MOUSE_SENSITIVITY)
KEY_D:
input_vec.z = 1.0 if pressed else 0.0
$yaw/pitch.rotate_x(-event.relative.y * MOUSE_SENSITIVITY)
KEY_SPACE:
if pressed and is_on_floor():
jump=true
$yaw/pitch.rotation.x = clamp(
$yaw/pitch.rotation.x,
deg_to_rad(-89.0),
deg_to_rad(89.0)
)
KEY_ESCAPE:
if pressed:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
KEY_SHIFT:
if has_hvms2:
velocity.y = max(velocity.y, -3) if pressed else velocity.y
gravity = 3 if pressed else 9.8
if is_on_floor():
velocity=$yaw/pitch/Camera.basis*Vector3(0,0,50)
func _physics_process(delta: float) -> void:
# Gravity
if not is_on_floor():
velocity += get_gravity() * delta
# W/S/A/D input
var input_direction := Vector2(
input_vec.z - input_vec.y,
input_vec.w - input_vec.x
)
# Read keyboard state directly
var input_x := 0.0
var input_z := 0.0
if Input.is_key_pressed(KEY_A):
input_x -= 1.0
if Input.is_key_pressed(KEY_D):
input_x += 1.0
if Input.is_key_pressed(KEY_W):
input_z -= 1.0
if Input.is_key_pressed(KEY_S):
input_z += 1.0
# Create movement vector
var input_direction := Vector3(input_x, 0.0, input_z)
# Prevent diagonal movement from being faster
if input_direction.length_squared() > 0.0:
if input_direction.length() > 1.0:
input_direction = input_direction.normalized()
# Rotate movement relative to yaw
var direction : Vector3 = $yaw.global_transform.basis * input_direction
direction.y = 0.0
# Camera yaw only
var yaw_basis: Basis = $yaw.global_transform.basis
if direction.length_squared() > 0.0:
direction = direction.normalized()
var forward := -yaw_basis.z
var right := yaw_basis.x
# Target velocity
var target := direction * SPEED
forward.y = 0.0
right.y = 0.0
var acceleration := ACCEL
if direction.length_squared() == 0.0:
acceleration = DECEL
forward = forward.normalized()
right = right.normalized()
# Smooth movement toward target
velocity.x = move_toward(
var target_direction := (
right * input_direction.x
+ forward * input_direction.y
)
# Target horizontal velocity in m/s
var target_velocity := target_direction * max_speed
# Current horizontal velocity in m/s
var current_velocity := Vector3(
velocity.x,
target.x,
0.0,
velocity.z
)
# Acceleration/deceleration in m/s²
var acceleration := accel if target_direction != Vector3.ZERO else deccel
current_velocity = current_velocity.move_toward(
target_velocity,
acceleration * delta
)
velocity.z = move_toward(
velocity.z,
target.z,
acceleration * delta
)
velocity.x = current_velocity.x
velocity.z = current_velocity.z
# Gravity
if not is_on_floor():
velocity.y -= gravity * delta
else:
if jump:
velocity.y=jump_velocity
jump=false
else:
velocity.y=0.0
if global_position.y<=-1000:
get_tree().reload_current_scene()
move_and_slide()