animated example
This commit is contained in:
parent
216972e73a
commit
c9fd1b1585
17 changed files with 576 additions and 465 deletions
115
examples/VulkanAnimated/main.cpp
Normal file
115
examples/VulkanAnimated/main.cpp
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
#include "vulkan/vulkan.h"
|
||||
|
||||
import Crafter.Graphics;
|
||||
import Crafter.Event;
|
||||
import Crafter.Math;
|
||||
import std;
|
||||
|
||||
using namespace Crafter;
|
||||
|
||||
// A simple "game HUD" demo: three Observable<float> drive ProgressBars at
|
||||
// different rates / colours, while Observable<std::string> labels feed the
|
||||
// Text widgets next to them. UIScene::RebuildFrame re-emits each frame, so
|
||||
// the only application code needed is "update the observables in
|
||||
// onUpdate" — no manual Invalidate / Redraw calls.
|
||||
|
||||
int main() {
|
||||
Device::Initialize();
|
||||
Window window(1280, 720, "VulkanAnimated");
|
||||
window.StartInit();
|
||||
window.FinishInit();
|
||||
|
||||
Font font("Inter.ttf");
|
||||
UI::Theme theme = UI::themes::default_dark();
|
||||
|
||||
UI::UIScene scene;
|
||||
scene.Initialize(window, "ui.comp.spv");
|
||||
scene.background(UI::Color{0.06f, 0.07f, 0.10f, 1.0f});
|
||||
|
||||
// ─── Observables ─────────────────────────────────────────────────────
|
||||
UI::Observable<float> health{1.0f};
|
||||
UI::Observable<float> mana {0.5f};
|
||||
UI::Observable<float> charge{0.0f};
|
||||
UI::Observable<std::string> healthLabel;
|
||||
UI::Observable<std::string> manaLabel;
|
||||
UI::Observable<std::string> chargeLabel;
|
||||
UI::Observable<std::string> fpsLabel;
|
||||
|
||||
// ─── Per-frame tick: drive the observables. UIScene re-emits on
|
||||
// onUpdate, so any read of these values is automatically picked
|
||||
// up in the next frame's draw list.
|
||||
float t = 0.0f;
|
||||
EventListener<FrameTime> tick(&window.onUpdate, [&](FrameTime ft) {
|
||||
const float dt = static_cast<float>(ft.delta.count());
|
||||
t += dt;
|
||||
|
||||
// Three offset waves at different rates / phases.
|
||||
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.0f);
|
||||
manaLabel = std::format("MP {:>3.0f} / 100", mana.Get() * 100.0f);
|
||||
chargeLabel = std::format("Charge {:>3.0f}%", charge.Get() * 100.0f);
|
||||
fpsLabel = (dt > 0.0f) ? std::format("{:>5.1f} fps", 1.0f / dt) : std::string{"---.- fps"};
|
||||
});
|
||||
|
||||
// ─── Helper: one HP/MP-style row (label on the left, bar on the right).
|
||||
// Build into a local (avoids returning a reference to a temporary
|
||||
// that dies at the end of the chain expression).
|
||||
auto bar = [&](UI::Observable<std::string>& label,
|
||||
UI::Observable<float>& value,
|
||||
UI::Color fg) -> UI::HStack {
|
||||
UI::HStack h;
|
||||
h.width(UI::Length::Frac(1))
|
||||
.spacing(12)
|
||||
.children(
|
||||
UI::Text{}.bind(label).font(font).size(16)
|
||||
.width(UI::Length::Px(160)),
|
||||
UI::ProgressBar{}
|
||||
.bindValue(value, 0.0f, 1.0f)
|
||||
.foreground(fg)
|
||||
.size(UI::Length::Frac(1), UI::Length::Px(20))
|
||||
);
|
||||
return h;
|
||||
};
|
||||
|
||||
scene.Root(
|
||||
UI::VStack{}
|
||||
.padding(28)
|
||||
.spacing(16)
|
||||
.children(
|
||||
UI::HStack{}
|
||||
.width(UI::Length::Frac(1))
|
||||
.children(
|
||||
UI::Text{"Animated HUD"}.font(font).size(28),
|
||||
UI::Spacer{},
|
||||
UI::Text{}.bind(fpsLabel).font(font).size(16)
|
||||
.color(UI::Color{0.55f, 0.85f, 1.0f, 1.0f})
|
||||
),
|
||||
|
||||
UI::Text{"Three Observable<float>s drive the bars; "
|
||||
"Observable<std::string>s drive the labels."}
|
||||
.font(font).size(14).color(UI::Color{0.65f, 0.65f, 0.65f, 1}),
|
||||
|
||||
bar(healthLabel, health, UI::Color{0.90f, 0.30f, 0.30f, 1.0f}),
|
||||
bar(manaLabel, mana, UI::Color{0.30f, 0.55f, 0.95f, 1.0f}),
|
||||
bar(chargeLabel, charge, UI::Color{0.95f, 0.85f, 0.30f, 1.0f}),
|
||||
|
||||
UI::Spacer{},
|
||||
|
||||
UI::HStack{}
|
||||
.width(UI::Length::Frac(1))
|
||||
.spacing(8)
|
||||
.children(
|
||||
UI::Spacer{},
|
||||
UI::Button{"Quit"}.font(font).style(theme.danger)
|
||||
.onClick([]{ std::_Exit(0); })
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
window.Render();
|
||||
window.StartUpdate();
|
||||
window.StartSync();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue