nodes/floating_label.pyΒΆ

Part of GDQuest Open RPG.

 1"""Short-lived damage / heal / miss label that floats up + fades."""
 2
 3from __future__ import annotations
 4
 5from simvx.core import Node2D
 6from simvx.core.math.types import Vec2
 7
 8
 9class FloatingLabel(Node2D):
10    LIFETIME = 0.85
11    RISE = 28.0
12
13    def __init__(self, text: str, origin: Vec2, colour: tuple[float, float, float, float] = (1, 1, 1, 1)) -> None:
14        super().__init__()
15        self.text = text
16        self.origin = Vec2(origin)
17        self.position = Vec2(origin)
18        self.colour = tuple(colour)
19        self.t = 0.0
20        self.z_index = 2000
21
22    def on_update(self, dt: float) -> None:
23        self.t += dt
24        if self.t >= self.LIFETIME:
25            self.destroy()
26            return
27        u = self.t / self.LIFETIME
28        self.position = Vec2(self.origin.x, self.origin.y - self.RISE * u)
29
30    def on_draw(self, renderer) -> None:
31        if self.t >= self.LIFETIME:
32            return
33        u = self.t / self.LIFETIME
34        alpha = max(0.0, 1.0 - u)
35        col = (self.colour[0], self.colour[1], self.colour[2], alpha)
36        # Pop scale from 0.85 -> 1.10 at 30%, then settle to 1.0
37        scale = 1.05 + 0.15 * max(0.0, 0.30 - u) * 3.0
38        # Outline by drawing 4 dark copies offset
39        text = self.text
40        x = self.position.x - renderer.text_width(text, scale) * 0.5
41        y = self.position.y
42        for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
43            renderer.draw_text(text, (x + dx, y + dy), colour=(0, 0, 0, alpha), scale=scale)
44        renderer.draw_text(text, (x, y), colour=col, scale=scale)