class_name BoosterScreen extends Control const CARD_W := 200 const CARD_H := 280 var app var cards: Array = [] # {"card", "rarity", "upgraded", "dust"} je Karte var revealed := {} var coins_label: Label var msg_label: Label var b_buy: Button var b_all: Button var slots: Control var fx_layer: Control var fresh := {} # gerade aufgedeckt: wird umgedreht class CardBack extends Control: signal clicked func _init(sz: Vector2) -> void: size = sz custom_minimum_size = sz mouse_filter = Control.MOUSE_FILTER_STOP focus_mode = Control.FOCUS_ALL focus_entered.connect(queue_redraw) focus_exited.connect(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() elif has_focus() and event.is_action_pressed("ui_accept"): accept_event() clicked.emit() func _draw() -> void: var rect := Rect2(Vector2.ZERO, size) draw_style_box(Style.box(Color("3c285a"), 8, Style.GOLD, 5 if has_focus() else 3), rect) Style.border(self, rect.grow(-15), Color("5a3c82"), 2, 6) Style.text(self, "?", 48, Style.GOLD, size / 2, "center", true) func slot_rect(i: int) -> Rect2: var gap := 20 var x0 := (1280 - Profile.BOOSTER_SIZE * CARD_W - (Profile.BOOSTER_SIZE - 1) * gap) / 2 return Rect2(x0 + i * (CARD_W + gap), 230, CARD_W, CARD_H) func _ready() -> void: Style.header(self, "Booster", func(): app.show_screen(MenuScreen.new())) coins_label = Style.chip(self, "", Rect2(860, 26, 240, 38)) fx_layer = Control.new() fx_layer.mouse_filter = Control.MOUSE_FILTER_IGNORE add_child(fx_layer) slots = Control.new() slots.mouse_filter = Control.MOUSE_FILTER_IGNORE add_child(slots) msg_label = Style.label(self, "", 17, Style.RED, Rect2(0, 640, 1280, 22), "center") b_buy = Style.button(self, "Booster kaufen (%d Münzen)" % Profile.BOOSTER_COST, Rect2(370, 690, 330, 52), buy, Color("5a4628")) b_buy.add_theme_font_size_override("font_size", 20) b_all = Style.button(self, "Alle aufdecken", Rect2(720, 690, 200, 52), reveal_all) refresh() func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE: app.show_screen(MenuScreen.new()) func buy() -> void: var p: Profile = app.profile var got: Array = p.open_booster() if got.is_empty(): msg_label.text = "Nicht genug Münzen" msg_label.add_theme_color_override("font_color", Style.RED) return app.save() app.sfx.play("play") cards = got revealed = {} msg_label.text = "" refresh() func reveal(i: int) -> void: revealed[i] = true fresh = {i: 0.0} app.sfx.play("combo" if cards[i].rarity != "Common" else "click") refresh() func reveal_all() -> void: fresh = {} var k := 0 for i in Profile.BOOSTER_SIZE: if not revealed.has(i): fresh[i] = k * 0.12 k += 1 revealed[i] = true app.sfx.play("play") refresh() ## Umdrehen: die Karte wächst aus der Mitte; seltene Stufen blitzen in ihrer Farbe auf. func flip(v: CardView, delay: float, rarity: String) -> void: if not Style.animations: return v.scale.x = 0.0 var tw := create_tween() tw.tween_interval(delay) tw.tween_property(v, "scale:x", 1.0, 0.18).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT) if rarity == "Common": return var burst := Style.panel(fx_layer, Rect2(v.position, v.size).grow(6), Color(Cards.RARITY_COLORS[rarity], 0.6), 12) burst.pivot_offset = burst.size / 2 burst.modulate.a = 0.0 var bt := create_tween() bt.tween_interval(delay + 0.1) bt.tween_property(burst, "modulate:a", 1.0, 0.05) bt.parallel().tween_property(burst, "scale", Vector2(1.25, 1.25), 0.45).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_OUT) bt.tween_property(burst, "modulate:a", 0.0, 0.3) bt.tween_callback(burst.queue_free) func refresh() -> void: var p: Profile = app.profile coins_label.text = "Münzen: %d" % p.coins b_buy.disabled = p.coins < Profile.BOOSTER_COST b_all.disabled = cards.is_empty() or revealed.size() >= Profile.BOOSTER_SIZE Style.clear(slots) for i in Profile.BOOSTER_SIZE: var r := slot_rect(i) if cards.is_empty(): Style.panel(slots, r, Style.PANEL, 8, Style.PANEL_LIGHT, 2) elif revealed.has(i): var res: Dictionary = cards[i] var c: Cards.Card = res.card var v := CardView.new(c.leveled(Cards.RARITIES.find(res.rarity)), r.size, false, res.rarity) v.position = r.position slots.add_child(v) if fresh.has(i): flip(v, fresh[i], res.rarity) Style.label(slots, tr(res.rarity), 16, Cards.RARITY_COLORS[res.rarity], Rect2(r.position.x, r.end.y + 8, r.size.x, 24), "center", true) if res.get("new", false): Style.label(slots, "Neu!", 16, Style.GOLD, Rect2(r.position.x, r.end.y + 32, r.size.x, 24), "center", true) elif res.upgraded: Style.label(slots, "Aufgewertet", 16, Style.GREEN, Rect2(r.position.x, r.end.y + 32, r.size.x, 24), "center", true) else: Style.label(slots, "+%d Staub" % res.dust, 14, Style.MUTED, Rect2(r.position.x, r.end.y + 32, r.size.x, 24), "center") else: var back := CardBack.new(r.size) back.position = r.position back.clicked.connect(reveal.bind(i)) slots.add_child(back) fresh = {}