First cut of pulling out the relevant parts of my original game to make a little framework.
This commit is contained in:
commit
6a0c9e8d46
177 changed files with 18197 additions and 0 deletions
189
src/graphics/scene.cpp
Normal file
189
src/graphics/scene.cpp
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
#include "graphics/scene.hpp"
|
||||
#include "graphics/animation.hpp"
|
||||
#include "graphics/shaders.hpp"
|
||||
#include <fmt/core.h>
|
||||
#include "dbc.hpp"
|
||||
|
||||
const bool DEBUG=false;
|
||||
|
||||
namespace scene {
|
||||
Element Engine::config_scene_element(nlohmann::json& config, bool duped) {
|
||||
std::string sprite_name = config["sprite"];
|
||||
auto st = textures::get_sprite(sprite_name, duped);
|
||||
|
||||
float scale_x = config["scale_x"];
|
||||
float scale_y = config["scale_y"];
|
||||
float x = config["x"];
|
||||
float y = config["y"];
|
||||
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();
|
||||
|
||||
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);
|
||||
|
||||
return {name, st, anim, cell, {scale_x, scale_y}, {x, y}, at_mid, flipped, nullptr, text};
|
||||
}
|
||||
|
||||
Engine::Engine(components::AnimatedScene& scene) :
|
||||
$scene(scene)
|
||||
{
|
||||
for(auto& config : $scene.actors) {
|
||||
auto element = config_scene_element(config, false);
|
||||
dbc::check(!$actor_name_ids.contains(element.name),
|
||||
$F("actors key {} already exists", element.name));
|
||||
$actors.push_back(element);
|
||||
$actor_name_ids.try_emplace(element.name, $actors.size() - 1);
|
||||
}
|
||||
|
||||
for(auto& fixture : $scene.fixtures) {
|
||||
auto element = config_scene_element(fixture, true);
|
||||
$fixtures.push_back(element);
|
||||
}
|
||||
|
||||
for(auto& line : $scene.layout) {
|
||||
$layout.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
background.set_sprite($scene.background, true);
|
||||
|
||||
$ui.layout($layout);
|
||||
|
||||
for(auto& actor : $actors) {
|
||||
actor.pos = position_sprite(actor.st, actor.cell,
|
||||
actor.scale, actor.at_mid, actor.pos.x, actor.pos.y);
|
||||
}
|
||||
|
||||
for(auto& fixture : $fixtures) {
|
||||
fixture.pos = position_sprite(fixture.st, fixture.cell,
|
||||
fixture.scale, fixture.at_mid, fixture.pos.x, fixture.pos.y);
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::apply_effect(const std::string& actor, const std::string& shader) {
|
||||
auto& element = actor_config(actor);
|
||||
element.effect = shaders::get(shader);
|
||||
}
|
||||
|
||||
void Engine::attach_text(const std::string& actor, const std::string& text) {
|
||||
auto& element = actor_config(actor);
|
||||
element.text.setPosition(element.pos);
|
||||
element.text.setScale(element.scale);
|
||||
element.text.setFillColor(sf::Color::Red);
|
||||
element.text.setOutlineThickness(2.0f);
|
||||
element.text.setOutlineColor(sf::Color::Black);
|
||||
element.text.setString(text);
|
||||
}
|
||||
|
||||
bool Engine::mouse(float x, float y, guecs::Modifiers mods) {
|
||||
return $ui.mouse(x, y, mods);
|
||||
}
|
||||
|
||||
void Engine::render(sf::RenderTexture& view) {
|
||||
$ui.render(view);
|
||||
|
||||
for(auto& fixture : $fixtures) {
|
||||
view.draw(*fixture.st.sprite, fixture.effect.get());
|
||||
}
|
||||
|
||||
for(auto& actor : $actors) {
|
||||
view.draw(*actor.st.sprite, actor.effect.get());
|
||||
if(actor.anim.playing) view.draw(actor.text);
|
||||
}
|
||||
|
||||
$camera.render(view);
|
||||
if(DEBUG) $ui.debug_layout(view);
|
||||
}
|
||||
|
||||
Element& Engine::actor_config(const std::string& actor) {
|
||||
dbc::check($actor_name_ids.contains(actor), $F("scene does not contain actor {}", actor));
|
||||
return $actors.at($actor_name_ids.at(actor));
|
||||
}
|
||||
|
||||
void Engine::move_actor(const std::string& actor, const std::string& cell_name) {
|
||||
auto& config = actor_config(actor);
|
||||
config.cell = cell_name;
|
||||
config.pos = position_sprite(config.st, config.cell, config.scale, config.at_mid);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::update() {
|
||||
this_is_stupid_refactor($fixtures);
|
||||
this_is_stupid_refactor($actors);
|
||||
}
|
||||
|
||||
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);
|
||||
float x = float(at_mid ? cell.mid_x : cell.x);
|
||||
float y = float(at_mid ? cell.mid_y : cell.y);
|
||||
|
||||
sf::Vector2f pos{x + x_diff, y + y_diff};
|
||||
st.sprite->setPosition(pos);
|
||||
st.sprite->setScale(scale);
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
void Engine::zoom(float mid_x, float mid_y, const std::string& style, float scale) {
|
||||
$camera.style(style);
|
||||
$camera.scale(scale);
|
||||
$camera.move(mid_x, mid_y);
|
||||
$camera.play();
|
||||
}
|
||||
|
||||
void Engine::zoom(const std::string &actor, const std::string& style, float scale) {
|
||||
auto& config = actor_config(actor);
|
||||
auto bounds = config.st.sprite->getGlobalBounds();
|
||||
float mid_x = config.pos.x + bounds.size.x / 2.0f;
|
||||
float mid_y = config.pos.y + bounds.size.y / 2.0f;
|
||||
|
||||
zoom(mid_x, mid_y, style, scale);
|
||||
}
|
||||
|
||||
void Engine::set_end_cb(std::function<void()> cb) {
|
||||
for(auto& actor : $actors) {
|
||||
actor.anim.onLoop = [&,cb](auto& seq, auto& tr) -> bool {
|
||||
seq.current = tr.toggled ? seq.frame_count - 1 : 0;
|
||||
cb();
|
||||
actor.effect = nullptr;
|
||||
return tr.looped;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void Engine::reset(sf::RenderTexture& view) {
|
||||
$camera.reset(view);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue