From c6b60ea0028d9f52e111712918955ef8d9d849a5 Mon Sep 17 00:00:00 2001 From: Artur <2123806@stud.th-mannheim.de> Date: Wed, 3 Jun 2026 18:19:57 +0200 Subject: [PATCH] changed laser build up logic to allow for actual enemy tracking --- scripts/beam.gd | 1 + scripts/laser.gd | 58 ++++++++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/scripts/beam.gd b/scripts/beam.gd index 90fd51f..aec735e 100644 --- a/scripts/beam.gd +++ b/scripts/beam.gd @@ -6,6 +6,7 @@ extends Area2D @onready var shape: CollisionShape2D = $CollisionShape2D func _ready() -> void: + scale = Vector2(0.7, 0.7) if sprite.sprite_frames.has_animation(beam_type): sprite.play(beam_type) shape.disabled = beam_type != "middle" diff --git a/scripts/laser.gd b/scripts/laser.gd index fa56bcc..9d87aac 100644 --- a/scripts/laser.gd +++ b/scripts/laser.gd @@ -5,8 +5,10 @@ const PRIMARY_TICK_DMG := 40 const SPLASH_TICK_DMG := 3 const TICK_INTERVAL := 0.5 const SWEEP_RATE := 22.0 +const FADE_IN := 0.3 +const FADE_OUT := 0.5 -@export var segment_size := 16.0 +@export var segment_size := 8.0 @export var start_offset := 24.0 @onready var perk_effects = get_node("/root/Game/PerkEffects") @@ -18,9 +20,9 @@ var mid_segs: Array = [] var tick_timer := 0.0 var elapsed := 0.0 var done := false -var current_angle := 0.0 -var sweep_to := 0.0 -var sweeping := false +var current_angle := 0.0 +var sweep_dest_angle := 0.0 +var sweeping := false func _ready() -> void: target = get_highest_hp_enemy() @@ -36,13 +38,26 @@ func _process(delta: float) -> void: elapsed += delta tick_timer += delta - if sweeping: - current_angle = lerp_angle(current_angle, sweep_to, 1.0 - exp(-SWEEP_RATE * delta)) - if abs(angle_difference(current_angle, sweep_to)) < 0.005: - current_angle = sweep_to - sweeping = false + if (not is_instance_valid(target) or target.is_dying) and perk_effects.laser_retarget_enabled: + var new_target := get_highest_hp_enemy() + if new_target != null: + target = new_target + sweep_dest_angle = global_position.direction_to(target.global_position).angle() + sweeping = true + + if is_instance_valid(target) and not target.is_dying: + var live_angle := global_position.direction_to(target.global_position).angle() + if sweeping: + current_angle = lerp_angle(current_angle, sweep_dest_angle, 1.0 - exp(-SWEEP_RATE * delta)) + if abs(angle_difference(current_angle, sweep_dest_angle)) < 0.01: + sweeping = false + current_angle = live_angle + else: + current_angle = live_angle rebuild_segments() + _update_alpha() + if tick_timer >= TICK_INTERVAL: tick_timer -= TICK_INTERVAL do_damage_tick() @@ -51,18 +66,20 @@ func _process(delta: float) -> void: cleanup() func rebuild_segments() -> void: + if not is_instance_valid(target): + return var dir := Vector2.from_angle(current_angle) var beam_start := global_position + dir * start_offset var dest_dist := global_position.distance_to(target.global_position) var beam_dist := dest_dist - start_offset - var n_mid := int(max(0.0, beam_dist - segment_size) / segment_size) + var n_mid: int = max(0, ceili(beam_dist / segment_size) - 1) var positions: Array = [beam_start] var types: Array = ["start"] for i in range(n_mid): positions.append(beam_start + dir * (segment_size * float(i + 1))) types.append("middle") - positions.append(beam_start + dir * (segment_size * float(n_mid + 1))) + positions.append(beam_start + dir * beam_dist) types.append("end") while all_segs.size() < positions.size(): @@ -99,16 +116,11 @@ func rebuild_segments() -> void: seg.sprite.frame_progress = ref_progress func retarget(new_target: Node2D) -> void: - target = new_target - sweep_to = global_position.direction_to(new_target.global_position).angle() - sweeping = true + target = new_target + sweep_dest_angle = global_position.direction_to(target.global_position).angle() + sweeping = true func do_damage_tick() -> void: - if (not is_instance_valid(target) or target.is_dying) and perk_effects.laser_retarget_enabled: - var new_target = get_highest_hp_enemy() - if new_target != null: - retarget(new_target) - if is_instance_valid(target) and not target.is_dying: target.take_damage(PRIMARY_TICK_DMG) @@ -122,6 +134,14 @@ func do_damage_tick() -> void: body.take_damage(SPLASH_TICK_DMG) hit.append(body) +func _update_alpha() -> void: + var alpha := clampf(elapsed / FADE_IN, 0.0, 1.0) + if elapsed > BEAM_DURATION - FADE_OUT: + alpha = minf(alpha, clampf((BEAM_DURATION - elapsed) / FADE_OUT, 0.0, 1.0)) + for seg in all_segs: + if is_instance_valid(seg): + seg.modulate.a = alpha + func cleanup() -> void: for seg in all_segs: if is_instance_valid(seg):