262 lines
12 KiB
GDScript
262 lines
12 KiB
GDScript
extends "res://scene_base.gd"
|
|
## Szene Schrein: schwebende Steinplattformen im Nebel, Leuchtkanten, Kristall in der Mitte.
|
|
## Licht kommt aus den Dingen selbst (Glühen), dazu kaltes Streiflicht von oben rechts.
|
|
|
|
const VOID := Color("0c0a16")
|
|
const NEBULA := Color("3a2a6a")
|
|
const SLAB := Color("2a2438")
|
|
const SLAB_DARK := Color("161222")
|
|
const TEAL := Color("4ad8d0")
|
|
const INK := Color("eef0ff")
|
|
const MUTED := Color("9a98c0")
|
|
const PLAT_OPP := Rect2(300, 150, 700, 190)
|
|
const PLAT_OWN := Rect2(280, 430, 700, 190)
|
|
const PLAT_HAND := Rect2(360, 650, 560, 140)
|
|
|
|
|
|
func build_env() -> void:
|
|
light_dir = Vector2(0, 12)
|
|
layer(linear_tex(darker(NEBULA, 0.5), VOID), Rect2(Vector2.ZERO, size))
|
|
layer(noise_tex(320, 200, "simplex", 0.02, 21), Rect2(Vector2.ZERO, size), Color(NEBULA, 0.6))
|
|
layer(noise_tex(640, 400, "simplex", 0.12, 22), Rect2(Vector2.ZERO, size), Color("204050"), true)
|
|
layer(noise_tex(640, 400, "simplex", 0.12, 22), Rect2(Vector2.ZERO, size), Color(0, 0, 0, 0.45))
|
|
# Sterne
|
|
var img := Image.create(640, 400, false, Image.FORMAT_RGBA8)
|
|
img.fill(Color(0, 0, 0, 0))
|
|
var rng := RandomNumberGenerator.new()
|
|
rng.seed = 9
|
|
for i in 220:
|
|
var p := Vector2i(rng.randi_range(0, 639), rng.randi_range(0, 399))
|
|
img.set_pixelv(p, Color(1, 1, 1, rng.randf_range(0.2, 0.9)))
|
|
layer(ImageTexture.create_from_image(img), Rect2(Vector2.ZERO, size), Color(0.8, 0.85, 1.0, 0.5))
|
|
# Glühen unter den Plattformen und um den Kristall
|
|
for r in [PLAT_OPP, PLAT_OWN, PLAT_HAND]:
|
|
light(Vector2(r.get_center().x, r.end.y + 10), r.size.x * 0.55, TEAL, 0.18)
|
|
light(Vector2(640, 392), 180, Color("a0e0ff"), 0.45)
|
|
light(Vector2(1100, 60), 500, Color("8090ff"), 0.18)
|
|
vignette_layer(0.6)
|
|
|
|
|
|
func _draw() -> void:
|
|
_platforms()
|
|
_opponent()
|
|
_boards()
|
|
_player()
|
|
_preview()
|
|
txt("Dinger · Szene: Schrein", 12, MUTED, Vector2(20, 782), "midleft")
|
|
|
|
|
|
# --- Plattformen ------------------------------------------------------------------------------
|
|
|
|
func platform(rect: Rect2, edge: Color) -> void:
|
|
# Unterseite als dickere Platte mit Bruchkante
|
|
var under := Rect2(rect.position + Vector2(6, rect.size.y - 10), Vector2(rect.size.x - 12, 26))
|
|
draw_colored_polygon(PackedVector2Array([under.position, Vector2(under.end.x, under.position.y), Vector2(under.end.x - 14, under.end.y), Vector2(under.position.x + 20, under.end.y - 6)]), SLAB_DARK)
|
|
shadow(rect, 8, 18, 0.7, Vector2(0, 16))
|
|
grad(rect, 8, lighter(SLAB, 0.06), darker(SLAB, 0.7))
|
|
border(rect, 8, Color(0, 0, 0, 0.6), 2)
|
|
# Leuchtkante oben
|
|
draw_line(rect.position + Vector2(10, 2), Vector2(rect.end.x - 10, rect.position.y + 2), Color(edge, 0.9), 2, true)
|
|
draw_line(rect.position + Vector2(10, 4), Vector2(rect.end.x - 10, rect.position.y + 4), Color(edge, 0.25), 4, true)
|
|
# Runenlinie
|
|
for i in range(int(rect.size.x / 46)):
|
|
var x := rect.position.x + 24 + i * 46
|
|
draw_line(Vector2(x, rect.end.y - 7), Vector2(x + 18, rect.end.y - 7), Color(edge, 0.35), 1.5, true)
|
|
|
|
|
|
func _platforms() -> void:
|
|
platform(PLAT_OPP, Color("d06060"))
|
|
platform(PLAT_OWN, TEAL)
|
|
platform(PLAT_HAND, TEAL)
|
|
# Leylinie und Kristall
|
|
var c := Vector2(640, 392)
|
|
draw_line(Vector2(640, 340), Vector2(640, 430), Color(TEAL, 0.35), 4, true)
|
|
draw_line(Vector2(640, 340), Vector2(640, 430), Color("c0ffff"), 1.5, true)
|
|
var pts := PackedVector2Array([c + Vector2(0, -44), c + Vector2(22, -12), c + Vector2(16, 30), c + Vector2(0, 46), c + Vector2(-16, 30), c + Vector2(-22, -12)])
|
|
draw_colored_polygon(pts, Color("a8e8ff"))
|
|
draw_colored_polygon(PackedVector2Array([c + Vector2(0, -44), c + Vector2(22, -12), c + Vector2(0, 0)]), Color(1, 1, 1, 0.5))
|
|
draw_colored_polygon(PackedVector2Array([c + Vector2(0, 0), c + Vector2(16, 30), c + Vector2(0, 46), c + Vector2(-16, 30)]), Color("4090c0"))
|
|
var closed := pts.duplicate()
|
|
closed.append(pts[0])
|
|
draw_polyline(closed, Color("e0ffff"), 1.5, true)
|
|
var i := 0
|
|
for e in ["Feuer", "Luft", "Wasser", "Erde"]:
|
|
var a := -PI / 2 + i * PI / 2
|
|
var p := c + Vector2(cos(a), sin(a)) * 74
|
|
circle(p, 12, Color(ELEM[e], 0.35))
|
|
circle(p, 7, lighter(ELEM[e], 0.3))
|
|
circle(p + Vector2(-2, -2), 2.5, Color(1, 1, 1, 0.7))
|
|
i += 1
|
|
|
|
|
|
func slot(rect: Rect2) -> void:
|
|
rr(rect, 6, Color(0, 0, 0, 0.35))
|
|
border(rect, 6, Color(TEAL, 0.25), 1)
|
|
for k in 4:
|
|
var p := rect.position + Vector2(10 + (k % 2) * (rect.size.x - 20), 10 + (k / 2) * (rect.size.y - 20))
|
|
circle(p, 2, Color(TEAL, 0.5))
|
|
|
|
|
|
# --- Karten aus Obsidian mit Leuchtrand --------------------------------------------------------------
|
|
|
|
func card(rect: Rect2, name: String, elem: String, cost: int, atk: int, hp: int, big := false, rare_col = null) -> void:
|
|
var base: Color = ELEM[elem]
|
|
var edge: Color = rare_col if rare_col != null else lighter(base, 0.25)
|
|
var rad := 10 if big else 8
|
|
glow(rect, rad, edge, 12 if big else 8, 0.6)
|
|
shadow(rect, rad, 14, 0.6, Vector2(0, 10))
|
|
grad(rect, rad, lighter(SLAB, 0.04), darker(SLAB, 0.55))
|
|
border(rect, rad, Color(edge, 0.9), 2)
|
|
border(rect.grow(-2), rad - 2, Color(0, 0, 0, 0.5), 1)
|
|
var inner := rect.grow(-6)
|
|
var pic := Rect2(inner.position, Vector2(inner.size.x, inner.size.y * (0.42 if big else 0.52)))
|
|
rr(pic, rad - 4, darker(base, 0.25))
|
|
inset(pic, rad - 4, 0.8)
|
|
var gc := pic.get_center()
|
|
var gs := pic.size.x * (0.55 if big else 0.6)
|
|
for k in 3:
|
|
circle(gc, gs * (0.55 - k * 0.12), Color(lighter(base, 0.5), 0.12))
|
|
glyph(elem, gc, gs, lighter(base, 0.55))
|
|
glyph(elem, gc, gs * 0.6, Color(1, 1, 1, 0.35))
|
|
var fs := 14 if big else 11
|
|
var band := Rect2(inner.position.x, pic.end.y + 4, inner.size.x, fs + 10)
|
|
rr(band, 3, Color(0, 0, 0, 0.45))
|
|
draw_line(band.position + Vector2(6, band.size.y - 1), Vector2(band.end.x - 6, band.end.y - 1), Color(edge, 0.8), 1.5, true)
|
|
txt(fit(name, fs, band.size.x - 12), fs, INK, band.get_center(), "center", true)
|
|
if big:
|
|
var y := band.end.y + 14
|
|
keyword_icon(Vector2(inner.position.x + 24, y), 9, KW[elem], lighter(base, 0.45), Color(0, 0, 0, 0.6))
|
|
txt(KW[elem], 12, INK, Vector2(inner.position.x + 40, y), "midleft")
|
|
var box := Rect2(inner.position.x + 4, y + 14, inner.size.x - 8, rect.end.y - 52 - (y + 14))
|
|
rr(box, 4, Color(0, 0, 0, 0.45))
|
|
txt("Greift zweimal je Zug", 11, INK, box.get_center())
|
|
var r := 15.0 if big else 11.0
|
|
var fsz := 17 if big else 13
|
|
var m := r + 8
|
|
badge(rect.position + Vector2(m, rect.size.y - m), r, str(atk), Color("e0a020"), fsz, Color("6a6a80"))
|
|
badge(rect.position + Vector2(rect.size.x - m, rect.size.y - m), r, str(hp), Color("3a78d8"), fsz, Color("6a6a80"))
|
|
crystal(rect.position + Vector2(m, m), r + 1, str(cost), fsz, Color("3a6ad0"), Color("9ad8ff"))
|
|
|
|
|
|
func card_back(rect: Rect2) -> void:
|
|
glow(rect, 8, Color("8060d0"), 8, 0.5)
|
|
shadow(rect, 8, 10, 0.6, Vector2(0, 8))
|
|
grad(rect, 8, lighter(SLAB, 0.04), darker(SLAB, 0.55))
|
|
border(rect, 8, Color("a080ff"), 2)
|
|
var c := rect.get_center()
|
|
for k in 3:
|
|
circle(c, 30 - k * 8, Color("8060d0", 0.18))
|
|
var pts := PackedVector2Array([c + Vector2(0, -22), c + Vector2(11, -6), c + Vector2(8, 15), c + Vector2(0, 23), c + Vector2(-8, 15), c + Vector2(-11, -6)])
|
|
draw_colored_polygon(pts, Color("c0a8ff"))
|
|
draw_colored_polygon(PackedVector2Array([c + Vector2(0, -22), c + Vector2(11, -6), c]), Color(1, 1, 1, 0.4))
|
|
var closed := pts.duplicate()
|
|
closed.append(pts[0])
|
|
draw_polyline(closed, Color("e8e0ff"), 1.2, true)
|
|
|
|
|
|
func obelisk(rect: Rect2, count: String, label := "") -> void:
|
|
for i in range(5, 0, -1):
|
|
var r := Rect2(rect.position + Vector2(0, -i * 2.2), rect.size)
|
|
rr(r, 8, Color("1c1828"))
|
|
border(r, 8, Color("5040a0", 0.5), 1)
|
|
card_back(Rect2(rect.position + Vector2(0, -12), rect.size))
|
|
if label != "":
|
|
rr(Rect2(rect.position.x + 12, rect.end.y - 76, rect.size.x - 24, 44), 4, Color(0, 0, 0, 0.55))
|
|
txt_shadow(label, 15, INK, Vector2(rect.get_center().x, rect.end.y - 64), "center", true)
|
|
txt("◆ 0", 14, Color("8ab8ff"), Vector2(rect.get_center().x, rect.end.y - 44))
|
|
pill(Rect2(rect.position.x + 30, rect.end.y - 4, rect.size.x - 60, 22), count, Color("a080ff"))
|
|
|
|
|
|
func pill(rect: Rect2, label: String, edge: Color, fs := 13) -> void:
|
|
rr(rect, int(rect.size.y / 2), Color(0, 0, 0, 0.55))
|
|
border(rect, int(rect.size.y / 2), Color(edge, 0.7), 1)
|
|
txt(label, fs, INK, rect.get_center(), "center", true)
|
|
|
|
|
|
func orb(c: Vector2, name: String, life: String, elem: String, mana_full: int, active := false) -> void:
|
|
var col: Color = ELEM[elem]
|
|
for k in 4:
|
|
circle(c, 56 + k * 8, Color(col, 0.07))
|
|
circle(c, 44, darker(SLAB, 0.8))
|
|
circle(c, 42, Color(col, 0.45))
|
|
for k in 3:
|
|
circle(c, 40 - k * 10, Color(lighter(col, 0.3), 0.12))
|
|
glyph(elem, c + Vector2(0, 2), 46, lighter(col, 0.5), Color(0, 0, 0, 0.4))
|
|
circle(c + Vector2(-14, -16), 10, Color(1, 1, 1, 0.22))
|
|
ring(c, 44, lighter(col, 0.35) if active else Color(col, 0.6), 3)
|
|
if active:
|
|
ring(c, 50, Color(TEAL, 0.7), 1.5)
|
|
pill(Rect2(c.x - 60, c.y + 52, 120, 24), name, lighter(col, 0.3), 14)
|
|
badge(c + Vector2(-40, 34), 16, life, Color("c83030"), 15, Color("6a6a80"))
|
|
for i in 3:
|
|
var p := Vector2(c.x - 20 + i * 20, c.y + 92)
|
|
circle(p, 6, Color("3a6ad0") if i < mana_full else Color("1a1a30"))
|
|
ring(p, 6, Color("9ad8ff", 0.8 if i < mana_full else 0.3), 1.5)
|
|
|
|
|
|
func rune_pill(rect: Rect2, elem: String, filled: int, played: String) -> void:
|
|
var col: Color = ELEM[elem]
|
|
pill(rect, "", lighter(col, 0.2))
|
|
circle(Vector2(rect.position.x + 18, rect.get_center().y), 11, Color(col, 0.35))
|
|
glyph(elem, Vector2(rect.position.x + 18, rect.get_center().y), 16, lighter(col, 0.45))
|
|
txt(elem, 13, INK, Vector2(rect.position.x + 36, rect.get_center().y), "midleft", true)
|
|
for k in 2:
|
|
keyword_icon(Vector2(rect.position.x + 114 + k * 24, rect.get_center().y), 8, KW[elem], lighter(col, 0.4) if k < filled else Color(col, 0.3), Color(0, 0, 0, 0.6))
|
|
txt(played, 15, lighter(col, 0.4), Vector2(rect.end.x - 14, rect.get_center().y), "midright", true)
|
|
|
|
|
|
func button(rect: Rect2, label: String) -> void:
|
|
glow(rect, 6, TEAL, 5, 0.3)
|
|
grad(rect, 6, lighter(SLAB, 0.1), darker(SLAB, 0.6), 8)
|
|
border(rect, 6, Color(TEAL, 0.7), 1)
|
|
txt_shadow(label, 13, INK, rect.get_center(), "center", true)
|
|
|
|
|
|
# --- Anordnung ---------------------------------------------------------------------------------------
|
|
|
|
func _opponent() -> void:
|
|
orb(Vector2(130, 110), "Gegner", "35", "Feuer", 0)
|
|
rune_pill(Rect2(30, 232, 210, 32), "Feuer", 1, "1")
|
|
button(Rect2(30, 276, 210, 30), "Überspringen")
|
|
for i in 4:
|
|
var t := i - 1.5
|
|
var r := Rect2(430 + i * 112, 10, 100, 128)
|
|
draw_set_transform(r.get_center() + Vector2(0, t * t * 2), deg_to_rad(-t * 2))
|
|
card_back(Rect2(-r.size / 2, r.size))
|
|
draw_set_transform(Vector2.ZERO)
|
|
obelisk(Rect2(1090, 40, 110, 150), "35")
|
|
|
|
|
|
func _boards() -> void:
|
|
for j in 5:
|
|
var r := Rect2(352 + j * 122, 172, 110, 140)
|
|
if j == 0:
|
|
card(r, "Schwelender Drache", "Feuer", 1, 0, 5)
|
|
else:
|
|
slot(r)
|
|
for j in 5:
|
|
var r := Rect2(332 + j * 122, 452, 110, 140)
|
|
if j == 0:
|
|
card(r, "Rieselnder Geist", "Wasser", 1, 1, 2)
|
|
else:
|
|
slot(r)
|
|
|
|
|
|
func _player() -> void:
|
|
orb(Vector2(130, 600), "Spieler", "30", "Wasser", 1, true)
|
|
rune_pill(Rect2(30, 476, 210, 32), "Wasser", 1, "1")
|
|
var hand := [["Leiser Hauch", "Luft", 0, 0, 1, null], ["Glimmender Wolf", "Feuer", 1, 1, 3, Color("d0d8e4")],
|
|
["Stiller Tropfen", "Wasser", 0, 0, 1, null], ["Fester Kiesel", "Erde", 1, 1, 1, Color("f0b030")], ["Rieselnder Geist", "Wasser", 1, 1, 2, null]]
|
|
for i in hand.size():
|
|
var h = hand[i]
|
|
var t := i - 2.0
|
|
var c := Vector2(640 + t * 104, 700 + t * t * 2)
|
|
draw_set_transform(c, deg_to_rad(t * 4))
|
|
card(Rect2(-55, -70, 110, 140), h[0], h[1], h[2], h[3], h[4], false, h[5])
|
|
draw_set_transform(Vector2.ZERO)
|
|
obelisk(Rect2(1090, 616, 110, 150), "35", "Ziehen")
|
|
|
|
|
|
func _preview() -> void:
|
|
card(Rect2(1062, 250, 176, 246), "Glimmender Wolf", "Feuer", 1, 1, 3, true, Color("d0d8e4"))
|