Files
dreamer-game/scripts/player.gd
2026-08-29 11:43:53 +02:00

151 lines
4.2 KiB
GDScript

extends CharacterBody3D
class_name Player
## Ein Wesen aus der Traumwelt. In der Traumwelt läuft es, auf der Erde schwebt
## es als unsichtbarer Geist durch Wände.
enum Mode { TRAUM, GEIST }
const SPEED_TRAUM := 8.0
const SPEED_GEIST := 11.0
const GRAVITY := 24.0
const JUMP := 9.0
const MAUS := 0.0026
var mode: int = Mode.TRAUM
var yaw := 0.0
var pitch := -0.25
var look_enabled := true
var pivot: Node3D
var arm: SpringArm3D
var cam: Camera3D
var body: Node3D
var _kern: MeshInstance3D
var _ringe: Array = []
func _ready() -> void:
var cs := CollisionShape3D.new()
var shape := CapsuleShape3D.new()
shape.radius = 0.45
shape.height = 1.9
cs.shape = shape
cs.position.y = 0.95
add_child(cs)
body = Node3D.new()
add_child(body)
_kern = Prims.capsule(body, Vector3(0, 1.0, 0), 0.42, 1.6, Color(0.55, 0.85, 1.0))
_kern.material_override = Prims.mat(Color(0.55, 0.85, 1.0), 0.9)
var kopf := Prims.sphere(body, Vector3(0, 2.0, 0), 0.28, Color(0.80, 0.92, 1.0), 0.6)
kopf.name = "Kopf"
for i in range(2):
var r := Prims.cyl(body, Vector3(0, 0.5 + i * 0.9, 0), 0.75 + i * 0.15, 0.06,
Color(0.6, 0.9, 1.0), false, 1.6)
r.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
_ringe.append(r)
# kleiner Blick nach vorn, damit man die Laufrichtung sieht
Prims.box(body, Vector3(0, 1.55, -0.36), Vector3(0.5, 0.12, 0.12), Color(1, 1, 1), false, 2.0)
pivot = Node3D.new()
pivot.position.y = 1.5
add_child(pivot)
arm = SpringArm3D.new()
arm.position.x = 0.75
arm.spring_length = 6.5
arm.margin = 0.3
pivot.add_child(arm)
cam = Camera3D.new()
cam.fov = 74.0
arm.add_child(cam)
set_mode(Mode.TRAUM)
func set_mode(m: int) -> void:
mode = m
if m == Mode.GEIST:
collision_layer = 0
collision_mask = 0
arm.collision_mask = 0
arm.spring_length = 5.0
pivot.position.y = 2.1
body.scale = Vector3.ONE * 0.72
_kern.material_override = Prims.mat(Color(0.65, 0.9, 1.0, 0.26), 0.5)
for r in _ringe:
r.material_override = Prims.mat(Color(0.7, 0.95, 1.0, 0.20), 0.8)
r.scale = Vector3(0.55, 1.0, 0.55)
else:
collision_layer = 1
collision_mask = 1
arm.collision_mask = 1
arm.spring_length = 6.5
pivot.position.y = 1.5
body.scale = Vector3.ONE
_kern.material_override = Prims.mat(Color(0.55, 0.85, 1.0), 0.9)
for r in _ringe:
r.material_override = Prims.mat(Color(0.6, 0.9, 1.0), 1.6)
r.scale = Vector3.ONE
velocity = Vector3.ZERO
func _unhandled_input(event: InputEvent) -> void:
if not look_enabled:
return
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
yaw -= event.relative.x * MAUS
pitch = clampf(pitch - event.relative.y * MAUS, -1.3, 0.6)
func _physics_process(delta: float) -> void:
pivot.rotation.y = yaw
arm.rotation.x = pitch
for i in range(_ringe.size()):
var r: MeshInstance3D = _ringe[i]
r.rotation.y += delta * (0.8 + 0.5 * i)
r.position.y = 0.5 + i * 0.9 + sin(Time.get_ticks_msec() * 0.001 * (1.2 + i * 0.4)) * 0.12
var input := Vector2.ZERO
if look_enabled:
input.x = Input.get_axis("links", "rechts")
input.y = Input.get_axis("vor", "zurueck")
var dir := Vector3.ZERO
if input.length() > 0.01:
var basis_yaw := Basis(Vector3.UP, yaw)
dir = (basis_yaw * Vector3(input.x, 0, input.y)).normalized()
if mode == Mode.GEIST:
var v := dir * SPEED_GEIST
if look_enabled:
if Input.is_action_pressed("steigen"):
v.y += SPEED_GEIST * 0.75
if Input.is_action_pressed("sinken"):
v.y -= SPEED_GEIST * 0.75
velocity = velocity.lerp(v, 1.0 - pow(0.001, delta))
move_and_slide()
if global_position.y < 0.4:
global_position.y = 0.4
if global_position.y > 45.0:
global_position.y = 45.0
else:
velocity.x = lerpf(velocity.x, dir.x * SPEED_TRAUM, 1.0 - pow(0.0005, delta))
velocity.z = lerpf(velocity.z, dir.z * SPEED_TRAUM, 1.0 - pow(0.0005, delta))
if is_on_floor():
if look_enabled and Input.is_action_pressed("steigen"):
velocity.y = JUMP
else:
velocity.y = -1.0
else:
velocity.y -= GRAVITY * delta
move_and_slide()
if global_position.y < -400.0:
global_position.y = 2.0
if dir.length() > 0.01:
var ziel := atan2(-dir.x, -dir.z)
body.rotation.y = lerp_angle(body.rotation.y, ziel, 1.0 - pow(0.0005, delta))
func blickrichtung() -> Vector3:
return -Vector3(sin(yaw), 0, cos(yaw))