Files
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

117 lines
4.3 KiB
GDScript

extends RefCounted
class_name Bullet
const BULLET_SPEED := 9.6
const MAX_LIFE := 180
const FADE_START := 150
const HIT_RADIUS := 9.6
var x: float; var y: float
var vx: float; var vy: float
var life: int = 0
var owner_type: String
var color: Color
var dead: bool = false
var effective_hit_radius: float = HIT_RADIUS
var pierce: bool = false
var pierce_hits: int = 0
var style: String = "default" # set by spaceship based on equipped weapon
func init(px: float, py: float, heading: float, otype: String) -> void:
x = px; y = py
vx = cos(heading) * BULLET_SPEED
vy = sin(heading) * BULLET_SPEED
owner_type = otype
match otype:
"p1": color = Color("#88aaff")
"p2": color = Color("#44ffaa")
"enemy": color = Color("#ff4444")
_: color = Color.WHITE
func update(world_w: float, world_h: float) -> void:
x += vx; y += vy
life += 1
if x < 0: x += world_w
elif x > world_w: x -= world_w
if y < 0: y += world_h
elif y > world_h: y -= world_h
if life >= MAX_LIFE: dead = true
func get_alpha() -> float:
if life >= FADE_START:
return 1.0 - float(life - FADE_START) / float(MAX_LIFE - FADE_START)
return 1.0
func draw(canvas: CanvasItem) -> void:
var a := get_alpha()
match style:
"plasma":
# Strahl — dicke Linie entlang der Flugrichtung, orange-gelb
var angle := atan2(vy, vx)
var len := 26.0
var ca := cos(angle); var sa := sin(angle)
var bx := x - ca * len * 0.6; var by := y - sa * len * 0.6
var ex := x + ca * len * 0.4; var ey := y + sa * len * 0.4
canvas.draw_line(Vector2(bx, by), Vector2(ex, ey), Color(1.0, 0.45, 0.05, a * 0.45), 5.0)
canvas.draw_line(Vector2(bx, by), Vector2(ex, ey), Color(1.0, 0.75, 0.15, a), 2.0)
canvas.draw_rect(Rect2(x - 1, y - 1, 3, 3), Color(1.0, 1.0, 0.7, a))
"laser":
# Dünner schneller Strahl, cyan-weiß
var angle := atan2(vy, vx)
var len := 22.0
var ca := cos(angle); var sa := sin(angle)
var bx := x - ca * len; var by := y - sa * len
canvas.draw_line(Vector2(bx, by), Vector2(x, y), Color(0.3, 0.9, 1.0, a * 0.4), 3.0)
canvas.draw_line(Vector2(bx, by), Vector2(x, y), Color(0.8, 1.0, 1.0, a), 1.0)
canvas.draw_rect(Rect2(x - 1, y - 1, 2, 2), Color(1.0, 1.0, 1.0, a))
"rail":
# Lange helle Nadel mit blauem Schweif
var angle := atan2(vy, vx)
var len := 32.0
var ca := cos(angle); var sa := sin(angle)
var bx := x - ca * len; var by := y - sa * len
canvas.draw_line(Vector2(bx, by), Vector2(x, y), Color(0.4, 0.7, 1.0, a * 0.35), 4.0)
canvas.draw_line(Vector2(bx, by), Vector2(x, y), Color(0.9, 0.98, 1.0, a), 1.0)
canvas.draw_rect(Rect2(x - 1, y - 1, 2, 2), Color(1.0, 1.0, 1.0, a))
"sniper":
# Mittellange scharfe Nadel, strahlend weiß
var angle := atan2(vy, vx)
var len := 18.0
var ca := cos(angle); var sa := sin(angle)
var bx := x - ca * len; var by := y - sa * len
canvas.draw_line(Vector2(bx, by), Vector2(x, y), Color(1.0, 0.95, 0.8, a * 0.5), 2.0)
canvas.draw_line(Vector2(bx, by), Vector2(x, y), Color(1.0, 1.0, 1.0, a), 1.0)
"ion":
# Leuchtender türkiser Orb
canvas.draw_circle(Vector2(x, y), 6.0, Color(0.2, 0.9, 0.85, a * 0.3))
canvas.draw_circle(Vector2(x, y), 3.5, Color(0.4, 1.0, 0.95, a * 0.75))
canvas.draw_rect(Rect2(x - 1, y - 1, 3, 3), Color(0.9, 1.0, 1.0, a))
"scatter":
# Kleine schnelle Schrotkügelchen, orange
canvas.draw_rect(Rect2(x - 1, y - 1, 3, 3), Color(1.0, 0.65, 0.2, a * 0.5))
canvas.draw_rect(Rect2(x, y, 2, 2), Color(1.0, 0.85, 0.5, a))
"burst":
# Winzige schnelle Punkte, hellblau
canvas.draw_rect(Rect2(x - 1, y - 1, 3, 3), Color(0.5, 0.85, 1.0, a * 0.5))
canvas.draw_rect(Rect2(x, y, 1, 1), Color(1.0, 1.0, 1.0, a))
"charge":
# Großer pulsierender Orb — Radius skaliert mit effective_hit_radius
var r: float = clamp(effective_hit_radius * 0.55, 4.0, 20.0)
canvas.draw_circle(Vector2(x, y), r + 4.0, Color(1.0, 0.85, 0.2, a * 0.2))
canvas.draw_circle(Vector2(x, y), r + 1.5, Color(1.0, 0.95, 0.4, a * 0.45))
canvas.draw_circle(Vector2(x, y), r, Color(1.0, 1.0, 0.75, a * 0.85))
canvas.draw_circle(Vector2(x, y), r * 0.45, Color(1.0, 1.0, 1.0, a))
_: # "default" — klassischer Dot
canvas.draw_rect(Rect2(x - 2, y - 2, 5, 5), Color(color.r, color.g, color.b, a * 0.5))
canvas.draw_rect(Rect2(x - 1, y - 1, 3, 3), Color(color.r, color.g, color.b, a))
canvas.draw_rect(Rect2(x, y, 1, 1), Color(1, 1, 1, a * 0.9))