extends Area2D ## 固定激光:每隔一段时间循环「蓄力闪烁 -> 发射 -> 熄灭」。 ## 蓄力阶段只闪不伤人(给玩家反应时间),发射阶段碰到就扣血。 ## 光束从自己的原点沿 +X 方向伸出,想改朝向就转节点本身。 enum State { WAIT, WARMUP, FIRING } @export var length: float = 90.0 @export var thickness: float = 6.0 @export var damage: int = 1 ## 蓄力(闪烁警告)时长 @export var warmup: float = 0.8 ## 发射持续时长 @export var fire_time: float = 0.35 ## 两次发射之间的间隔 @export var cooldown: float = 1.8 ## 开场后第一次发射前的延迟 @export var start_delay: float = 1.0 @export var laser_color: Color = Color(1.0, 0.25, 0.25) @export var warn_color: Color = Color(1.0, 0.8, 0.4) var _state: int = State.WAIT var _timer: float = 0.0 var _first: bool = true var _beam: Polygon2D = null func _ready() -> void: add_to_group("hazard") _beam = get_node_or_null("Beam") as Polygon2D var half := thickness * 0.5 if _beam != null: _beam.polygon = PackedVector2Array([ Vector2(0.0, -half), Vector2(length, -half), Vector2(length, half), Vector2(0.0, half)]) _beam.color = laser_color _beam.visible = false var hit := get_node_or_null("HitBox") as CollisionShape2D if hit != null: var rect := RectangleShape2D.new() rect.size = Vector2(length, thickness) hit.shape = rect hit.position = Vector2(length * 0.5, 0.0) func _physics_process(delta: float) -> void: _timer += delta match _state: State.WAIT: var wait: float = start_delay if _first else cooldown if _timer >= wait: _first = false _state = State.WARMUP _timer = 0.0 State.WARMUP: if _beam != null: _beam.color = warn_color _beam.visible = fmod(_timer, 0.16) < 0.08 if _timer >= warmup: _state = State.FIRING _timer = 0.0 if _beam != null: _beam.color = laser_color _beam.visible = true State.FIRING: for body in get_overlapping_bodies(): if body.has_method("hurt"): body.hurt(damage) if _timer >= fire_time: _state = State.WAIT _timer = 0.0 if _beam != null: _beam.visible = false