430 lines
20 KiB
GDScript
430 lines
20 KiB
GDScript
extends Control
|
||
## Mockup des Kampfbildschirms (1280×800) von Dinger. Die Optik kommt aus dem Dictionary P;
|
||
## Richtungen überschreiben P in _init(). Layout wie BattleLayout im Spiel.
|
||
|
||
const FONT_DIR := "/home/arbeit/projects/cards/assets/fonts/"
|
||
const ELEM := {"Feuer": Color("be3c23"), "Wasser": Color("2d64be"), "Erde": Color("73552d"), "Luft": Color("78aac8")}
|
||
|
||
var font: FontFile
|
||
var bold: FontFile
|
||
var P := {
|
||
"bg_top": Color("1a1c24"), "bg_bottom": Color("12131a"), "vignette": 0.35,
|
||
"panel_bg": Color("282b36"), "panel_bg2": Color("282b36"), "panel_border": Color("3a3e4c"), "panel_border_w": 1,
|
||
"panel_radius": 8, "panel_shadow": 6, "panel_highlight": Color(1, 1, 1, 0.0), "chamfer": 0,
|
||
"slot_bg": Color(1, 1, 1, 0.03), "slot_border": Color(1, 1, 1, 0.08),
|
||
"card_radius": 8, "card_border": Color("14141c"), "card_border_w": 2, "card_inner": Color(1, 1, 1, 0.0),
|
||
"card_grad": 0.0, "card_vignette": 0.0, "glyph_shadow": true, "glyph_outline": false,
|
||
"band_bg": Color(0.05, 0.05, 0.08, 0.82), "band_text": Color("ececf0"), "band_inset": 0,
|
||
"back_bg": Color("3c285a"), "back_bg2": Color("3c285a"), "back_border": Color("f5c850"), "back_inner": Color("5a3c82"),
|
||
"stat": "circle", "stat_outline": Color("14141c"), "stat_w": 2,
|
||
"btn_bg": Color("3a3e4c"), "btn_bg2": Color("3a3e4c"), "btn_border": Color("9698a5"), "btn_w": 2, "btn_radius": 8, "btn_edge": Color(0, 0, 0, 0),
|
||
"text": Color("ececf0"), "muted": Color("9698a5"), "gold": Color("f5c850"), "life": Color("e65555"), "mana": Color("6eaaf0"),
|
||
"amber": Color("f0b429"), "blue": Color("4a86d8"), "crystal": Color("3a78d2"),
|
||
"rare": Color("c8d0dc"), "ultra": Color("f0aa28"), "elem_light": 0.38,
|
||
}
|
||
|
||
|
||
func _init() -> void:
|
||
font = FontFile.new()
|
||
font.load_dynamic_font(FONT_DIR + "DejaVuSans.ttf")
|
||
bold = FontFile.new()
|
||
bold.load_dynamic_font(FONT_DIR + "DejaVuSans-Bold.ttf")
|
||
|
||
|
||
# --- Grundformen ---------------------------------------------------------------
|
||
|
||
static func lighter(c: Color, d: float) -> Color:
|
||
return Color(minf(1, c.r + d), minf(1, c.g + d), minf(1, c.b + d), c.a)
|
||
|
||
static func darker(c: Color, f: float) -> Color:
|
||
return Color(c.r * f, c.g * f, c.b * f, c.a)
|
||
|
||
|
||
## Eckpunkte eines abgerundeten (oder abgeschrägten) Rechtecks.
|
||
func shape(rect: Rect2, radius: float) -> PackedVector2Array:
|
||
var pts := PackedVector2Array()
|
||
var cut: float = P.chamfer
|
||
if cut > 0:
|
||
var p := rect.position
|
||
var e := rect.end
|
||
pts.append_array([Vector2(p.x + cut, p.y), Vector2(e.x - cut, p.y), Vector2(e.x, p.y + cut), Vector2(e.x, e.y - cut),
|
||
Vector2(e.x - cut, e.y), Vector2(p.x + cut, e.y), Vector2(p.x, e.y - cut), Vector2(p.x, p.y + cut)])
|
||
return pts
|
||
radius = minf(radius, minf(rect.size.x, rect.size.y) / 2)
|
||
var centers := [rect.position + Vector2(radius, radius), Vector2(rect.end.x - radius, rect.position.y + radius),
|
||
rect.end - Vector2(radius, radius), Vector2(rect.position.x + radius, rect.end.y - radius)]
|
||
for i in 4:
|
||
for k in 13:
|
||
var a := -PI + PI / 2 * i + PI / 2 * k / 12
|
||
pts.append(centers[i] + Vector2(cos(a), sin(a)) * radius)
|
||
return pts
|
||
|
||
|
||
## Fläche: senkrechter Verlauf von top nach bottom.
|
||
func fill(rect: Rect2, radius: float, top: Color, bottom: Color) -> void:
|
||
var pts := shape(rect, radius)
|
||
var cols := PackedColorArray()
|
||
for p in pts:
|
||
cols.append(top.lerp(bottom, clampf((p.y - rect.position.y) / rect.size.y, 0, 1)))
|
||
draw_polygon(pts, cols)
|
||
|
||
|
||
func outline(rect: Rect2, radius: float, col: Color, w: float) -> void:
|
||
if P.chamfer > 0:
|
||
var pts := shape(rect.grow(-w / 2), radius - w / 2)
|
||
pts.append(pts[0])
|
||
draw_polyline(pts, col, w, true)
|
||
return
|
||
var sb := StyleBoxFlat.new()
|
||
sb.draw_center = false
|
||
sb.border_color = col
|
||
sb.set_border_width_all(int(round(w)))
|
||
sb.set_corner_radius_all(int(radius))
|
||
sb.anti_aliasing_size = 1.0
|
||
draw_style_box(sb, rect)
|
||
|
||
|
||
func shadow(rect: Rect2, radius: float, size: int, alpha := 0.45, offset := Vector2(0, 3)) -> void:
|
||
if size <= 0:
|
||
return
|
||
var sb := StyleBoxFlat.new()
|
||
sb.bg_color = Color(0, 0, 0, 0)
|
||
sb.set_corner_radius_all(int(radius))
|
||
sb.shadow_color = Color(0, 0, 0, alpha)
|
||
sb.shadow_size = size
|
||
sb.shadow_offset = offset
|
||
draw_style_box(sb, rect)
|
||
|
||
|
||
func glow(rect: Rect2, radius: float, col: Color, size: int) -> void:
|
||
var sb := StyleBoxFlat.new()
|
||
sb.bg_color = Color(0, 0, 0, 0)
|
||
sb.set_corner_radius_all(int(radius))
|
||
sb.shadow_color = Color(col, 0.55)
|
||
sb.shadow_size = size
|
||
draw_style_box(sb, rect)
|
||
|
||
|
||
## Dunkler Rand nach innen (Vignette) als Ringe.
|
||
func vignette(rect: Rect2, radius: float, strength: float) -> void:
|
||
if strength <= 0:
|
||
return
|
||
for i in 4:
|
||
var r := rect.grow(-i * 3.0)
|
||
outline(r, radius - i * 3, Color(0, 0, 0, strength * (0.3 - i * 0.06)), 3)
|
||
|
||
|
||
func txt(s: String, size: int, col: Color, pos: Vector2, anchor := "center", b := false) -> void:
|
||
var f := bold if b else font
|
||
var dim := f.get_string_size(s, HORIZONTAL_ALIGNMENT_LEFT, -1, size)
|
||
var p := pos
|
||
match anchor:
|
||
"center": p -= dim / 2
|
||
"midtop": p.x -= dim.x / 2
|
||
"midleft": p.y -= dim.y / 2
|
||
"midright": p -= Vector2(dim.x, dim.y / 2)
|
||
"topright": p.x -= dim.x
|
||
draw_string(f, Vector2(p.x, p.y + f.get_ascent(size)), s, HORIZONTAL_ALIGNMENT_LEFT, -1, size, col)
|
||
|
||
|
||
func txt_outlined(s: String, size: int, col: Color, pos: Vector2, ow := 4, ocol := Color(0.05, 0.05, 0.08, 0.95)) -> void:
|
||
var dim := bold.get_string_size(s, HORIZONTAL_ALIGNMENT_LEFT, -1, size)
|
||
var at := pos - dim / 2 + Vector2(0, bold.get_ascent(size))
|
||
draw_string_outline(bold, at, s, HORIZONTAL_ALIGNMENT_LEFT, -1, size, ow, ocol)
|
||
draw_string(bold, at, s, HORIZONTAL_ALIGNMENT_LEFT, -1, size, col)
|
||
|
||
|
||
func fit(s: String, size: int, max_w: float) -> String:
|
||
while bold.get_string_size(s, HORIZONTAL_ALIGNMENT_LEFT, -1, size).x > max_w and s.length() > 3:
|
||
s = s.substr(0, s.length() - 2) + "…"
|
||
return s
|
||
|
||
|
||
# --- Bausteine -----------------------------------------------------------------
|
||
|
||
func panel(rect: Rect2, border = null) -> void:
|
||
shadow(rect, P.panel_radius, P.panel_shadow)
|
||
fill(rect, P.panel_radius, P.panel_bg, P.panel_bg2)
|
||
if P.panel_highlight.a > 0:
|
||
draw_line(rect.position + Vector2(P.panel_radius, 1.5), Vector2(rect.end.x - P.panel_radius, rect.position.y + 1.5), P.panel_highlight, 1.0)
|
||
var bc: Color = border if border != null else P.panel_border
|
||
if P.panel_border_w > 0:
|
||
outline(rect, P.panel_radius, bc, P.panel_border_w)
|
||
|
||
|
||
func button(rect: Rect2, label: String, size := 14) -> void:
|
||
if P.btn_edge.a > 0:
|
||
fill(Rect2(rect.position + Vector2(0, 4), rect.size), P.btn_radius, P.btn_edge, P.btn_edge)
|
||
else:
|
||
shadow(rect, P.btn_radius, 4, 0.35)
|
||
fill(rect, P.btn_radius, P.btn_bg, P.btn_bg2)
|
||
if P.panel_highlight.a > 0:
|
||
draw_line(rect.position + Vector2(P.btn_radius, 1.5), Vector2(rect.end.x - P.btn_radius, rect.position.y + 1.5), P.panel_highlight, 1.0)
|
||
if P.btn_w > 0:
|
||
outline(rect, P.btn_radius, P.btn_border, P.btn_w)
|
||
txt(label, size, P.text, rect.get_center())
|
||
|
||
|
||
func slot(rect: Rect2) -> void:
|
||
fill(rect, P.card_radius, P.slot_bg, P.slot_bg)
|
||
outline(rect, P.card_radius, P.slot_border, 1)
|
||
|
||
|
||
## Zahl auf Form: Kreis, Sechseck oder Schild.
|
||
func stat(c: Vector2, r: float, value: String, col: Color, fsize: int, shape_name := "") -> void:
|
||
var kind: String = shape_name if shape_name != "" else P.stat
|
||
if kind == "hex":
|
||
var pts := PackedVector2Array()
|
||
for i in 6:
|
||
var a := -PI / 2 + i * PI / 3
|
||
pts.append(c + Vector2(cos(a), sin(a)) * r)
|
||
var closed := pts.duplicate()
|
||
closed.append(pts[0])
|
||
draw_colored_polygon(pts, col)
|
||
draw_colored_polygon(PackedVector2Array([pts[4], pts[5], pts[0], c + Vector2(0, -r * 0.1), c + Vector2(-r * 0.55, r * 0.15)]), Color(1, 1, 1, 0.16))
|
||
draw_polyline(closed, P.stat_outline, P.stat_w + 1, true)
|
||
else:
|
||
draw_circle(c, r + P.stat_w, P.stat_outline, true, -1, true)
|
||
draw_circle(c, r, col, true, -1, true)
|
||
draw_circle(c + Vector2(-r * 0.25, -r * 0.3), r * 0.45, Color(1, 1, 1, 0.16), true, -1, true)
|
||
draw_arc(c, r - 0.5, 0, TAU, 40, darker(col, 0.75), 1.5, true)
|
||
txt_outlined(value, fsize, Color.WHITE, c, 3)
|
||
|
||
|
||
func crystal(c: Vector2, r: float, cost: String, fsize: int) -> void:
|
||
stat(c, r, cost, P.crystal, fsize, "hex")
|
||
|
||
|
||
func keyword_icon(c: Vector2, r: float, kind: String, col: Color) -> void:
|
||
draw_circle(c, r + 3, Color(0.05, 0.05, 0.08, 0.75))
|
||
var w := maxf(1.5, r * 0.22)
|
||
match kind:
|
||
"Doppelschlag":
|
||
draw_line(c + Vector2(-r * 0.65, r * 0.65), c + Vector2(r * 0.6, -r * 0.6), col, w)
|
||
draw_line(c + Vector2(r * 0.65, r * 0.65), c + Vector2(-r * 0.6, -r * 0.6), col, w)
|
||
"Regeneration":
|
||
draw_line(c + Vector2(0, -r * 0.7), c + Vector2(0, r * 0.7), col, w * 1.5)
|
||
draw_line(c + Vector2(-r * 0.7, 0), c + Vector2(r * 0.7, 0), col, w * 1.5)
|
||
"Spott":
|
||
draw_line(c + Vector2(0, -r * 0.7), c + Vector2(0, r * 0.2), col, w * 1.6)
|
||
draw_circle(c + Vector2(0, r * 0.6), w * 0.95, col)
|
||
"Flink":
|
||
for i in 2:
|
||
var x := c.x - r * 0.55 + i * r * 0.55
|
||
draw_polyline(PackedVector2Array([Vector2(x, c.y - r * 0.6), Vector2(x + r * 0.5, c.y), Vector2(x, c.y + r * 0.6)]), col, w)
|
||
|
||
|
||
# --- Elementsymbole --------------------------------------------------------------
|
||
|
||
func glyph(elem: String, c: Vector2, s: float, alpha := 0.9) -> void:
|
||
var col := lighter(ELEM[elem], P.elem_light)
|
||
col.a = alpha
|
||
if P.glyph_outline:
|
||
for o in [Vector2(-2, 0), Vector2(2, 0), Vector2(0, -2), Vector2(0, 2), Vector2(2, 2), Vector2(-2, 2)]:
|
||
_glyph(elem, c + o, s, Color(0.04, 0.03, 0.06, alpha))
|
||
elif P.glyph_shadow:
|
||
_glyph(elem, c + Vector2(2, 3), s, Color(0, 0, 0, alpha * 0.45))
|
||
_glyph(elem, c, s, col)
|
||
_glyph_light(elem, c, s, Color(1, 1, 1, alpha * 0.35))
|
||
|
||
|
||
func _glyph(elem: String, c: Vector2, s: float, col: Color) -> void:
|
||
var h := s / 2
|
||
match elem:
|
||
"Feuer":
|
||
for i in 3:
|
||
var off := Vector2((i - 1) * s * 0.32, (0 if i == 1 else s * 0.12))
|
||
var hh := h * (1.0 if i == 1 else 0.68)
|
||
var w := hh * 0.75
|
||
draw_colored_polygon(PackedVector2Array([c + off + Vector2(0, -hh), c + off + Vector2(w * 0.55, -hh * 0.25), c + off + Vector2(w * 0.4, hh * 0.45),
|
||
c + off + Vector2(0, hh), c + off + Vector2(-w * 0.4, hh * 0.45), c + off + Vector2(-w * 0.55, -hh * 0.25)]), col)
|
||
"Wasser":
|
||
for i in 2:
|
||
var y := c.y + (i - 0.5) * s * 0.3
|
||
for k in 3:
|
||
var x := c.x - s * 0.4 + k * s * 0.4
|
||
draw_arc(Vector2(x, y), s * 0.2, PI, TAU, 12, col, maxf(2, s * 0.09), true)
|
||
"Erde":
|
||
for i in 3:
|
||
var off := (i - 1) * s * 0.4
|
||
var hs := h * (1.0 if i == 1 else 0.65)
|
||
draw_colored_polygon(PackedVector2Array([c + Vector2(off - hs, h * 0.7), c + Vector2(off, -hs), c + Vector2(off + hs, h * 0.7)]), col)
|
||
draw_line(c + Vector2(-h, h * 0.7), c + Vector2(h, h * 0.7), col, maxf(2, s * 0.08))
|
||
"Luft":
|
||
for i in 3:
|
||
var r := h * (1.0 - i * 0.28)
|
||
draw_arc(c + Vector2(i * s * 0.06, 0), r, PI * 0.2 + i * 0.4, PI * 1.5 + i * 0.4, 20, col, maxf(2, s * 0.09), true)
|
||
|
||
|
||
## Lichtkante: kleiner heller Kern.
|
||
func _glyph_light(elem: String, c: Vector2, s: float, col: Color) -> void:
|
||
var h := s / 2
|
||
match elem:
|
||
"Feuer":
|
||
var w := h * 0.75
|
||
draw_colored_polygon(PackedVector2Array([c + Vector2(0, -h * 0.35), c + Vector2(w * 0.25, h * 0.35), c + Vector2(0, h * 0.75), c + Vector2(-w * 0.25, h * 0.35)]), Color(1.0, 0.9, 0.5, col.a * 2))
|
||
"Erde":
|
||
draw_colored_polygon(PackedVector2Array([c + Vector2(0, -h), c + Vector2(h * 0.35, -h * 0.4), c + Vector2(-h * 0.1, -h * 0.4)]), col)
|
||
_:
|
||
pass
|
||
|
||
|
||
# --- Karten ------------------------------------------------------------------------
|
||
|
||
## Kartenfläche in Elementfarbe mit Rahmen; frame: Rahmenfarbe (Seltenheit) oder null.
|
||
func card_body(rect: Rect2, elem: String, frame = null, shadow_size := 6) -> void:
|
||
var base: Color = ELEM[elem]
|
||
var fc: Color = frame if frame != null else P.card_border
|
||
if frame != null:
|
||
glow(rect, P.card_radius, fc, 7)
|
||
else:
|
||
shadow(rect, P.card_radius, shadow_size)
|
||
fill(rect, P.card_radius, lighter(base, P.card_grad), darker(base, 1.0 - P.card_grad * 1.6))
|
||
vignette(rect, P.card_radius, P.card_vignette)
|
||
if P.card_inner.a > 0:
|
||
outline(rect.grow(-P.card_border_w - 1), P.card_radius - P.card_border_w, P.card_inner, 1)
|
||
outline(rect, P.card_radius, fc, P.card_border_w)
|
||
|
||
|
||
func name_band(rect: Rect2, y: float, h: float, name: String, fsize: int, col = null) -> void:
|
||
var band := Rect2(rect.position.x + P.band_inset, y, rect.size.x - P.band_inset * 2, h)
|
||
if P.band_inset > 0:
|
||
fill(band, h / 2, P.band_bg, P.band_bg)
|
||
else:
|
||
draw_rect(band, P.band_bg)
|
||
var c: Color = col if col != null else P.band_text
|
||
txt(fit(name, fsize, band.size.x - 10), fsize, c, band.get_center(), "center", true)
|
||
|
||
|
||
## Kleine Karte (Hand, Feld): 110×140.
|
||
func card_small(rect: Rect2, name: String, elem: String, cost: int, atk: int, hp: int, frame = null, name_col = null) -> void:
|
||
card_body(rect, elem, frame)
|
||
glyph(elem, rect.position + Vector2(rect.size.x / 2, rect.size.y * 0.35), rect.size.x * 0.56)
|
||
name_band(rect, rect.position.y + rect.size.y * 0.5, 22, name, 11, name_col)
|
||
stat(rect.position + Vector2(17, rect.size.y - 17), 11, str(atk), P.amber, 13)
|
||
stat(rect.position + Vector2(rect.size.x - 17, rect.size.y - 17), 11, str(hp), P.blue, 13)
|
||
crystal(rect.position + Vector2(17, 17), 11, str(cost), 13)
|
||
|
||
|
||
## Große Karte (Vorschau): 170×238, mit Eigenschaft.
|
||
func card_big(rect: Rect2, name: String, elem: String, cost: int, atk: int, hp: int, kw: String, frame = null, name_col = null) -> void:
|
||
card_body(rect, elem, frame, 10)
|
||
glyph(elem, rect.position + Vector2(rect.size.x / 2, rect.size.y * 0.2), rect.size.x * 0.56)
|
||
name_band(rect, rect.position.y + rect.size.y * 0.36, 26, name, 14, name_col)
|
||
var y := rect.position.y + rect.size.y * 0.36 + 40
|
||
keyword_icon(Vector2(rect.position.x + 40, y), 9, kw, lighter(ELEM[elem], 0.45))
|
||
txt(kw, 12, P.text, Vector2(rect.position.x + 56, y), "midleft")
|
||
var box := Rect2(rect.position.x + 8, y + 18, rect.size.x - 16, 54)
|
||
draw_rect(box, Color(0.06, 0.06, 0.09, 0.6))
|
||
txt("Greift zweimal je Zug", 11, P.text, box.get_center())
|
||
stat(rect.position + Vector2(22, rect.size.y - 22), 15, str(atk), P.amber, 17)
|
||
stat(rect.position + Vector2(rect.size.x - 22, rect.size.y - 22), 15, str(hp), P.blue, 17)
|
||
crystal(rect.position + Vector2(22, 22), 14, str(cost), 17)
|
||
|
||
|
||
func card_back(rect: Rect2, deg := 0.0) -> void:
|
||
var c := rect.get_center()
|
||
draw_set_transform(c, deg_to_rad(deg))
|
||
var r := Rect2(-rect.size / 2, rect.size)
|
||
shadow(r, P.card_radius, 6)
|
||
fill(r, P.card_radius, P.back_bg, P.back_bg2)
|
||
outline(r.grow(-9), P.card_radius - 4, P.back_inner, 2)
|
||
draw_circle(Vector2.ZERO, 22, Color(P.back_inner, 0.5), true, -1, true)
|
||
draw_arc(Vector2.ZERO, 22, 0, TAU, 48, P.back_border, 2, true)
|
||
outline(r, P.card_radius, P.back_border, P.card_border_w + 1)
|
||
txt("?", 30, P.back_border, Vector2(0, 0), "center", true)
|
||
draw_set_transform(Vector2.ZERO)
|
||
|
||
|
||
func deck(rect: Rect2, count: String, label := "") -> void:
|
||
for i in range(3, 0, -1):
|
||
var r := Rect2(rect.position + Vector2(i * 3, -i * 3), rect.size)
|
||
fill(r, P.card_radius, darker(P.back_bg, 0.8), darker(P.back_bg2, 0.8))
|
||
outline(r, P.card_radius, Color(0, 0, 0, 0.5), 1)
|
||
shadow(rect, P.card_radius, 6)
|
||
fill(rect, P.card_radius, P.back_bg, P.back_bg2)
|
||
outline(rect.grow(-9), P.card_radius - 4, P.back_inner, 2)
|
||
outline(rect, P.card_radius, Color(P.back_border, 0.6), 2)
|
||
if label != "":
|
||
txt(label, 17, P.muted, rect.get_center() + Vector2(0, -14), "center", true)
|
||
txt("◆ 0", 17, P.mana, rect.get_center() + Vector2(0, 14), "center", true)
|
||
else:
|
||
txt(count, 22, P.text, rect.get_center(), "center", true)
|
||
txt(count, 11, P.muted, Vector2(rect.get_center().x, rect.end.y - 22), "center")
|
||
|
||
|
||
func hero_box(rect: Rect2, name: String, life: String, border = null) -> void:
|
||
panel(rect, border)
|
||
txt(name, 17, P.text, Vector2(rect.get_center().x, rect.position.y + 12), "midtop", true)
|
||
txt("♥", 24, P.life, Vector2(rect.position.x + 24, rect.position.y + 46), "center", true)
|
||
txt(life, 24, P.life, Vector2(rect.position.x + 42, rect.position.y + 46), "midleft", true)
|
||
txt("◆", 20, P.mana, Vector2(rect.end.x - 54, rect.position.y + 46), "center", true)
|
||
txt("0", 24, P.mana, Vector2(rect.end.x - 14, rect.position.y + 46), "midright", true)
|
||
|
||
|
||
func element_row(rect: Rect2, elem: String, kw: String, filled: int, played: String) -> void:
|
||
var col: Color = ELEM[elem]
|
||
fill(rect, 6, Color(col, 0.16), Color(col, 0.10))
|
||
outline(rect, 6, Color(col, 0.45), 1)
|
||
txt(elem, 13, P.text, Vector2(rect.position.x + 10, rect.get_center().y), "midleft", true)
|
||
for k in 2:
|
||
keyword_icon(Vector2(rect.position.x + 86 + k * 24, rect.get_center().y), 8, kw, lighter(col, 0.45) if k < filled else Color(col, 0.35))
|
||
txt(played, 15, lighter(col, 0.45), Vector2(rect.position.x + 142, rect.get_center().y), "midleft", true)
|
||
|
||
|
||
# --- Hintergrund ---------------------------------------------------------------------
|
||
|
||
func background() -> void:
|
||
fill(Rect2(Vector2.ZERO, size), 0, P.bg_top, P.bg_bottom)
|
||
var c := Vector2(size.x * 0.5, size.y * 0.42)
|
||
for i in range(8, 0, -1):
|
||
draw_circle(c, size.x * 0.09 * i, Color(1, 1, 1, 0.012))
|
||
if P.vignette > 0:
|
||
for i in 6:
|
||
outline(Rect2(Vector2.ZERO, size).grow(-i * 14.0), 0, Color(0, 0, 0, P.vignette * 0.12), 28)
|
||
|
||
|
||
# --- Der Bildschirm ------------------------------------------------------------------
|
||
|
||
func _draw() -> void:
|
||
background()
|
||
# Gegner: Hand oben, Stapel und Kasten rechts
|
||
for i in 4:
|
||
var r := Rect2(410 + i * 120, 11, 110, 140)
|
||
var t := i - 1.5
|
||
card_back(Rect2(r.position + Vector2(0, -t * t * 3), r.size), -t * 3)
|
||
deck(Rect2(1090, 10, 130, 182), "35")
|
||
hero_box(Rect2(1050, 200, 210, 70), "Gegner", "35", P.mana)
|
||
button(Rect2(20, 48, 210, 32), "Überspringen", 13)
|
||
element_row(Rect2(20, 222, 210, 28), "Feuer", "Doppelschlag", 1, "1")
|
||
# Bretter
|
||
for j in 5:
|
||
var r := Rect2(345 + j * 120, 220, 110, 140)
|
||
if j == 0:
|
||
card_small(r, "Schwelender Drache", "Feuer", 1, 0, 5)
|
||
else:
|
||
slot(r)
|
||
for j in 5:
|
||
var r := Rect2(345 + j * 120, 440, 110, 140)
|
||
if j == 0:
|
||
card_small(r, "Rieselnder Geist", "Wasser", 1, 1, 2)
|
||
else:
|
||
slot(r)
|
||
element_row(Rect2(20, 442, 210, 28), "Wasser", "Regeneration", 1, "1")
|
||
# Hand
|
||
var hand := [["Leiser Hauch", "Luft", 0, 0, 1, null, null], ["Glimmender Wolf", "Feuer", 1, 1, 3, P.rare, lighter(P.rare, 0.25)],
|
||
["Stiller Tropfen", "Wasser", 0, 0, 1, null, null], ["Fester Kiesel", "Erde", 1, 1, 1, P.ultra, lighter(P.ultra, 0.25)]]
|
||
var total := hand.size() * 110 + (hand.size() - 1) * 10
|
||
for i in hand.size():
|
||
var h = hand[i]
|
||
var t := i - (hand.size() - 1) / 2.0
|
||
var r := Rect2(240 + (800 - total) / 2 + i * 120, 610 + t * t * 3, 110, 140)
|
||
draw_set_transform(r.get_center(), deg_to_rad(t * 3))
|
||
card_small(Rect2(-r.size / 2, r.size), h[0], h[1], h[2], h[3], h[4], h[5], h[6])
|
||
draw_set_transform(Vector2.ZERO)
|
||
# Eigener Kasten, Stapel, Vorschau
|
||
hero_box(Rect2(1050, 526, 210, 70), "Spieler", "30")
|
||
deck(Rect2(1090, 606, 130, 182), "35", "Ziehen")
|
||
card_big(Rect2(1070, 278, 170, 238), "Glimmender Wolf", "Feuer", 1, 1, 3, "Doppelschlag", P.rare, lighter(P.rare, 0.25))
|
||
txt("Dinger · Richtung: " + P.get("name", "?"), 12, P.muted, Vector2(20, 780), "midleft")
|