class_name Mech extends CharacterBody2D ## M03, greybox slab. Piloting is positioning ONLY (canon: no aim, no ## combos) — movement input is the entire control surface. signal hull_changed(hull: float, hull_max: float) signal destroyed @export var move_speed := 160.0 @export var accel := 900.0 @export var decel := 1200.0 @export var hull_max := 100.0 @export var dash_decay := 4.0 var hull: float var _dash := Vector2.ZERO func _ready() -> void: add_to_group("mech") hull = hull_max # Runtime load (not preload): a stale/incomplete import cache must # degrade to an invisible sprite, never a script-compile failure # that would kill movement too. var spr := Sprite2D.new() spr.texture = load("res://assets/sprites_ph/m03_ph.png") add_child(spr) func _physics_process(delta: float) -> void: var dir := Input.get_vector("move_left", "move_right", "move_up", "move_down") var rate := accel if dir != Vector2.ZERO else decel _dash = _dash.lerp(Vector2.ZERO, 1.0 - exp(-dash_decay * delta)) velocity = velocity.move_toward(dir * move_speed, rate * delta) + _dash move_and_slide() velocity -= _dash func impulse(v: Vector2) -> void: _dash += v func take_damage(amount: float) -> void: if hull <= 0.0: return hull = maxf(hull - amount, 0.0) hull_changed.emit(hull, hull_max) if hull <= 0.0: # The run manager decides what death means (tally + relaunch). destroyed.emit()