class_name CardView extends Control ## Zeichnet eine Karte (Hand, Sammlung, Booster, Vorschau). signal clicked(view: CardView) signal hover(card: Cards.Card, entered: bool) var card: Cards.Card var border = null # Color oder null (dann Seltenheitsfarbe) var rarity := "gewöhnlich" # nur Optik: Rahmenfarbe der eigenen Stufe var dim := false ## focusable: per Gamepad oder Tab anwählbar (Sammlung, Booster); A bzw. Enter wirkt wie ein Klick. func _init(c: Cards.Card, sz: Vector2, focusable: bool = false, rar: String = "gewöhnlich") -> void: card = c rarity = rar custom_minimum_size = sz size = sz mouse_filter = Control.MOUSE_FILTER_STOP mouse_entered.connect(func(): hover.emit(card, true)) mouse_exited.connect(func(): hover.emit(card, false)) if focusable: focus_mode = Control.FOCUS_ALL focus_entered.connect(func(): hover.emit(card, true) queue_redraw()) focus_exited.connect(func(): hover.emit(card, false) queue_redraw()) func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: accept_event() clicked.emit(self) elif has_focus() and event.is_action_pressed("ui_accept"): accept_event() clicked.emit(self) func _draw() -> void: var rect := Rect2(Vector2.ZERO, size) var big := size.x >= 180 var mid := size.x >= 115 var f_name := 18 if big else (14 if mid else 12) var f_text := 14 if big else (11 if mid else 10) var f_stat := 24 if big else (18 if mid else 15) Style.fill_elements(self, rect, card.elements, 8) var bcol: Color = border if border != null else Cards.RARITY_COLORS[rarity] Style.border(self, rect, bcol, 3 if big else 2, 8) # Kosten var r := 16 if big else 12 var cc := Vector2(r + 4, r + 4) draw_circle(cc, r, Color("14141c")) Style.text(self, str(card.cost), f_stat, Style.GOLD, cc, "center", true) # Name und Kombo var name_left := 2 * r + 10 var nm := Style.fit(card.title(), true, f_name, size.x - name_left - 6) Style.text(self, nm, f_name, Style.TEXT, Vector2((name_left + size.x - 6) / 2.0, 4), "midtop", true) if mid: var sub: String = tr(card.combo()) if card.is_combo() else "" Style.text(self, sub, f_text, Color("e6e6e6"), Vector2(size.x / 2, 2 * r + 4), "midtop") # Textfeld: Höhe folgt dem umbrochenen Text und der Schriftgröße, das Bild bekommt den Rest var tsize := Style.fs(f_text) var text_w: float = size.x - 20 var needed: float = Style.FONT.get_multiline_string_size(card.text(), HORIZONTAL_ALIGNMENT_LEFT, text_w, tsize).y + 8 if card.text() != "" else size.y * 0.42 var box_bottom: float = size.y - (28 if big else 22) var band_top: float = 2 * r + 4 + (f_text + 6 if mid else 0) # unter Name und Kombo var box_top: float = maxf(maxf(size.y * 0.30, band_top), box_bottom - maxf(needed, size.y * 0.42)) var box := Rect2(6, box_top, size.x - 12, box_bottom - box_top) # Bild var band_bottom: float = box_top - 4 if band_bottom - band_top > 14: var gsize: float = minf(band_bottom - band_top, size.x * 0.42) Style.glyph(self, card, Vector2(size.x / 2, (band_top + band_bottom) / 2), gsize) draw_rect(box, Color(0.06, 0.06, 0.09, 0.67)) var max_lines := maxi(1, int((box.size.y - 6) / Style.FONT.get_height(tsize))) # große Schrift: lieber kürzen als überlaufen draw_multiline_string(Style.FONT, Vector2(box.position.x + 4, box.position.y + 4 + Style.FONT.get_ascent(tsize)), card.text(), HORIZONTAL_ALIGNMENT_LEFT, box.size.x - 8, tsize, max_lines, Style.TEXT) # Werte Style.text(self, str(card.attack), f_stat, Style.YELLOW, Vector2(10, size.y - 6), "bottomleft", true) Style.text(self, str(card.health), f_stat, Style.RED, Vector2(size.x - 10, size.y - 6), "bottomright", true) if dim: draw_rect(rect, Color(0, 0, 0, 0.47)) if has_focus(): Style.border(self, rect, Style.GOLD, 4, 8)