Now have a simple storyboard system that can display an image and move with the camera to different cells.

This commit is contained in:
Zed A. Shaw 2025-11-04 00:20:49 -05:00
parent 068eeeecd1
commit 4bda2ee01c
10 changed files with 118 additions and 40 deletions

View file

@ -73,3 +73,6 @@ money:
arena:
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args ./builddir/arena
story:
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args ./builddir/storyboard

View file

@ -288,23 +288,5 @@
"toggled": false,
"flipped": false,
"looped": false
},
"test_zoom": {
"_type": "Animation",
"easing": 2,
"motion": 7,
"ease_rate": 0.05,
"min_x": 0,
"min_y": 0,
"max_x": 150.0,
"max_y": 0.0,
"simple": true,
"frames": 1,
"speed": 0.01,
"scaled": false,
"stationary": true,
"toggled": false,
"flipped": false,
"looped": false
}
}

View file

@ -274,6 +274,11 @@
{"path": "assets/bossfights/test_thirds.png",
"frame_width": 1656,
"frame_height": 1080
},
"test_story":
{"path": "assets/story/test_storyboard.png",
"frame_width": 1280,
"frame_height": 720
}
},
"worldgen": {

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -86,8 +86,6 @@ namespace boss {
$ui.status(L"PLAYER TURN");
const std::string& player_pos = run % 10 < 5 ? "player1" : "player2";
$ui.move_actor("player", player_pos);
$ui.zoom(player_pos);
$ui.$camera.play();
int attack_id = std::any_cast<int>(data);
boss::System::combat(attack_id);
state(State::PLAYER_TURN);
@ -110,7 +108,6 @@ namespace boss {
$ui.status(L"BOSS TURN");
const std::string &boss_at = run % 10 < 5 ? "boss5" : "boss6";
$ui.move_actor("boss", boss_at);
$ui.zoom("");
$ui.animate_actor("boss");
int attack_id = std::any_cast<int>(data);
boss::System::combat(attack_id);

View file

@ -45,10 +45,6 @@ namespace boss {
$actions.render(window);
$combat_ui.render(window);
if($camera.playing()) {
zoom("player2");
}
$arena.render($view_texture);
$view_texture.display();
window.draw($view_sprite);
@ -77,17 +73,13 @@ namespace boss {
}
void UI::zoom(const std::string &cell_name) {
if(cell_name == "") {
sf::View zoom{{BOSS_VIEW_WIDTH/2,BOSS_VIEW_HEIGHT/2}, {BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT}};
$view_texture.setView(zoom);
} else if($camera.playing()) {
auto& cell = $arena.$ui.cell_for(cell_name);
auto& cell = $arena.$ui.cell_for(cell_name);
$camera.resize({BOSS_VIEW_WIDTH/2, BOSS_VIEW_HEIGHT/2});
$camera.move($view_texture,
{float(cell.x/2), float(cell.y/2)});
}
$camera.resize({BOSS_VIEW_WIDTH/2, BOSS_VIEW_HEIGHT/2});
$camera.move($view_texture,
{float(cell.x/2), float(cell.y/2)});
$view_sprite.setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
// BUG: do I need this?
// $view_sprite.setPosition({BOSS_VIEW_X, BOSS_VIEW_Y});
}
}

View file

@ -121,10 +121,10 @@ sources = [
'rituals.cpp',
'scene.cpp',
'shaders.cpp',
'shiterator.hpp',
'sound.cpp',
'spatialmap.cpp',
'stats.cpp',
'storyboard/ui.cpp',
'systems.cpp',
'textures.cpp',
'worldbuilder.cpp',

69
storyboard/ui.cpp Normal file
View file

@ -0,0 +1,69 @@
#include "storyboard/ui.hpp"
#include "components.hpp"
#include "animation.hpp"
namespace storyboard {
UI::UI() :
$view_texture({SCREEN_WIDTH, SCREEN_HEIGHT}),
$view_sprite($view_texture.getTexture())
{
$view_sprite.setPosition({0, 0});
$camera.style("bounce");
}
void UI::init() {
$ui.position(0,0, SCREEN_WIDTH, SCREEN_HEIGHT);
$ui.set<guecs::Background>($ui.MAIN, {$ui.$parser, guecs::THEME.TRANSPARENT});
auto& background = $ui.get<guecs::Background>($ui.MAIN);
background.set_sprite("test_story", true);
$ui.layout(
"[a|b|c]"
"[*%(200,100)d|_|f]"
"[g|h|i]");
}
void UI::render(sf::RenderWindow &window) {
if($camera.playing()) {
zoom($zoom_target);
}
$ui.render($view_texture);
$ui.debug_layout($view_texture);
$view_texture.display();
window.draw($view_sprite);
}
bool UI::mouse(float x, float y, guecs::Modifiers mods) {
if(zoomed) {
zoomed = false;
reset();
} else {
zoomed = true;
auto target = $ui.$parser.hit(x, y);
$zoom_target = *target;
zoom($zoom_target);
$camera.play();
}
return $ui.mouse(x, y, mods);
}
void UI::zoom(const std::string &cell_name) {
auto& cell = $ui.cell_for(cell_name);
$camera.resize({float(cell.w), float(cell.h)});
$camera.move($view_texture,
{float(cell.mid_x), float(cell.mid_y)});
}
void UI::reset() {
sf::FloatRect where{{0,0},{SCREEN_WIDTH, SCREEN_HEIGHT}};
sf::View view{where};
$view_texture.setView(view);
}
}

25
storyboard/ui.hpp Normal file
View file

@ -0,0 +1,25 @@
#pragma once
#include "constants.hpp"
#include <guecs/ui.hpp>
#include "camera.hpp"
namespace storyboard {
struct UI {
guecs::UI $ui;
sf::RenderTexture $view_texture;
sf::Sprite $view_sprite;
cinematic::Camera $camera;
std::string $zoom_target;
bool zoomed = false;
UI();
void init();
void render(sf::RenderWindow &window);
bool mouse(float x, float y, guecs::Modifiers mods);
void zoom(const std::string &cell_name);
void reset();
};
}

View file

@ -1,18 +1,15 @@
#include "gui/fsm.hpp"
#include "textures.hpp"
#include "sound.hpp"
#include "autowalker.hpp"
#include "ai.hpp"
#include "animation.hpp"
#include <iostream>
#include "shaders.hpp"
#include "backend.hpp"
#include "game_level.hpp"
#include "gui/fsm_events.hpp"
#include "events.hpp"
#include "constants.hpp"
#include "gui/event_router.hpp"
#include "camera.hpp"
#include "storyboard/ui.hpp"
int main(int, char*[]) {
components::init();
@ -28,14 +25,22 @@ int main(int, char*[]) {
gui::routing::Router router;
storyboard::UI main;
main.init();
while(true) {
while(const auto ev = window.pollEvent()) {
auto gui_ev = router.process_event(ev);
auto mouse_pos = window.mapPixelToCoords(router.position);
if(gui_ev == gui::Event::QUIT) {
return 0;
} else if(gui_ev == gui::Event::MOUSE_CLICK) {
main.mouse(mouse_pos.x, mouse_pos.y, guecs::NO_MODS);
}
}
main.render(window);
window.display();
}