update
This commit is contained in:
163
scripts/icons.gd
Normal file
163
scripts/icons.gd
Normal file
@@ -0,0 +1,163 @@
|
||||
extends RefCounted
|
||||
## Gezeichnete Sinnbilder für das HUD: Münze und Würfel. Bilder als Dateien
|
||||
## gibt es im Projekt nicht; alles wird zur Laufzeit gemalt. Kein class_name:
|
||||
## den Klassencache baut nur der Editor, headless fehlt er - deshalb
|
||||
## `const Icons = preload(...)` und dann `Icons.MuenzIcon.new(...)`.
|
||||
|
||||
|
||||
## Gezeichnete Münze. Bilder als Dateien gibt es im Projekt nicht; alles wird
|
||||
## zur Laufzeit gemalt, so wie die Würfel auch. Vorn das Sinnbild der Wirkung
|
||||
## (Wappen), hinten die glatte Zahlseite.
|
||||
class MuenzIcon extends Control:
|
||||
const RAND := Color(0.40, 0.29, 0.11) ## Prägekante
|
||||
const FLAECHE := Color(0.78, 0.60, 0.26) ## Messing
|
||||
const GLANZ := Color(0.91, 0.75, 0.39) ## Lichtkante
|
||||
const GRAVUR := Color(0.19, 0.13, 0.04) ## eingeschlagenes Zeichen
|
||||
|
||||
var id := ""
|
||||
var farbe := GRAVUR ## Zeichenfarbe, von den Zeichenhilfen benutzt
|
||||
var kind_col := Color.WHITE
|
||||
var seite := 0 ## 0 = Wappen (Sinnbild), 1 = Zahl
|
||||
|
||||
func _init(muenze: String, col: Color, px: float) -> void:
|
||||
id = muenze
|
||||
kind_col = col
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
custom_minimum_size = Vector2(px, px)
|
||||
size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
pivot_offset = Vector2(px, px) * 0.5
|
||||
|
||||
func _draw() -> void:
|
||||
var s := minf(size.x, size.y)
|
||||
var m := size * 0.5
|
||||
var r := s * 0.5
|
||||
draw_circle(m, r, RAND)
|
||||
draw_circle(m - Vector2(r, r) * 0.05, r * 0.95, GLANZ)
|
||||
draw_circle(m, r * 0.89, FLAECHE)
|
||||
# Der Farbring sagt, ob die Münze dir hilft oder den anderen schadet.
|
||||
draw_arc(m, r * 0.79, 0, TAU, 40, kind_col, maxf(1.0, s * 0.05))
|
||||
if seite == 1:
|
||||
draw_arc(m, r * 0.52, 0, TAU, 32, GRAVUR, maxf(1.0, s * 0.04))
|
||||
draw_circle(m, s * 0.09, GRAVUR)
|
||||
return
|
||||
_zeichen(m, s * 0.74)
|
||||
|
||||
func _zeichen(m: Vector2, s: float) -> void:
|
||||
match id:
|
||||
"peek":
|
||||
_auge(m, s)
|
||||
"count":
|
||||
_striche(m, s)
|
||||
"set_face":
|
||||
_schiefer_wuerfel(m, s * 0.50)
|
||||
"gain_die":
|
||||
_wuerfel(m + Vector2(-s * 0.10, 0), s * 0.46, 4)
|
||||
_plus(m + Vector2(s * 0.26, -s * 0.20), s * 0.20)
|
||||
"bid_up":
|
||||
_pfeil(m, s * 0.52, true)
|
||||
"gag":
|
||||
var r := Rect2(m - Vector2(s * 0.28, s * 0.16), Vector2(s * 0.56, s * 0.32))
|
||||
draw_rect(r, farbe, false, s * 0.07)
|
||||
draw_line(m + Vector2(-s * 0.28, s * 0.22), m + Vector2(s * 0.28, -s * 0.22),
|
||||
farbe, s * 0.08)
|
||||
_:
|
||||
draw_circle(m, s * 0.26, farbe)
|
||||
|
||||
## Vier Striche und einer quer - eine Strichliste, das Zeichen fürs Zählen.
|
||||
func _striche(mitte: Vector2, s: float) -> void:
|
||||
var w := maxf(1.5, s * 0.07)
|
||||
for i in 4:
|
||||
var x: float = mitte.x + (float(i) - 1.5) * s * 0.16
|
||||
draw_line(Vector2(x, mitte.y - s * 0.26), Vector2(x, mitte.y + s * 0.26), farbe, w)
|
||||
draw_line(mitte + Vector2(-s * 0.32, s * 0.20), mitte + Vector2(s * 0.32, -s * 0.20), farbe, w)
|
||||
|
||||
## Ein gekippter Würfel mit einem Auge - der wird gerade umgedreht.
|
||||
func _schiefer_wuerfel(mitte: Vector2, kante: float) -> void:
|
||||
var h := kante * 0.5
|
||||
var ecken := PackedVector2Array()
|
||||
for e: Vector2 in [Vector2(-h, -h), Vector2(h, -h), Vector2(h, h), Vector2(-h, h)]:
|
||||
ecken.append(mitte + e.rotated(0.35))
|
||||
draw_colored_polygon(ecken, farbe)
|
||||
draw_circle(mitte, kante * 0.11, FLAECHE)
|
||||
|
||||
func _wuerfel(mitte: Vector2, kante: float, augen: int) -> void:
|
||||
var r := Rect2(mitte - Vector2(kante, kante) * 0.5, Vector2(kante, kante))
|
||||
draw_rect(r, farbe, true)
|
||||
var punkt := kante * 0.10
|
||||
var weg := kante * 0.26
|
||||
for p: Vector2 in DieIcon.PIPS[augen]:
|
||||
draw_circle(mitte + p * weg, punkt, FLAECHE)
|
||||
|
||||
func _plus(mitte: Vector2, r: float) -> void:
|
||||
draw_rect(Rect2(mitte - Vector2(r, r * 0.28), Vector2(r * 2, r * 0.56)), farbe, true)
|
||||
draw_rect(Rect2(mitte - Vector2(r * 0.28, r), Vector2(r * 0.56, r * 2)), farbe, true)
|
||||
|
||||
## Der Schaft sitzt hinter der Spitze, sonst überlagern sich beide zu
|
||||
## einem Klecks.
|
||||
func _pfeil(mitte: Vector2, h: float, hoch: bool) -> void:
|
||||
var d := -1.0 if hoch else 1.0
|
||||
var schaft_y: float = mitte.y - d * h * 0.48
|
||||
var oben: float = minf(mitte.y, schaft_y)
|
||||
draw_rect(Rect2(Vector2(mitte.x - h * 0.13, oben),
|
||||
Vector2(h * 0.26, absf(mitte.y - schaft_y))), farbe, true)
|
||||
draw_colored_polygon([mitte + Vector2(0, d * h * 0.50),
|
||||
mitte + Vector2(-h * 0.34, d * h * 0.02),
|
||||
mitte + Vector2(h * 0.34, d * h * 0.02)], farbe)
|
||||
|
||||
func _auge(mitte: Vector2, s: float) -> void:
|
||||
var punkte := PackedVector2Array()
|
||||
for i in 17:
|
||||
var t := -1.0 + 2.0 * i / 16.0
|
||||
punkte.append(mitte + Vector2(t * s * 0.34, -sqrt(maxf(0.0, 1.0 - t * t)) * s * 0.20))
|
||||
for i in 17:
|
||||
var t := 1.0 - 2.0 * i / 16.0
|
||||
punkte.append(mitte + Vector2(t * s * 0.34, sqrt(maxf(0.0, 1.0 - t * t)) * s * 0.20))
|
||||
draw_polyline(punkte, farbe, s * 0.05, true)
|
||||
draw_circle(mitte, s * 0.11, farbe)
|
||||
|
||||
|
||||
## Ein gezeichnetes Würfelbild: Augen 1-6 oder ein Fragezeichen bei unbekanntem
|
||||
## Wert. Wird überall dort benutzt, wo früher Ziffern oder Sternchen standen.
|
||||
class DieIcon extends Control:
|
||||
const PIPS := {
|
||||
1: [Vector2(0, 0)],
|
||||
2: [Vector2(-1, -1), Vector2(1, 1)],
|
||||
3: [Vector2(-1, -1), Vector2(0, 0), Vector2(1, 1)],
|
||||
4: [Vector2(-1, -1), Vector2(-1, 1), Vector2(1, -1), Vector2(1, 1)],
|
||||
5: [Vector2(-1, -1), Vector2(-1, 1), Vector2(0, 0), Vector2(1, -1), Vector2(1, 1)],
|
||||
6: [Vector2(-1, -1), Vector2(-1, 0), Vector2(-1, 1),
|
||||
Vector2(1, -1), Vector2(1, 0), Vector2(1, 1)],
|
||||
}
|
||||
|
||||
var value := 0
|
||||
var _box := StyleBoxFlat.new()
|
||||
|
||||
func _init(v: int, px: float = 0.0, bg := Color.TRANSPARENT) -> void:
|
||||
value = v
|
||||
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||||
if px > 0.0:
|
||||
custom_minimum_size = Vector2(px, px)
|
||||
# sonst zieht der Container das Symbol in die Höhe und es wird unrund
|
||||
size_flags_vertical = Control.SIZE_SHRINK_CENTER
|
||||
if bg.a > 0.0:
|
||||
_box.bg_color = bg
|
||||
else:
|
||||
_box.bg_color = Color(0.93, 0.92, 0.88) if v > 0 else Color(0.26, 0.28, 0.34)
|
||||
_box.set_corner_radius_all(4)
|
||||
_box.border_color = Color(0, 0, 0, 0.35)
|
||||
_box.set_border_width_all(1)
|
||||
|
||||
func _draw() -> void:
|
||||
# Immer im grössten Quadrat zeichnen, das in die Fläche passt.
|
||||
var s := minf(size.x, size.y)
|
||||
var mid := size * 0.5
|
||||
draw_style_box(_box, Rect2(mid - Vector2(s, s) * 0.5, Vector2(s, s)))
|
||||
if value <= 0:
|
||||
var f := get_theme_default_font()
|
||||
var fs := int(s * 0.66)
|
||||
var w := f.get_string_size("?", HORIZONTAL_ALIGNMENT_LEFT, -1, fs).x
|
||||
draw_string(f, Vector2(mid.x - w * 0.5, mid.y + fs * 0.35), "?",
|
||||
HORIZONTAL_ALIGNMENT_LEFT, -1, fs, Color(0.85, 0.88, 0.94))
|
||||
return
|
||||
for p: Vector2 in PIPS[value]:
|
||||
draw_circle(mid + p * (s * 0.24), s * 0.105, Color(0.09, 0.08, 0.1))
|
||||
Reference in New Issue
Block a user