265 lines
12 KiB
GDScript
265 lines
12 KiB
GDScript
extends "res://scene_base.gd"
|
|
## Szene Arena: Steinboden bei Nacht, runde Kampfarena, Mondlicht von oben, Fackeln an den Seiten.
|
|
|
|
const STONE := Color("4a5260")
|
|
const STONE_DARK := Color("262c36")
|
|
const IRON := Color("8a94a4")
|
|
const INK := Color("e8ecf4")
|
|
const MUTED := Color("98a2b4")
|
|
const BANNER_OPP := Color("7a2630")
|
|
const BANNER_OWN := Color("24467a")
|
|
const C := Vector2(640, 400)
|
|
|
|
|
|
func build_env() -> void:
|
|
light_dir = Vector2(0, 8)
|
|
layer(linear_tex(STONE_DARK, darker(STONE_DARK, 0.6)), Rect2(Vector2.ZERO, size))
|
|
layer(noise_tex(320, 200, "cellfill", 0.06, 11), Rect2(Vector2.ZERO, size), Color(STONE, 0.35)) # Platten
|
|
layer(noise_tex(640, 400, "cell", 0.05, 11), Rect2(Vector2.ZERO, size), Color(0, 0, 0, 0.5)) # Fugen
|
|
layer(noise_tex(256, 256, "simplex", 0.08, 4), Rect2(Vector2.ZERO, size), Color(1, 1, 1, 0.06))
|
|
light(Vector2(640, 120), 820, Color("b8d0ff"), 0.30) # Mond
|
|
light(Vector2(30, 420), 300, Color("ff9a40"), 0.45) # Fackeln
|
|
light(Vector2(1250, 420), 300, Color("ff9a40"), 0.45)
|
|
for e in ["Feuer", "Wasser", "Erde", "Luft"]: # Runenlicht
|
|
light(rune_pos(e), 90, ELEM[e], 0.6)
|
|
vignette_layer(0.75)
|
|
|
|
|
|
func rune_pos(e: String) -> Vector2:
|
|
match e:
|
|
"Feuer": return C + Vector2(-258, 0)
|
|
"Erde": return C + Vector2(-190, 0)
|
|
"Wasser": return C + Vector2(258, 0)
|
|
return C + Vector2(190, 0)
|
|
|
|
|
|
func _draw() -> void:
|
|
_arena()
|
|
_opponent()
|
|
_boards()
|
|
_player()
|
|
_preview()
|
|
txt("Dinger · Szene: Arena", 12, MUTED, Vector2(20, 782), "midleft")
|
|
|
|
|
|
# --- Arena -------------------------------------------------------------------------------
|
|
|
|
func _arena() -> void:
|
|
circle(C, 340, Color(0, 0, 0, 0.35))
|
|
circle(C, 330, Color(STONE, 0.55))
|
|
ring(C, 330, darker(STONE, 0.5), 10)
|
|
ring(C, 335, Color(1, 1, 1, 0.08), 1)
|
|
ring(C, 325, Color(0, 0, 0, 0.35), 2)
|
|
ring(C, 300, Color(0, 0, 0, 0.25), 3)
|
|
ring(C, 301, Color(1, 1, 1, 0.05), 1)
|
|
# Mittellinie und Kernstein
|
|
draw_line(C + Vector2(-300, 0), C + Vector2(-70, 0), Color(0, 0, 0, 0.45), 3, true)
|
|
draw_line(C + Vector2(70, 0), C + Vector2(300, 0), Color(0, 0, 0, 0.45), 3, true)
|
|
draw_line(C + Vector2(-300, 1), C + Vector2(-70, 1), Color(1, 1, 1, 0.08), 1, true)
|
|
draw_line(C + Vector2(70, 1), C + Vector2(300, 1), Color(1, 1, 1, 0.08), 1, true)
|
|
circle(C, 62, Color(0, 0, 0, 0.35))
|
|
circle(C, 54, darker(STONE, 0.8))
|
|
ring(C, 54, darker(STONE, 0.45), 4)
|
|
ring(C, 44, Color(IRON, 0.5), 2)
|
|
var pts := PackedVector2Array()
|
|
for i in 6:
|
|
var a := -PI / 2 + i * PI / 3
|
|
pts.append(C + Vector2(cos(a), sin(a)) * 30)
|
|
draw_colored_polygon(pts, Color("1a2030"))
|
|
for i in 6:
|
|
draw_line(C, pts[i], Color(IRON, 0.5), 1, true)
|
|
for e in ["Feuer", "Wasser", "Erde", "Luft"]:
|
|
var p := rune_pos(e)
|
|
circle(p, 22, Color("12161e"))
|
|
ring(p, 22, darker(STONE, 0.6), 3)
|
|
glyph(e, p, 24, lighter(ELEM[e], 0.35))
|
|
# Steinsims für die Hand
|
|
var ledge := Rect2(300, 652, 680, 148)
|
|
rr(ledge, 6, Color("1c2129"))
|
|
border(ledge, 6, Color(0, 0, 0, 0.6), 3)
|
|
draw_line(ledge.position + Vector2(4, 2), Vector2(ledge.end.x - 4, ledge.position.y + 2), Color(1, 1, 1, 0.12), 2, true)
|
|
|
|
|
|
func slot(rect: Rect2) -> void:
|
|
rr(rect, 4, Color(0, 0, 0, 0.3))
|
|
inset(rect, 4, 0.8)
|
|
border(rect, 4, Color(1, 1, 1, 0.07), 1)
|
|
border(rect.grow(-5), 3, Color(0, 0, 0, 0.25), 1)
|
|
|
|
|
|
# --- Karten als Steintafeln ------------------------------------------------------------------
|
|
|
|
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 rad := 6 if big else 5
|
|
if rare_col != null:
|
|
glow(rect, rad, rare_col, 9, 0.7)
|
|
shadow(rect, rad, 12 if big else 8, 0.6)
|
|
grad(rect, rad, lighter(STONE, 0.12), darker(STONE, 0.6))
|
|
border(rect, rad, Color(0, 0, 0, 0.7), 2)
|
|
draw_line(rect.position + Vector2(4, 2.5), Vector2(rect.end.x - 4, rect.position.y + 2.5), Color(1, 1, 1, 0.2), 1.5, true) # Lichtkante
|
|
var inner := rect.grow(-6)
|
|
# Fenster in Elementfarbe (Glas)
|
|
var pic := Rect2(inner.position, Vector2(inner.size.x, inner.size.y * (0.42 if big else 0.52)))
|
|
rr(pic, 4, darker(base, 0.5))
|
|
grad(pic.grow(-2), 3, lighter(base, 0.1), darker(base, 0.45))
|
|
inset(pic, 4, 1.0)
|
|
var gc := pic.get_center()
|
|
var gs := pic.size.x * (0.55 if big else 0.6)
|
|
circle(gc, gs * 0.45, Color(lighter(base, 0.5), 0.3))
|
|
glyph(elem, gc + Vector2(0, 3), gs, Color(0, 0, 0, 0.4))
|
|
glyph(elem, gc, gs, lighter(base, 0.5))
|
|
# Gemeißeltes Namensfeld
|
|
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("161a22"))
|
|
inset(band, 3, 0.9)
|
|
txt(fit(name, fs, band.size.x - 12), fs, INK if rare_col == null else lighter(rare_col, 0.3), 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("161a22"))
|
|
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, 3, Color("161a22"))
|
|
inset(box, 3, 0.7)
|
|
txt("Greift zweimal je Zug", 11, INK, box.get_center())
|
|
if rare_col != null:
|
|
border(rect.grow(-3), rad - 1, Color(rare_col, 0.8), 1)
|
|
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("d89a20"), fsz, IRON)
|
|
badge(rect.position + Vector2(rect.size.x - m, rect.size.y - m), r, str(hp), Color("3a78d8"), fsz, IRON)
|
|
crystal(rect.position + Vector2(m, m), r + 1, str(cost), fsz, Color("3a6ad0"), IRON)
|
|
|
|
|
|
func card_back(rect: Rect2) -> void:
|
|
shadow(rect, 5, 8, 0.6)
|
|
grad(rect, 5, lighter(STONE, 0.08), darker(STONE, 0.55))
|
|
border(rect, 5, Color(0, 0, 0, 0.7), 2)
|
|
var inner := rect.grow(-8)
|
|
rr(inner, 3, Color("1a2030"))
|
|
inset(inner, 3, 0.9)
|
|
var c := rect.get_center()
|
|
ring(c, 22, Color(IRON, 0.8), 2)
|
|
var pts := PackedVector2Array()
|
|
for i in 6:
|
|
var a := -PI / 2 + i * PI / 3
|
|
pts.append(c + Vector2(cos(a), sin(a)) * 14)
|
|
draw_colored_polygon(pts, Color(IRON, 0.5))
|
|
ring(c, 6, Color("1a2030"), 2)
|
|
|
|
|
|
func pedestal(rect: Rect2, count: String, label := "") -> void:
|
|
var base := Rect2(rect.position.x - 12, rect.end.y - 10, rect.size.x + 24, 26)
|
|
shadow(base, 3, 8, 0.6)
|
|
grad(base, 3, lighter(STONE, 0.05), darker(STONE, 0.5), 6)
|
|
border(base, 3, Color(0, 0, 0, 0.7), 2)
|
|
for i in range(5, 0, -1):
|
|
var r := Rect2(rect.position + Vector2(0, -i * 2.2), rect.size)
|
|
rr(r, 5, Color("2a3140"))
|
|
border(r, 5, Color(0, 0, 0, 0.5), 1)
|
|
card_back(Rect2(rect.position + Vector2(0, -12), rect.size))
|
|
if label != "":
|
|
rr(Rect2(rect.position.x + 12, rect.end.y - 64, rect.size.x - 24, 44), 4, Color("12161e"))
|
|
txt_shadow(label, 15, INK, Vector2(rect.get_center().x, rect.end.y - 52), "center", true)
|
|
txt("◆ 0", 14, Color("8ab8ff"), Vector2(rect.get_center().x, rect.end.y - 32))
|
|
txt_shadow(count, 13, INK, Vector2(rect.get_center().x, base.get_center().y + 1), "center", true)
|
|
|
|
|
|
# --- Banner, Runensteine ------------------------------------------------------------------------
|
|
|
|
func banner(pos: Vector2, col: Color, name: String, life: String, elem: String, mana_full: int, active := false) -> void:
|
|
var w := 150.0
|
|
var h := 170.0
|
|
var pts := PackedVector2Array([pos, pos + Vector2(w, 0), pos + Vector2(w, h - 28), pos + Vector2(w / 2, h), pos + Vector2(0, h - 28)])
|
|
var sh := PackedVector2Array()
|
|
for p in pts:
|
|
sh.append(p + Vector2(0, 8))
|
|
draw_colored_polygon(sh, Color(0, 0, 0, 0.45))
|
|
draw_colored_polygon(pts, darker(col, 0.8))
|
|
var in_pts := PackedVector2Array([pos + Vector2(8, 8), pos + Vector2(w - 8, 8), pos + Vector2(w - 8, h - 32), pos + Vector2(w / 2, h - 12), pos + Vector2(8, h - 32)])
|
|
draw_colored_polygon(in_pts, col)
|
|
var closed := pts.duplicate()
|
|
closed.append(pts[0])
|
|
draw_polyline(closed, Color(0, 0, 0, 0.6), 2, true)
|
|
# Stange
|
|
rr(Rect2(pos.x - 10, pos.y - 8, w + 20, 10), 3, darker(IRON, 0.6))
|
|
draw_line(Vector2(pos.x - 8, pos.y - 5), Vector2(pos.x + w + 8, pos.y - 5), lighter(IRON, 0.15), 2, true)
|
|
# Emblem
|
|
var c := pos + Vector2(w / 2, 58)
|
|
circle(c, 34, Color(0, 0, 0, 0.35))
|
|
circle(c, 30, darker(col, 0.5))
|
|
glyph(elem, c + Vector2(0, 1), 36, lighter(ELEM[elem], 0.4), Color(0, 0, 0, 0.5))
|
|
metal_ring(c, 30, 3, IRON if not active else lighter(IRON, 0.2))
|
|
txt_shadow(name, 15, INK, pos + Vector2(w / 2, 108), "center", true)
|
|
badge(pos + Vector2(w / 2 - 34, 134), 15, life, Color("c83030"), 15, IRON)
|
|
for i in 3:
|
|
var p := pos + Vector2(w / 2 + 6 + i * 20, 134)
|
|
circle(p, 7, Color("3a6ad0") if i < mana_full else Color("1a2030"))
|
|
ring(p, 7, darker(IRON, 0.7), 1.5)
|
|
|
|
|
|
func rune_stone(rect: Rect2, elem: String, filled: int, played: String) -> void:
|
|
var col: Color = ELEM[elem]
|
|
shadow(rect, 10, 6, 0.6)
|
|
grad(rect, 10, lighter(STONE, 0.05), darker(STONE, 0.5), 8)
|
|
border(rect, 10, Color(0, 0, 0, 0.7), 2)
|
|
draw_line(rect.position + Vector2(10, 2.5), Vector2(rect.end.x - 10, rect.position.y + 2.5), Color(1, 1, 1, 0.15), 1.5, true)
|
|
circle(Vector2(rect.position.x + 20, rect.get_center().y), 13, Color(col, 0.35))
|
|
glyph(elem, Vector2(rect.position.x + 20, rect.get_center().y), 18, lighter(col, 0.4))
|
|
txt(elem, 13, INK, Vector2(rect.position.x + 40, rect.get_center().y), "midleft", true)
|
|
for k in 2:
|
|
keyword_icon(Vector2(rect.position.x + 118 + k * 24, rect.get_center().y), 8, KW[elem], lighter(col, 0.4) if k < filled else Color(col, 0.3), Color("161a22"))
|
|
txt(played, 15, lighter(col, 0.4), Vector2(rect.end.x - 12, rect.get_center().y), "midright", true)
|
|
|
|
|
|
func button(rect: Rect2, label: String) -> void:
|
|
shadow(rect, 4, 5, 0.5)
|
|
grad(rect, 4, lighter(STONE, 0.1), darker(STONE, 0.55), 8)
|
|
border(rect, 4, Color(0, 0, 0, 0.7), 2)
|
|
draw_line(rect.position + Vector2(4, 2.5), Vector2(rect.end.x - 4, rect.position.y + 2.5), Color(1, 1, 1, 0.2), 1.5, true)
|
|
txt_shadow(label, 13, INK, rect.get_center(), "center", true)
|
|
|
|
|
|
# --- Anordnung ---------------------------------------------------------------------------------
|
|
|
|
func _opponent() -> void:
|
|
banner(Vector2(50, 20), BANNER_OPP, "Gegner", "35", "Feuer", 0)
|
|
rune_stone(Rect2(30, 220, 210, 36), "Feuer", 1, "1")
|
|
button(Rect2(30, 268, 210, 30), "Überspringen")
|
|
for i in 4:
|
|
var r := Rect2(426 + i * 114, 12, 100, 128)
|
|
card_back(r)
|
|
pedestal(Rect2(1090, 40, 110, 150), "35")
|
|
|
|
|
|
func _boards() -> void:
|
|
for j in 5:
|
|
var r := Rect2(342 + 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(342 + j * 122, 488, 110, 140)
|
|
if j == 0:
|
|
card(r, "Rieselnder Geist", "Wasser", 1, 1, 2)
|
|
else:
|
|
slot(r)
|
|
|
|
|
|
func _player() -> void:
|
|
banner(Vector2(50, 560), BANNER_OWN, "Spieler", "30", "Wasser", 1, true)
|
|
rune_stone(Rect2(30, 500, 210, 36), "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]
|
|
card(Rect2(350 + i * 118, 650, 110, 140), h[0], h[1], h[2], h[3], h[4], false, h[5])
|
|
pedestal(Rect2(1090, 610, 110, 150), "35", "Ziehen")
|
|
|
|
|
|
func _preview() -> void:
|
|
card(Rect2(1062, 260, 176, 246), "Glimmender Wolf", "Feuer", 1, 1, 3, true, Color("d0d8e4"))
|