feat: 场景与核心玩法脚本(双机型/波次/Boss/道具/炸弹/地面单位/浮游炮激光)
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user