The new scene system brought over and updated animation to be optional in the scene engine.
This commit is contained in:
parent
d86617aa3a
commit
e7b6b42698
13 changed files with 194 additions and 38 deletions
|
|
@ -46,7 +46,7 @@ namespace boss {
|
|||
$actions.set<Text>(commit, {L"COMMIT"});
|
||||
$actions.set<Effect>(commit, {});
|
||||
$actions.set<Clickable>(commit,
|
||||
guecs::make_action(commit, game::Event::COMBAT_START, {}));
|
||||
guecs::make_action(commit, game::Event::COMBAT_START));
|
||||
|
||||
auto stats = $actions.entity("stats");
|
||||
$actions.set<Rectangle>(stats, {});
|
||||
|
|
@ -98,7 +98,7 @@ namespace boss {
|
|||
}
|
||||
|
||||
void UI::status(const std::wstring& msg, const std::wstring &button_msg) {
|
||||
$arena.$ui.show_text("status", msg);
|
||||
$arena.$gui.show_text("status", msg);
|
||||
$actions.show_text("commit", button_msg);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@ constexpr int COMBAT_UI_Y = RAY_VIEW_HEIGHT;
|
|||
constexpr int COMBAT_UI_WIDTH = RAY_VIEW_WIDTH ;
|
||||
constexpr int COMBAT_UI_HEIGHT = SCREEN_HEIGHT - RAY_VIEW_HEIGHT;
|
||||
|
||||
constexpr int SCENE_VIEW_WIDTH=SCREEN_WIDTH;
|
||||
constexpr int SCENE_VIEW_HEIGHT=SCREEN_HEIGHT;
|
||||
constexpr int SCENE_VIEW_X=0;
|
||||
constexpr int SCENE_VIEW_Y=0;
|
||||
|
||||
constexpr int INITIAL_MAP_W = 21;
|
||||
constexpr int INITIAL_MAP_H = 21;
|
||||
|
||||
|
|
|
|||
|
|
@ -249,13 +249,12 @@ namespace animation {
|
|||
sequence.INVARIANT();
|
||||
}
|
||||
|
||||
Animation load(const std::string &file, const std::string &anim_name) {
|
||||
std::optional<Animation> maybe_load(const std::string &file, const std::string &anim_name) {
|
||||
using nlohmann::json;
|
||||
std::ifstream infile(file);
|
||||
auto data = json::parse(infile);
|
||||
|
||||
dbc::check(data.contains(anim_name),
|
||||
$F("{} animation config does not have animation {}", file, anim_name));
|
||||
if(!data.contains(anim_name)) return std::nullopt;
|
||||
|
||||
Animation anim;
|
||||
animation::from_json(data[anim_name], anim);
|
||||
|
|
@ -269,6 +268,15 @@ namespace animation {
|
|||
return anim;
|
||||
}
|
||||
|
||||
Animation load(const std::string &file, const std::string &anim_name) {
|
||||
auto anim = maybe_load(file, anim_name);
|
||||
|
||||
dbc::check(anim != std::nullopt,
|
||||
$F("FAILED to load animation {} from file {}", anim_name, file));
|
||||
|
||||
return *anim;
|
||||
}
|
||||
|
||||
void Sequence::INVARIANT(const std::source_location location) {
|
||||
dbc::check(frames.size() == durations.size(),
|
||||
$F("frames.size={} doesn't match durations.size={}",
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ namespace animation {
|
|||
void motion(sf::View& view_out, sf::Vector2f pos, sf::Vector2f scale);
|
||||
};
|
||||
|
||||
std::optional<Animation> maybe_load(const std::string &file, const std::string &anim_name);
|
||||
Animation load(const std::string &file, const std::string &anim_name);
|
||||
|
||||
// BUG: brought over from animation to finish the refactor, but these may not be needed or maybe they go in system.cpp?
|
||||
|
|
|
|||
|
|
@ -18,17 +18,20 @@ namespace scene {
|
|||
bool flipped = config["flipped"];
|
||||
|
||||
// BUG: put the .json file to load as a default/optional arg
|
||||
auto anim = animation::load("./assets/animation.json", sprite_name);
|
||||
anim.play();
|
||||
auto anim = animation::maybe_load("./assets/animation.json", sprite_name);
|
||||
|
||||
anim.transform.flipped = flipped;
|
||||
if(anim) {
|
||||
// only start it if there's an animation set
|
||||
anim->play();
|
||||
anim->transform.flipped = flipped;
|
||||
}
|
||||
|
||||
std::string cell = config["cell"];
|
||||
std::string name = config["name"];
|
||||
|
||||
bool at_mid = config["at_mid"];
|
||||
|
||||
sf::Text text(*$ui.$font, "", 60);
|
||||
sf::Text text(*$gui.$font, "", 60);
|
||||
|
||||
return {name, st, anim, cell, {scale_x, scale_y}, {x, y}, at_mid, flipped, nullptr, text};
|
||||
}
|
||||
|
|
@ -55,12 +58,12 @@ namespace scene {
|
|||
}
|
||||
|
||||
void Engine::init() {
|
||||
$ui.position(0,0, BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT);
|
||||
$ui.set<guecs::Background>($ui.MAIN, {$ui.$parser, guecs::THEME.TRANSPARENT});
|
||||
auto& background = $ui.get<guecs::Background>($ui.MAIN);
|
||||
$gui.position(SCENE_VIEW_X, SCENE_VIEW_Y, SCENE_VIEW_WIDTH, SCENE_VIEW_HEIGHT);
|
||||
$gui.set<guecs::Background>($gui.MAIN, {$gui.$parser, guecs::THEME.TRANSPARENT});
|
||||
auto& background = $gui.get<guecs::Background>($gui.MAIN);
|
||||
background.set_sprite($scene.background, true);
|
||||
|
||||
$ui.layout($layout);
|
||||
$gui.layout($layout);
|
||||
|
||||
for(auto& actor : $actors) {
|
||||
actor.pos = position_sprite(actor.st, actor.cell,
|
||||
|
|
@ -71,6 +74,17 @@ namespace scene {
|
|||
fixture.pos = position_sprite(fixture.st, fixture.cell,
|
||||
fixture.scale, fixture.at_mid, fixture.pos.x, fixture.pos.y);
|
||||
}
|
||||
|
||||
if($gui.contains("text")) {
|
||||
auto text_id = $gui.entity("text");
|
||||
auto bg_color = guecs::THEME.DARK_DARK;
|
||||
bg_color.a = 100;
|
||||
// BUG: guecs should initialize anything added if it needs it
|
||||
$gui.set<guecs::Rectangle>(text_id, {0, bg_color});
|
||||
$gui.set<guecs::Text>(text_id, {L"", 55});
|
||||
}
|
||||
|
||||
$gui.init();
|
||||
}
|
||||
|
||||
void Engine::apply_effect(const std::string& actor, const std::string& shader) {
|
||||
|
|
@ -89,11 +103,11 @@ namespace scene {
|
|||
}
|
||||
|
||||
bool Engine::mouse(float x, float y, guecs::Modifiers mods) {
|
||||
return $ui.mouse(x, y, mods);
|
||||
return $gui.mouse(x, y, mods);
|
||||
}
|
||||
|
||||
void Engine::render(sf::RenderTexture& view) {
|
||||
$ui.render(view);
|
||||
$gui.render(view);
|
||||
|
||||
for(auto& fixture : $fixtures) {
|
||||
view.draw(*fixture.st.sprite, fixture.effect.get());
|
||||
|
|
@ -101,11 +115,11 @@ namespace scene {
|
|||
|
||||
for(auto& actor : $actors) {
|
||||
view.draw(*actor.st.sprite, actor.effect.get());
|
||||
if(actor.anim.playing) view.draw(actor.text);
|
||||
if(actor.anim && actor.anim->playing) view.draw(actor.text);
|
||||
}
|
||||
|
||||
$camera.render(view);
|
||||
if(DEBUG) $ui.debug_layout(view);
|
||||
if(DEBUG) $gui.debug_layout(view);
|
||||
}
|
||||
|
||||
Element& Engine::actor_config(const std::string& actor) {
|
||||
|
|
@ -121,20 +135,23 @@ namespace scene {
|
|||
|
||||
void Engine::animate_actor(const std::string& actor, const std::string& form) {
|
||||
auto& config = actor_config(actor);
|
||||
config.anim.set_form(form);
|
||||
|
||||
if(!config.anim.playing) {
|
||||
config.anim.play();
|
||||
if(!config.anim) return;
|
||||
|
||||
config.anim->set_form(form);
|
||||
|
||||
if(!config.anim->playing) {
|
||||
config.anim->play();
|
||||
}
|
||||
}
|
||||
|
||||
inline void this_is_stupid_refactor(std::vector<Element>& elements) {
|
||||
for(auto& element : elements) {
|
||||
if(element.anim.playing) {
|
||||
element.anim.update();
|
||||
element.anim.motion(*element.st.sprite, element.pos, element.scale);
|
||||
element.anim.apply(*element.st.sprite);
|
||||
if(element.effect != nullptr) element.anim.apply_effect(element.effect);
|
||||
if(element.anim && element.anim->playing) {
|
||||
element.anim->update();
|
||||
element.anim->motion(*element.st.sprite, element.pos, element.scale);
|
||||
element.anim->apply(*element.st.sprite);
|
||||
if(element.effect != nullptr) element.anim->apply_effect(element.effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -145,7 +162,7 @@ namespace scene {
|
|||
}
|
||||
|
||||
sf::Vector2f Engine::position_sprite(textures::SpriteTexture& st, const std::string& cell_name, sf::Vector2f scale, bool at_mid, float x_diff, float y_diff) {
|
||||
auto& cell = $ui.cell_for(cell_name);
|
||||
auto& cell = $gui.cell_for(cell_name);
|
||||
float x = float(at_mid ? cell.mid_x : cell.x);
|
||||
float y = float(at_mid ? cell.mid_y : cell.y);
|
||||
|
||||
|
|
@ -174,7 +191,10 @@ namespace scene {
|
|||
|
||||
void Engine::set_end_cb(std::function<void()> cb) {
|
||||
for(auto& actor : $actors) {
|
||||
actor.anim.onLoop = [&,cb](auto& seq, auto& tr) -> bool {
|
||||
// no animation set so no point doing the end
|
||||
if(!actor.anim) continue;
|
||||
|
||||
actor.anim->onLoop = [&,cb](auto& seq, auto& tr) -> bool {
|
||||
seq.current = tr.toggled ? seq.frame_count - 1 : 0;
|
||||
cb();
|
||||
actor.effect = nullptr;
|
||||
|
|
@ -183,6 +203,13 @@ namespace scene {
|
|||
}
|
||||
}
|
||||
|
||||
void Engine::set_text(const std::string& content) {
|
||||
if($gui.contains("text")) {
|
||||
auto el = $gui.get_if<guecs::Text>($gui.entity("text"));
|
||||
el->text->setString(guecs::to_wstring(content));
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::reset(sf::RenderTexture& view) {
|
||||
$camera.reset(view);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace scene {
|
|||
struct Element {
|
||||
std::string name;
|
||||
textures::SpriteTexture st;
|
||||
animation::Animation anim;
|
||||
std::optional<animation::Animation> anim;
|
||||
std::string cell;
|
||||
sf::Vector2f scale{1.0f, 1.0f};
|
||||
sf::Vector2f pos{0.0f, 0.0f};
|
||||
|
|
@ -29,13 +29,13 @@ namespace scene {
|
|||
|
||||
struct Engine {
|
||||
sf::Clock $clock;
|
||||
guecs::UI $ui;
|
||||
guecs::UI $gui;
|
||||
components::AnimatedScene& $scene;
|
||||
std::string $layout;
|
||||
std::unordered_map<std::string, int> $actor_name_ids;
|
||||
std::vector<Element> $fixtures;
|
||||
std::vector<Element> $actors;
|
||||
cinematic::Camera $camera{{BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT}, "scene"};
|
||||
cinematic::Camera $camera{{SCENE_VIEW_WIDTH, SCENE_VIEW_HEIGHT}, "scene"};
|
||||
|
||||
Engine(components::AnimatedScene& scene);
|
||||
|
||||
|
|
@ -44,6 +44,8 @@ namespace scene {
|
|||
void update();
|
||||
bool mouse(float x, float y, guecs::Modifiers mods);
|
||||
void attach_text(const std::string& actor, const std::string& text);
|
||||
nlohmann::json& buttons() { return $scene.buttons; };
|
||||
lel::Cell& button_cell() { return $gui.cell_for("buttons"); }
|
||||
Element config_scene_element(nlohmann::json& config, bool duped);
|
||||
|
||||
sf::Vector2f position_sprite(textures::SpriteTexture& st, const std::string& cell_name, sf::Vector2f scale, bool at_mid, float x_diff=0.0f, float y_diff=0.0f);
|
||||
|
|
@ -56,5 +58,6 @@ namespace scene {
|
|||
void zoom(float mid_x, float mid_y, const std::string& style, float scale);
|
||||
void reset(sf::RenderTexture& view);
|
||||
void set_end_cb(std::function<void()> cb);
|
||||
void set_text(const std::string& content);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ namespace gui {
|
|||
auto hp_gauge = $gui.entity("hp_gauge");
|
||||
$gui.set<Sprite>(hp_gauge, {"stone_doll_cursed"});
|
||||
$gui.set<Clickable>(hp_gauge,
|
||||
guecs::make_action(hp_gauge, game::Event::HP_STATUS, {}));
|
||||
guecs::make_action(hp_gauge, game::Event::HP_STATUS));
|
||||
}
|
||||
|
||||
$gui.init();
|
||||
|
|
|
|||
|
|
@ -1,18 +1,22 @@
|
|||
#include "gui/guecstra.hpp"
|
||||
#include "game/level.hpp"
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
#include "dbc.hpp"
|
||||
|
||||
namespace guecs {
|
||||
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event) {
|
||||
return {[&, gui_id, event](auto){
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event, const std::source_location location) {
|
||||
return {[&, gui_id, event, location](guecs::Modifiers mods){
|
||||
auto world = GameDB::current_world();
|
||||
dbc::log($F("SENDING EVENT: {}: {}", magic_enum::enum_name(event), mods.to_string()), location);
|
||||
world->send<game::Event>(event, gui_id, {});
|
||||
}};
|
||||
}
|
||||
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event, std::any data) {
|
||||
return {[&, event, data](auto){
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event, std::any data, const std::source_location location) {
|
||||
return {[&, event, data, location](auto){
|
||||
auto world = GameDB::current_world();
|
||||
dbc::log($F("SENDING EVENT: {}", magic_enum::enum_name(event)), location);
|
||||
world->send<game::Event>(event, gui_id, data);
|
||||
}};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,10 @@
|
|||
#include "graphics/textures.hpp"
|
||||
|
||||
namespace guecs {
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event);
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event, std::any data);
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event,
|
||||
const std::source_location location = std::source_location::current());
|
||||
Clickable make_action(guecs::Entity gui_id, game::Event event, std::any data,
|
||||
const std::source_location location = std::source_location::current());
|
||||
|
||||
struct GrabSource {
|
||||
DinkyECS::Entity world_entity;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ namespace gui {
|
|||
auto area = gui.entity(name);
|
||||
|
||||
gui.set<Clickable>(area, {
|
||||
[&](auto) {
|
||||
[=](auto) {
|
||||
auto world = GameDB::current_world();
|
||||
world->send<game::Event>(game::Event::AIM_CLICK, area, {});
|
||||
}
|
||||
|
|
|
|||
78
src/gui/scene_ui.cpp
Normal file
78
src/gui/scene_ui.cpp
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
#include "gui/scene_ui.hpp"
|
||||
#include "game/config.hpp"
|
||||
#include "events.hpp"
|
||||
#include "gui/guecstra.hpp"
|
||||
#include <iostream>
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
namespace gui {
|
||||
void SceneUI::init() {
|
||||
$view_sprite.setPosition({0,0});
|
||||
$scene.init();
|
||||
create_buttons($scene.buttons());
|
||||
}
|
||||
|
||||
void SceneUI::create_buttons(nlohmann::json& buttons) {
|
||||
// buttons are optional
|
||||
if(buttons.size() == 0) return;
|
||||
|
||||
// alright have buttons
|
||||
has_buttons = true;
|
||||
|
||||
std::string layout{};
|
||||
auto& actions = buttons["actions"];
|
||||
|
||||
for(auto& line : buttons["layout"]) {
|
||||
layout.append(line);
|
||||
}
|
||||
|
||||
auto& button_cell = $scene.button_cell();
|
||||
|
||||
$gui.position(button_cell.x, button_cell.y, button_cell.w, button_cell.h);
|
||||
$gui.layout(layout);
|
||||
|
||||
for(auto& [name, cell] : $gui.cells()) {
|
||||
auto ui_id = $gui.entity(name);
|
||||
$gui.set<guecs::Text>(ui_id, {guecs::to_wstring(name), 40});
|
||||
$gui.set<guecs::Rectangle>(ui_id, {5, guecs::THEME.DARK_MID});
|
||||
$gui.set<guecs::Effect>(ui_id, {});
|
||||
|
||||
if(actions.contains(name)) {
|
||||
auto event_id = actions[name];
|
||||
$gui.set<guecs::Clickable>(ui_id, guecs::make_action(ui_id, event_id));
|
||||
}
|
||||
}
|
||||
|
||||
$gui.init();
|
||||
}
|
||||
|
||||
void SceneUI::set_text(const std::string& text) {
|
||||
$scene.set_text(text);
|
||||
}
|
||||
|
||||
void SceneUI::render(sf::RenderTarget &target) {
|
||||
$scene.render($view_texture);
|
||||
target.draw($view_sprite);
|
||||
|
||||
if(has_buttons) {
|
||||
$gui.render(target);
|
||||
if(DEBUG) $gui.debug_layout(target);
|
||||
}
|
||||
}
|
||||
|
||||
void SceneUI::update() {
|
||||
$scene.update();
|
||||
}
|
||||
|
||||
bool SceneUI::mouse(float x, float y, guecs::Modifiers mods) {
|
||||
$scene.mouse(x, y, mods);
|
||||
$gui.mouse(x, y, mods);
|
||||
return false;
|
||||
}
|
||||
|
||||
AnimatedScene SceneUI::load_scene(const std::string& name) {
|
||||
auto scene_config = settings::get("scenes")[name];
|
||||
return components::convert<AnimatedScene>(scene_config);
|
||||
}
|
||||
}
|
||||
27
src/gui/scene_ui.hpp
Normal file
27
src/gui/scene_ui.hpp
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include <guecs/ui.hpp>
|
||||
#include "graphics/scene.hpp"
|
||||
|
||||
namespace gui {
|
||||
using namespace components;
|
||||
|
||||
class SceneUI {
|
||||
public:
|
||||
std::string name;
|
||||
sf::RenderTexture $view_texture{{SCENE_VIEW_WIDTH, SCENE_VIEW_HEIGHT}};
|
||||
sf::Sprite $view_sprite{$view_texture.getTexture()};
|
||||
AnimatedScene $scene_data{load_scene(name)};
|
||||
scene::Engine $scene{$scene_data};
|
||||
bool has_buttons = false;
|
||||
guecs::UI $gui;
|
||||
|
||||
AnimatedScene load_scene(const std::string& name);
|
||||
void create_buttons(nlohmann::json& buttons);
|
||||
|
||||
void init();
|
||||
void render(sf::RenderTarget &target);
|
||||
void update();
|
||||
bool mouse(float x, float y, guecs::Modifiers mods);
|
||||
void set_text(const std::string& text);
|
||||
};
|
||||
}
|
||||
|
|
@ -27,6 +27,7 @@ sources = files(
|
|||
'gui/overlay_ui.cpp',
|
||||
'gui/ritual_ui.cpp',
|
||||
'gui/status_ui.cpp',
|
||||
'gui/scene_ui.cpp',
|
||||
|
||||
# storyboard
|
||||
'storyboard/ui.cpp',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue