Can now export the time code/actions from Reaper as json data and the storyboard will play them.
This commit is contained in:
parent
b5280b4a4d
commit
c486db5a57
6 changed files with 51 additions and 16 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
{
|
{
|
||||||
"sounds": {
|
"sounds": {
|
||||||
|
"epic_theme": "assets/sounds/epic_theme.mp3",
|
||||||
"Sword_Hit_1": "assets/sounds/Creature_Sounds-Sword_Hit_1.ogg",
|
"Sword_Hit_1": "assets/sounds/Creature_Sounds-Sword_Hit_1.ogg",
|
||||||
"Evil_Eye_Sound_1": "assets/sounds/Creature_Sounds-Evil_Eye_Sound_1.ogg",
|
"Evil_Eye_Sound_1": "assets/sounds/Creature_Sounds-Evil_Eye_Sound_1.ogg",
|
||||||
"Evil_Eye_Sound_2": "assets/sounds/Creature_Sounds-Evil_Eye_Sound_2.ogg",
|
"Evil_Eye_Sound_2": "assets/sounds/Creature_Sounds-Evil_Eye_Sound_2.ogg",
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ namespace components {
|
||||||
void init() {
|
void init() {
|
||||||
if(!MAP_configured) {
|
if(!MAP_configured) {
|
||||||
components::enroll<AnimatedScene>(MAP);
|
components::enroll<AnimatedScene>(MAP);
|
||||||
|
components::enroll<Storyboard>(MAP);
|
||||||
components::enroll<Combat>(MAP);
|
components::enroll<Combat>(MAP);
|
||||||
components::enroll<Position>(MAP);
|
components::enroll<Position>(MAP);
|
||||||
components::enroll<Curative>(MAP);
|
components::enroll<Curative>(MAP);
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ namespace components {
|
||||||
settings::Config devices;
|
settings::Config devices;
|
||||||
settings::Config bosses;
|
settings::Config bosses;
|
||||||
settings::Config rituals;
|
settings::Config rituals;
|
||||||
|
settings::Config stories;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Personality {
|
struct Personality {
|
||||||
|
|
@ -90,6 +91,13 @@ namespace components {
|
||||||
json fixtures;
|
json fixtures;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Storyboard {
|
||||||
|
std::string image;
|
||||||
|
std::string audio;
|
||||||
|
std::vector<std::string> layout;
|
||||||
|
json beats;
|
||||||
|
};
|
||||||
|
|
||||||
struct Combat {
|
struct Combat {
|
||||||
int hp;
|
int hp;
|
||||||
int max_hp;
|
int max_hp;
|
||||||
|
|
@ -170,6 +178,7 @@ namespace components {
|
||||||
ENROLL_COMPONENT(Motion, dx, dy, random);
|
ENROLL_COMPONENT(Motion, dx, dy, random);
|
||||||
ENROLL_COMPONENT(Combat, hp, max_hp, damage, dead);
|
ENROLL_COMPONENT(Combat, hp, max_hp, damage, dead);
|
||||||
ENROLL_COMPONENT(Device, config, events);
|
ENROLL_COMPONENT(Device, config, events);
|
||||||
|
ENROLL_COMPONENT(Storyboard, image, audio, layout, beats);
|
||||||
ENROLL_COMPONENT(Animation, min_x, min_y,
|
ENROLL_COMPONENT(Animation, min_x, min_y,
|
||||||
max_x, max_y, simple, frames,
|
max_x, max_y, simple, frames,
|
||||||
speed, easing, motion, ease_rate,
|
speed, easing, motion, ease_rate,
|
||||||
|
|
|
||||||
|
|
@ -123,7 +123,8 @@ namespace GameDB {
|
||||||
settings::get("tiles"),
|
settings::get("tiles"),
|
||||||
settings::get("devices"),
|
settings::get("devices"),
|
||||||
settings::get("bosses"),
|
settings::get("bosses"),
|
||||||
settings::get("rituals")
|
settings::get("rituals"),
|
||||||
|
settings::get("stories")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,11 @@
|
||||||
#include "components.hpp"
|
#include "components.hpp"
|
||||||
#include "animation.hpp"
|
#include "animation.hpp"
|
||||||
#include "sound.hpp"
|
#include "sound.hpp"
|
||||||
|
#include "config.hpp"
|
||||||
|
#include <chrono>
|
||||||
|
#include <iostream>
|
||||||
|
#include <locale>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
namespace storyboard {
|
namespace storyboard {
|
||||||
UI::UI() :
|
UI::UI() :
|
||||||
|
|
@ -11,25 +16,26 @@ namespace storyboard {
|
||||||
{
|
{
|
||||||
$view_sprite.setPosition({0, 0});
|
$view_sprite.setPosition({0, 0});
|
||||||
$camera.style("pan");
|
$camera.style("pan");
|
||||||
sound::play("ambient_1", true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::init() {
|
void UI::init() {
|
||||||
|
auto config = settings::get("stories");
|
||||||
|
$story = components::convert<components::Storyboard>(config["rat_king"]);
|
||||||
|
|
||||||
$ui.position(0,0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
$ui.position(0,0, SCREEN_WIDTH, SCREEN_HEIGHT);
|
||||||
|
|
||||||
$ui.set<guecs::Background>($ui.MAIN, {$ui.$parser, guecs::THEME.TRANSPARENT});
|
$ui.set<guecs::Background>($ui.MAIN, {$ui.$parser, guecs::THEME.TRANSPARENT});
|
||||||
|
|
||||||
auto& background = $ui.get<guecs::Background>($ui.MAIN);
|
auto& background = $ui.get<guecs::Background>($ui.MAIN);
|
||||||
background.set_sprite("test_story", true);
|
background.set_sprite($story.image, true);
|
||||||
|
|
||||||
$ui.layout(
|
for(auto& line : $story.layout) {
|
||||||
"[a|b|c]"
|
$layout.append(line);
|
||||||
"[*%(200,100)d|_|f]"
|
|
||||||
"[g|h|i]");
|
|
||||||
|
|
||||||
for(auto& [key, value] : $ui.$parser.cells) {
|
|
||||||
$cell_names.push_back(key);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$ui.layout($layout);
|
||||||
|
|
||||||
|
sound::play($story.audio, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::render(sf::RenderWindow &window) {
|
void UI::render(sf::RenderWindow &window) {
|
||||||
|
|
@ -44,10 +50,23 @@ namespace storyboard {
|
||||||
window.draw($view_sprite);
|
window.draw($view_sprite);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UI::track_audio() {
|
sf::Time parse_time_code(const std::string& time) {
|
||||||
int track_head = int($audio->getPlayingOffset().asSeconds());
|
std::chrono::seconds out{};
|
||||||
|
|
||||||
if(track_head % 3 == 0) {
|
std::istringstream is{time};
|
||||||
|
is >> std::chrono::parse("%M:%S", out);
|
||||||
|
dbc::check(!is.fail(), fmt::format("Time parse failed: {}", time));
|
||||||
|
|
||||||
|
return sf::Time(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UI::track_audio() {
|
||||||
|
auto& beat = $story.beats[cur_beat % $story.beats.size()];
|
||||||
|
|
||||||
|
auto track_head = $audio->getPlayingOffset();
|
||||||
|
auto next_beat = parse_time_code(beat[0]);
|
||||||
|
|
||||||
|
if(track_head >= next_beat) {
|
||||||
if($moving) return;
|
if($moving) return;
|
||||||
$moving = true; // prevent motion until next tick
|
$moving = true; // prevent motion until next tick
|
||||||
|
|
||||||
|
|
@ -55,10 +74,12 @@ namespace storyboard {
|
||||||
auto& cell = $ui.cell_for($zoom_target);
|
auto& cell = $ui.cell_for($zoom_target);
|
||||||
$camera.position(cell.mid_x, cell.mid_y);
|
$camera.position(cell.mid_x, cell.mid_y);
|
||||||
|
|
||||||
|
$zoom_target = beat[1];
|
||||||
|
$camera.style(beat[2]);
|
||||||
// get the new target from the cell names
|
// get the new target from the cell names
|
||||||
$zoom_target = $cell_names.at(track_head % $cell_names.size());
|
|
||||||
zoom($zoom_target);
|
zoom($zoom_target);
|
||||||
$camera.play();
|
$camera.play();
|
||||||
|
cur_beat++;
|
||||||
} else {
|
} else {
|
||||||
$moving = false;
|
$moving = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,10 @@ namespace storyboard {
|
||||||
cinematic::Camera $camera;
|
cinematic::Camera $camera;
|
||||||
std::shared_ptr<sf::Sound> $audio;
|
std::shared_ptr<sf::Sound> $audio;
|
||||||
std::string $zoom_target = "a";
|
std::string $zoom_target = "a";
|
||||||
int $moving = false;
|
bool $moving = false;
|
||||||
std::vector<std::string> $cell_names;
|
int cur_beat = 0;
|
||||||
|
components::Storyboard $story;
|
||||||
|
std::string $layout;
|
||||||
|
|
||||||
UI();
|
UI();
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue