class_name Title extends Node2D ## 启动界面:滚动海面打底,左右选择战机,回车/J 出击。 const PLANE_A_TEX := Player.TEX const PLANE_B_TEX := preload("res://assets/svg/plane_funnel.svg") # 兜底:美术 PNG 存在时优先 const FUNNEL_TEX := preload("res://assets/svg/funnel.svg") const PLANE_B_ART := "res://assets/art/plane_funnel.png" static func _plane_b_texture() -> Texture2D: if ResourceLoader.exists(PLANE_B_ART): return load(PLANE_B_ART) return PLANE_B_TEX var _sel := 0 var _started := false var _borders: Array[ColorRect] = [] func _ready() -> void: add_child(OceanScroll.new()) var dim := ColorRect.new() dim.color = Color(0.02, 0.05, 0.1, 0.62) dim.set_anchors_preset(Control.PRESET_FULL_RECT) add_child(dim) var layer := CanvasLayer.new() layer.layer = 10 add_child(layer) var title := Label.new() title.text = "AERO STRIKE" title.position = Vector2(0.0, 130.0) title.size = Vector2(540.0, 80.0) title.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER title.add_theme_font_size_override("font_size", 64) title.add_theme_color_override("font_color", Color(1.0, 0.85, 0.35)) title.add_theme_color_override("font_shadow_color", Color(0.0, 0.0, 0.0, 0.8)) title.add_theme_constant_override("shadow_offset_x", 3) title.add_theme_constant_override("shadow_offset_y", 3) layer.add_child(title) var subtitle := Label.new() subtitle.text = "1 9 4 2" subtitle.position = Vector2(0.0, 205.0) subtitle.size = Vector2(540.0, 40.0) subtitle.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER subtitle.add_theme_font_size_override("font_size", 28) subtitle.add_theme_color_override("font_color", Color(0.85, 0.9, 1.0)) layer.add_child(subtitle) var choose := Label.new() choose.text = "— 选择战机 —" choose.position = Vector2(0.0, 300.0) choose.size = Vector2(540.0, 34.0) choose.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER choose.add_theme_font_size_override("font_size", 24) choose.add_theme_color_override("font_color", Color.WHITE) layer.add_child(choose) _build_card(layer, 0, 40.0, PLANE_A_TEX, "P-38 战斗机", "宽域机枪弹幕", "P 升级火力 · K 炸弹") _build_card(layer, 1, 280.0, _plane_b_texture(), "雷光 浮游炮型", "贯穿激光 + 浮游炮", "I 聚焦合体激光 · K 炸弹", true) var hint := Label.new() hint.text = "←→ 选择 回车 / J 出击" hint.position = Vector2(0.0, 880.0) hint.size = Vector2(540.0, 34.0) hint.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER hint.add_theme_font_size_override("font_size", 22) hint.add_theme_color_override("font_color", Color(0.75, 0.8, 0.85)) layer.add_child(hint) _update_selection() func _build_card(parent: Node, index: int, x: float, tex: Texture2D, plane_name: String, line1: String, line2: String, with_funnels := false) -> void: var bg := ColorRect.new() bg.position = Vector2(x, 350.0) bg.size = Vector2(220.0, 330.0) bg.color = Color(0.08, 0.12, 0.18, 0.92) parent.add_child(bg) var border := ColorRect.new() border.position = bg.position - Vector2(4.0, 4.0) border.size = bg.size + Vector2(8.0, 8.0) border.color = Color(1.0, 0.82, 0.25) parent.add_child(border) _borders.append(border) var icon := Sprite2D.new() icon.texture = tex icon.scale = Vector2.ONE * 1.7 icon.position = Vector2(x + 110.0, 455.0) parent.add_child(icon) if with_funnels: for i in 2: var funnel := Sprite2D.new() funnel.texture = FUNNEL_TEX funnel.position = Vector2(x + 110.0 + (-60.0 if i == 0 else 60.0), 425.0 + 30.0 * i) parent.add_child(funnel) var name_label := Label.new() name_label.text = plane_name name_label.position = Vector2(x, 545.0) name_label.size = Vector2(220.0, 34.0) name_label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER name_label.add_theme_font_size_override("font_size", 24) name_label.add_theme_color_override("font_color", Color.WHITE) parent.add_child(name_label) var desc1 := Label.new() desc1.text = line1 desc1.position = Vector2(x, 600.0) desc1.size = Vector2(220.0, 28.0) desc1.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER desc1.add_theme_font_size_override("font_size", 19) desc1.add_theme_color_override("font_color", Color(0.8, 0.88, 1.0)) parent.add_child(desc1) var desc2 := Label.new() desc2.text = line2 desc2.position = Vector2(x, 640.0) desc2.size = Vector2(220.0, 26.0) desc2.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER desc2.add_theme_font_size_override("font_size", 17) desc2.add_theme_color_override("font_color", Color(0.7, 0.78, 0.88)) parent.add_child(desc2) func _process(_delta: float) -> void: if _started: return if Input.is_action_just_pressed("move_left") and _sel != 0: _sel = 0 _update_selection() elif Input.is_action_just_pressed("move_right") and _sel != 1: _sel = 1 _update_selection() if Input.is_action_just_pressed("ui_accept") or Input.is_action_just_pressed("fire"): _started = true GameSession.plane_variant = _sel get_tree().change_scene_to_file("res://scenes/game.tscn") func _update_selection() -> void: for i in _borders.size(): _borders[i].visible = i == _sel