3c6f31b503
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
79 lines
2.1 KiB
GDScript
79 lines
2.1 KiB
GDScript
class_name LaserBeam
|
|
extends Node2D
|
|
## 直线激光束:从所在位置垂直向上延伸,被第一个命中的敌人截断,
|
|
## 对其造成持续伤害(dps)。视觉为核心线 + 外发光双层 Line2D。
|
|
|
|
var dps := 10.0
|
|
var width := 5.0
|
|
var color := Color(0.55, 0.9, 1.0)
|
|
var active := false
|
|
|
|
var _core: Line2D
|
|
var _glow: Line2D
|
|
var _acc := 0.0
|
|
var _t := 0.0
|
|
|
|
|
|
func _ready() -> void:
|
|
z_index = 5
|
|
_glow = Line2D.new()
|
|
_glow.width = width * 2.8
|
|
_glow.default_color = Color(color, 0.28)
|
|
_glow.points = [Vector2.ZERO, Vector2(0.0, -10.0)]
|
|
add_child(_glow)
|
|
_core = Line2D.new()
|
|
_core.width = width
|
|
_core.default_color = color
|
|
_core.points = [Vector2.ZERO, Vector2(0.0, -10.0)]
|
|
add_child(_core)
|
|
visible = false
|
|
|
|
|
|
## 从自身祖先中解析所属游戏的敌容器(避免多实例时全局组查找拿错容器)
|
|
func _get_enemies_container() -> Node2D:
|
|
var node := get_parent()
|
|
while node != null:
|
|
var candidate := node.get_node_or_null("Enemies")
|
|
if candidate != null:
|
|
return candidate as Node2D
|
|
node = node.get_parent()
|
|
return null
|
|
|
|
|
|
func _process(delta: float) -> void:
|
|
if not active:
|
|
if visible:
|
|
visible = false
|
|
return
|
|
visible = true
|
|
_t += delta
|
|
|
|
var muzzle := global_position
|
|
var hit_y := -40.0
|
|
var target: EnemyBase = null
|
|
var container := _get_enemies_container()
|
|
if container != null:
|
|
for enemy in container.get_children():
|
|
if enemy is EnemyBase and not (enemy as EnemyBase).dead:
|
|
var e := enemy as EnemyBase
|
|
if absf(e.global_position.x - muzzle.x) < e.hit_radius + width * 0.5:
|
|
# 光束向上:命中敌人底缘;若炮口已进入敌人范围则从炮口起算
|
|
var hy := minf(muzzle.y, e.global_position.y + e.hit_radius)
|
|
if hy >= hit_y:
|
|
hit_y = hy
|
|
target = e
|
|
|
|
var length := maxf(muzzle.y - hit_y, 0.0)
|
|
var pulse := 1.0 + 0.1 * sin(_t * 42.0)
|
|
_core.width = width * pulse
|
|
_glow.width = width * 2.8 * pulse
|
|
_core.points = [Vector2.ZERO, Vector2(0.0, -length)]
|
|
_glow.points = [Vector2.ZERO, Vector2(0.0, -length)]
|
|
|
|
if target != null and is_instance_valid(target):
|
|
_acc += dps * delta
|
|
if _acc >= 1.0:
|
|
var whole := int(_acc)
|
|
_acc -= float(whole)
|
|
target.apply_damage(whole)
|