Files
spacel/scripts/ship_select.gd
alpacaman edc40f9008 Initial commit — Godot space roguelite source
- Touch controls: direct InputEventScreenTouch in shop_ui (bypass relay)
- ItemDB: static preload list instead of DirAccess scan (export fix)
- All 18 items with EN localisation (name_en, desc_en, category_en)
- Ship playstyles: NOVA-1 shield, INFERNO ram, AURORA agile/tank
- Quasar: SMBH visual, jet boost, merge, push, BH-eating
- Atlas & UI text updated EN+DE

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-21 14:38:09 +02:00

168 lines
6.6 KiB
GDScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
extends Node2D
var W: float = 960.0
var H: float = 600.0
# Cockpit palette
const COL_BG := Color(0.0, 0.04, 0.02, 0.90)
const COL_PRIMARY := Color(0.0, 1.0, 0.533, 1.0) # phosphor green
const COL_ACCENT := Color(0.27, 1.0, 0.8, 1.0)
const COL_DIM := Color(0.0, 0.27, 0.13, 0.6) # lines / brackets only
const COL_TEXT := Color(0.3, 0.68, 0.46, 0.88) # readable secondary text
const COL_P2 := Color(0.27, 1.0, 0.67, 1.0)
const COL_OVERLAY := Color(0.0, 0.0, 0.04, 0.78)
var is_p2_mode: bool = false
var selected: int = 0
var ships: Array = []
var blink_phase: float = 0.0
var enter_blink: bool = true
var enter_timer: float = 0.0
func start_select(p2_mode: bool, start_sel: int, ship_data: Array) -> void:
is_p2_mode = p2_mode
selected = start_sel
ships = ship_data
visible = true
blink_phase = 0.0
func set_selection(idx: int) -> void:
selected = idx
queue_redraw()
func _process(delta: float) -> void:
blink_phase += delta
enter_timer += delta
if enter_timer >= 0.5:
enter_timer = 0.0
enter_blink = not enter_blink
queue_redraw()
func _draw() -> void:
var vs: Vector2 = get_viewport_rect().size
W = vs.x; H = vs.y
# Background overlay so live simulation shows through
draw_rect(get_viewport_rect(), COL_OVERLAY)
# ── Header bar ───────────────────────────────────────────────────────────
draw_rect(Rect2(0, 0, W, 52.0), Color(0.0, 0.04, 0.02, 0.92))
draw_line(Vector2(0, 52), Vector2(W, 52), COL_DIM, 1.0)
var header_col := COL_PRIMARY if not is_p2_mode else COL_P2
_draw_text_centered(Tr.t("select_header"), W * 0.5, 14.0, 10, COL_TEXT)
var sub := Tr.t("select_pilot1") if not is_p2_mode else Tr.t("select_pilot2")
_draw_text_centered(sub, W * 0.5, 30.0, 13, header_col)
# Outer corner brackets
_draw_corner_brackets(8.0, 8.0, W - 8.0, H - 8.0, COL_DIM, 16.0)
# ── Ship boxes ───────────────────────────────────────────────────────────
# 2×2 Grid Layout (supports 4 ships, falls back for 3)
var n := ships.size()
var cols: int = 2 if n >= 4 else min(n, 3)
var box_w := 220.0; var box_h := 180.0
if cols == 3:
box_w = 210.0; box_h = 220.0
var row_h: float = box_h + 16.0
var col_space: float = (W - box_w * cols) / float(cols + 1)
var grid_start_y: float = 72.0
for i in n:
var col_i: int = i % cols
var row_i: int = int(i / cols)
var bx: float = col_space + col_i * (box_w + col_space)
var by: float = grid_start_y + row_i * row_h
var is_sel := i == selected
var pulse := 0.5 + 0.5 * sin(blink_phase * 3.0)
# Box background
draw_rect(Rect2(bx, by, box_w, box_h), Color(0.0, 0.04, 0.02, 0.72))
# Corner L-brackets instead of full border
var bracket_col: Color
if is_sel:
bracket_col = Color(COL_ACCENT.r, COL_ACCENT.g, COL_ACCENT.b, 0.6 + 0.4 * pulse)
else:
bracket_col = COL_DIM
_draw_corner_brackets(bx, by, bx + box_w, by + box_h, bracket_col, 16.0)
# Ship preview
var cx := bx + box_w * 0.5
var cy := by + box_h * 0.42
var preview_heading := blink_phase * 0.6 if is_sel else -PI * 0.5
_draw_ship_preview(cx, cy, preview_heading, ships[i])
# Ship name
var name_col := COL_ACCENT if is_sel else COL_TEXT
_draw_text_centered(ships[i]["name"], cx, by + box_h - 42.0, 12, name_col)
# Ship identifier or boost hint
var sub_str: String
match ships[i]["id"]:
"classic": sub_str = "1 SHIELD · BALANCED"
"inferno": sub_str = "SPEED+ · RAM DAMAGE"
"aurora": sub_str = "2 SHIELDS · BH RESIST"
"titan": sub_str = "[SHIFT] BOOST"
_: sub_str = ships[i]["id"].to_upper()
_draw_text_centered(sub_str, cx, by + box_h - 24.0, 8,
Color(COL_TEXT.r, COL_TEXT.g, COL_TEXT.b, 0.85))
# ── Footer ───────────────────────────────────────────────────────────────
draw_rect(Rect2(0, H - 48.0, W, 48.0), Color(0.0, 0.04, 0.02, 0.92))
draw_line(Vector2(0, H - 48.0), Vector2(W, H - 48.0), COL_DIM, 1.0)
_draw_text_centered(Tr.hint("select_choose"), W * 0.5, H - 44.0, 9, COL_TEXT)
if not is_p2_mode:
if enter_blink:
_draw_text_centered(Tr.hint("select_confirm"), W * 0.5, H - 26.0, 11, COL_PRIMARY)
else:
_draw_text_centered(Tr.hint("select_join"), W * 0.3, H - 26.0, 10,
COL_P2 if enter_blink else COL_DIM)
_draw_text_centered(Tr.hint("select_solo"), W * 0.7, H - 26.0, 10,
COL_PRIMARY if enter_blink else COL_DIM)
# ── Drawing helpers ───────────────────────────────────────────────────────────
func _draw_corner_brackets(x1: float, y1: float, x2: float, y2: float,
col: Color, arm: float) -> void:
# Top-left
draw_line(Vector2(x1, y1), Vector2(x1 + arm, y1), col, 1.5)
draw_line(Vector2(x1, y1), Vector2(x1, y1 + arm), col, 1.5)
# Top-right
draw_line(Vector2(x2, y1), Vector2(x2 - arm, y1), col, 1.5)
draw_line(Vector2(x2, y1), Vector2(x2, y1 + arm), col, 1.5)
# Bottom-left
draw_line(Vector2(x1, y2), Vector2(x1 + arm, y2), col, 1.5)
draw_line(Vector2(x1, y2), Vector2(x1, y2 - arm), col, 1.5)
# Bottom-right
draw_line(Vector2(x2, y2), Vector2(x2 - arm, y2), col, 1.5)
draw_line(Vector2(x2, y2), Vector2(x2, y2 - arm), col, 1.5)
func _draw_ship_preview(cx: float, cy: float, heading: float, ship: Dictionary) -> void:
var cos_h := cos(heading); var sin_h := sin(heading)
var preview_scale := 5.5
var hull_pixels := [
[3, 0, "nose"], [2, -1, "mid"], [2, 1, "mid"],
[1, 0, "dim"], [0, -2, "accent"],[0, 2, "accent"],
[0, 0, "bright"],[-1,-1, "dim"], [-1, 1, "dim"],
[-2,-2, "shadow"],[-2, 2, "shadow"],[-2, 0, "edge"],
]
for px_data in hull_pixels:
var lx: float = px_data[0] * preview_scale
var ly: float = px_data[1] * preview_scale
var col: Color = ship.get(px_data[2], Color.WHITE)
var rx := cx + lx * cos_h - ly * sin_h
var ry := cy + lx * sin_h + ly * cos_h
draw_rect(Rect2(rx - 2, ry - 2, 5, 5), col)
func _draw_text_centered(text: String, x: float, y: float, font_size: int, col: Color) -> void:
var font := ThemeDB.fallback_font
var tw := font.get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, font_size).x
draw_string(font, Vector2(x - tw * 0.5, y + font_size), text,
HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, col)
func _draw_text(text: String, x: float, y: float, font_size: int, col: Color) -> void:
var font := ThemeDB.fallback_font
draw_string(font, Vector2(x, y + font_size), text,
HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, col)