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:
2026-08-31 00:31:29 +08:00
parent 024447fbda
commit 3c6f31b503
36 changed files with 1692 additions and 0 deletions
+163
View File
@@ -0,0 +1,163 @@
class_name WaveSpawner
extends Node
## 波次生成器:时间线循环刷敌,每轮提升难度。
var difficulty := 1.0
var game: Game
func _ready() -> void:
call_deferred("_run")
func _run() -> void:
game = get_tree().get_first_node_in_group("game") as Game
await get_tree().create_timer(0.8).timeout
var round_num := 1
while true:
difficulty = minf(1.0 + (round_num - 1) * 0.12, 1.8)
await _play_round()
await _wait_playing()
# 关底 Boss 战
if game != null and is_instance_valid(game):
game.show_boss_warning()
await _timer(2.0)
await _wait_playing()
var boss: Boss = null
if game != null and is_instance_valid(game):
boss = game.spawn_boss(difficulty)
while boss != null and is_instance_valid(boss):
await _timer(0.3)
await _wait_playing()
await _timer(2.5)
round_num += 1
await get_tree().create_timer(2.5).timeout
func _play_round() -> void:
await _wait_playing()
await _column(140.0)
await _timer(3.2)
await _wait_playing()
_v_formation(270.0)
await _timer(3.8)
await _wait_playing()
_sine_squad(170.0)
_sine_squad(370.0)
await _timer(3.8)
await _wait_playing()
_fortress(120.0)
_fortress(420.0)
await _timer(2.6)
await _wait_playing()
await _column(400.0)
await _timer(0.8)
await _column(120.0)
await _timer(3.0)
await _wait_playing()
_medium(1, 210.0)
await _timer(4.0)
await _wait_playing()
_ship(190.0)
await _timer(4.0)
await _wait_playing()
_v_formation(160.0)
await _timer(1.4)
_v_formation(380.0)
await _timer(3.6)
await _wait_playing()
_sine_squad(270.0)
_fortress(270.0)
await _timer(3.4)
await _wait_playing()
_medium(-1, 260.0)
await _column(270.0)
_ship(380.0)
await _timer(4.2)
## 游戏结束时挂起等待,避免继续刷敌
func _wait_playing() -> void:
while game == null or game.state != Game.State.PLAYING:
await get_tree().create_timer(0.5).timeout
func _timer(duration: float) -> void:
await get_tree().create_timer(duration).timeout
## 纵队:同一直线依次下压,头机掉宝
func _column(x: float) -> void:
for i in 5:
_spawn_small(x, -30.0 - 46.0, 190.0 * difficulty, 0.0, 2.0, 0.0, true, 250.0 * difficulty, i == 0)
await _timer(0.32)
## V 字编队:5 机整体压境,仅领队开火并掉宝
func _v_formation(center_x: float) -> void:
var offsets := [Vector2(0.0, -30.0), Vector2(-44.0, -66.0), Vector2(44.0, -66.0), Vector2(-88.0, -102.0), Vector2(88.0, -102.0)]
for i in offsets.size():
var offset: Vector2 = offsets[i]
var is_leader := i == 0
_spawn_small(center_x + offset.x, offset.y, 150.0 * difficulty, 16.0, 1.6, 0.0, is_leader, 240.0 * difficulty, is_leader)
## 摆动机队:同路径依次进场、正弦横摆,头机掉宝
func _sine_squad(x: float) -> void:
for i in 4:
_spawn_small(x, -30.0, 130.0 * difficulty, 72.0, 1.8, 0.0, randf() < 0.5, 230.0 * difficulty, i == 0)
await _timer(0.4)
## 中型轰炸机横掠
func _medium(p_side: int, y: float) -> void:
var enemy := EnemyMedium.new()
enemy.setup(p_side, y, 112.0 * difficulty, 235.0 * difficulty, maxf(0.9, 1.6 / difficulty))
_add_enemy(enemy)
## 地面固定堡垒
func _fortress(x: float) -> void:
var enemy := EnemyFortress.new()
enemy.setup(x, -60.0, difficulty)
_add_enemy(enemy)
## 驱逐舰
func _ship(x: float) -> void:
var enemy := EnemyShip.new()
enemy.setup(x, -140.0, difficulty)
_add_enemy(enemy)
func _spawn_small(
x: float,
y: float,
vy: float,
sway_amp: float,
sway_freq: float,
phase: float,
shoot: bool,
bullet_speed: float,
drop := false
) -> void:
var enemy := EnemySmall.new()
enemy.setup(x, y, vy, sway_amp, sway_freq, phase, shoot, bullet_speed)
enemy.drops_powerup = drop
_add_enemy(enemy)
func _add_enemy(enemy: EnemyBase) -> void:
var container := get_tree().get_first_node_in_group("enemies")
if container == null:
return
container.add_child(enemy)