55 lines
1.9 KiB
Markdown
55 lines
1.9 KiB
Markdown
|
|
# VulkanAnimated
|
||
|
|
|
||
|
|
A live HUD demo: three `Observable<float>`s drive `ProgressBar`s, three
|
||
|
|
`Observable<std::string>`s drive `Text` labels, and an FPS readout in
|
||
|
|
the corner ticks every frame. Everything updates from a single
|
||
|
|
`onUpdate` listener — no `Invalidate()` / `Redraw()` calls.
|
||
|
|
|
||
|
|
## What it shows
|
||
|
|
|
||
|
|
- **`Observable<T>` data flow**: change a value in `onUpdate`, the
|
||
|
|
next frame's `RebuildFrame` re-emits the draw list with the new value
|
||
|
|
automatically. No tree rebuild.
|
||
|
|
- **`ProgressBar::bindValue(obs, lo, hi)`** — the bar fill normalises the
|
||
|
|
observable's current value into 0..1 each frame.
|
||
|
|
- **`Text::bind(observable)`** — the displayed string is sourced from
|
||
|
|
the observable each frame, replacing any baked-in runs.
|
||
|
|
- **Composition pattern**: a small lambda helper builds one HP/MP-style
|
||
|
|
row (`Text` + `ProgressBar` inside an `HStack`) given the observables
|
||
|
|
and a colour, then the row is dropped into the parent `VStack` like
|
||
|
|
any other widget.
|
||
|
|
- **Different update rates per observable**: `health` oscillates at 0.7
|
||
|
|
rad/s, `mana` at 1.3, `charge` advances linearly modulo 1 — visible
|
||
|
|
proof that each observable updates independently.
|
||
|
|
|
||
|
|
## Run
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd examples/VulkanAnimated
|
||
|
|
crafter-build -r
|
||
|
|
```
|
||
|
|
|
||
|
|
You should see "Animated HUD" with three coloured bars (red HP, blue MP,
|
||
|
|
yellow Charge) all moving at different rates, with the FPS readout in
|
||
|
|
the top-right ticking once per frame.
|
||
|
|
|
||
|
|
Click `Quit` to exit.
|
||
|
|
|
||
|
|
## Notes
|
||
|
|
|
||
|
|
The whole tick handler is just:
|
||
|
|
|
||
|
|
```cpp
|
||
|
|
EventListener<FrameTime> tick(&window.onUpdate, [&](FrameTime ft){
|
||
|
|
t += ft.delta.count();
|
||
|
|
health = 0.5f + 0.5f * std::sin(t * 0.7f);
|
||
|
|
mana = std::abs(std::sin(t * 1.3f));
|
||
|
|
charge = std::fmod(t * 0.3f, 1.0f);
|
||
|
|
healthLabel = std::format("HP {:>3.0f} / 100", health.Get() * 100);
|
||
|
|
// …
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
That's the entire animation system. There is deliberately no
|
||
|
|
`Animation<T>` / tween primitive in the library — drive observables
|
||
|
|
from any source you like.
|