diff --git a/assets/animate2.json b/assets/animate2.json index 16f632e..a48d27f 100644 --- a/assets/animate2.json +++ b/assets/animate2.json @@ -8,7 +8,7 @@ "sequences": { "idle": {"frames": [0], "durations": [47] }, "hurt": {"frames": [0, 1], "durations": [5, 57] }, - "attack": {"frames": [0, 1, 0, 1], "durations": [35, 15, 5, 50] } + "attack": {"frames": [0, 1], "durations": [30, 15] } }, "transforms": { "rushing": { @@ -58,7 +58,7 @@ }, "sounds": { "idle": [], - "attack": [[0, "Sword_Hit_1"], [1, "Marmot_Scream_1"]], + "attack": [[0, "Sword_Hit_1"], [1, "Sword_Hit_1"]], "hurt": [[1, "Marmot_Scream_1"]] } }, diff --git a/assets/cameras.json b/assets/cameras.json index 728b3d7..8ea577f 100644 --- a/assets/cameras.json +++ b/assets/cameras.json @@ -1,5 +1,5 @@ { - "cameras": { + "scene": { "sheet": { "frames": 1, "frame_width": 1024, @@ -80,5 +80,84 @@ "shake": [], "bounce": [] } + }, + "story": { + "sheet": { + "frames": 1, + "frame_width": 1024, + "frame_height": 768 + }, + "sequences": {}, + "transforms": { + "pan": { + "min_x": 0.0, + "min_y": 0.0, + "max_x": 0.0, + "max_y": 0.0, + "flipped": false, + "scaled": false, + "toggled": false, + "looped": false, + "easing": "linear", + "relative": false, + "motion": "move_slide" + }, + "shake": { + "min_x": -10.0, + "min_y": -10.0, + "max_x": 10.0, + "max_y": 10.0, + "flipped": false, + "scaled": false, + "toggled": false, + "looped": false, + "relative": true, + "easing": "normal_dist", + "motion": "move_shake" + }, + "dolly": { + "min_x": 0.8, + "min_y": 0.8, + "max_x": 1.0, + "max_y": 1.0, + "flipped": false, + "scaled": false, + "toggled": false, + "looped": false, + "easing": "sine", + "relative": true, + "motion": "move_rush" + }, + "bounce": { + "min_x": 0, + "min_y": -20, + "max_x": 0, + "max_y": 0, + "flipped": false, + "scaled": false, + "toggled": false, + "looped": false, + "relative": true, + "easing": "in_out_back", + "motion": "move_bounce" + }, + "pause": { + "min_x": 0, + "min_y": 0, + "max_x": 0, + "max_y": 0, + "flipped": false, + "scaled": false, + "toggled": false, + "looped": false, + "relative": false, + "easing": "none", + "motion": "move_none" + } + }, + "forms": {}, + "sounds": { + "idle": [] + } } } diff --git a/assets/stories.json b/assets/stories.json index c058343..4ceea23 100644 --- a/assets/stories.json +++ b/assets/stories.json @@ -10,8 +10,8 @@ ], "beats": [ ["00:00", "a","pan"], - ["00:01", "a","pan"], - ["00:02", "b","pan"], + ["00:01", "a","shake"], + ["00:02", "a","pause"], ["00:03", "g","pan"], ["00:04", "h","pan"], ["00:05", "h","bounce"], diff --git a/camera.cpp b/camera.cpp index 799e264..4f18106 100644 --- a/camera.cpp +++ b/camera.cpp @@ -17,15 +17,20 @@ namespace cinematic { void init() { if(!initialized) { + // BUG: it should be that you give a camera to load by name, not just one for all cameras auto data = settings::get("cameras"); - auto anim = components::convert(data["cameras"]); - MGR.animations.try_emplace("main", anim); + + for(auto [key, value] : data.json().items()) { + auto anim = components::convert(value); + MGR.animations.try_emplace(key, anim); + } + initialized = true; } } - Camera::Camera(sf::Vector2f size) : - anim(MGR.animations.at("main")), + Camera::Camera(sf::Vector2f size, const std::string &name) : + anim(MGR.animations.at(name)), size(size), base_size(size), aimed_at{size.x/2, size.y/2}, @@ -33,6 +38,8 @@ namespace cinematic { camera_bounds{{0,0}, size}, view{aimed_at, size} { + anim.sheet.frame_width = base_size.x; + anim.sheet.frame_height = base_size.y; } void Camera::update_camera_bounds(sf::Vector2f size) { diff --git a/camera.hpp b/camera.hpp index 3cf8834..f63fce3 100644 --- a/camera.hpp +++ b/camera.hpp @@ -13,7 +13,7 @@ namespace cinematic { sf::FloatRect camera_bounds{{0,0},{SCREEN_WIDTH, SCREEN_HEIGHT}}; sf::View view; - Camera(sf::Vector2f base_size); + Camera(sf::Vector2f size, const std::string &name); void resize(float width); void scale(float ratio); diff --git a/components.hpp b/components.hpp index b265319..9f33b95 100644 --- a/components.hpp +++ b/components.hpp @@ -13,6 +13,7 @@ #include "easings.hpp" #include "json_mods.hpp" #include "goap.hpp" +#include namespace combat { enum class BattleHostState; @@ -106,7 +107,7 @@ namespace components { std::string image; std::string audio; std::vector layout; - json beats; + std::vector> beats; }; struct Combat { diff --git a/scene.hpp b/scene.hpp index 32e7557..4a7b895 100644 --- a/scene.hpp +++ b/scene.hpp @@ -35,7 +35,7 @@ namespace scene { std::unordered_map $actor_name_ids; std::vector $fixtures; std::vector $actors; - cinematic::Camera $camera{{BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT}}; + cinematic::Camera $camera{{BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT}, "scene"}; Engine(components::AnimatedScene& scene); diff --git a/storyboard/ui.cpp b/storyboard/ui.cpp index bf9318a..a69080c 100644 --- a/storyboard/ui.cpp +++ b/storyboard/ui.cpp @@ -17,6 +17,20 @@ namespace storyboard { auto config = settings::get("stories"); $story = components::convert(config[story_name]); $audio = sound::get_sound_pair($story.audio).sound; + config_camera($camera); + } + + void UI::config_camera(cinematic::Camera &camera) { + camera.anim.sequences.clear(); + camera.anim.forms.clear(); + + for(auto& [timecode, cell, transform] : $story.beats) { + animate2::Sequence seq{.frames={0}, .durations={60}}; + camera.anim.sequences.try_emplace(timecode, seq); + + animate2::Form form{timecode, transform}; + camera.anim.forms.try_emplace(timecode, form); + } } void UI::init() { @@ -66,20 +80,22 @@ namespace storyboard { } void UI::track_audio() { - auto& beat = $story.beats[cur_beat % $story.beats.size()]; + auto& [timecode, cell_name, form] = $story.beats[cur_beat % $story.beats.size()]; auto track_head = $audio->getPlayingOffset(); - auto next_beat = parse_time_code(beat[0]); + + auto next_beat = parse_time_code(timecode); if(track_head >= next_beat) { if($moving) return; $moving = true; // prevent motion until next tick // get the original zoom target as from - auto& cell = $ui.cell_for($zoom_target); - $camera.position(cell.mid_x, cell.mid_y); + auto& from_cell = $ui.cell_for($zoom_target); + $camera.position(from_cell.mid_x, from_cell.mid_y); + + $zoom_target = cell_name; + $camera.style(timecode); - $zoom_target = beat[1]; - $camera.style(beat[2]); // get the new target from the cell names zoom($zoom_target); $camera.play(); diff --git a/storyboard/ui.hpp b/storyboard/ui.hpp index 8737dea..e801ef8 100644 --- a/storyboard/ui.hpp +++ b/storyboard/ui.hpp @@ -11,7 +11,7 @@ namespace storyboard { guecs::UI $ui; sf::RenderTexture $view_texture; sf::Sprite $view_sprite; - cinematic::Camera $camera{{SCREEN_WIDTH, SCREEN_HEIGHT}}; + cinematic::Camera $camera{{SCREEN_WIDTH, SCREEN_HEIGHT}, "story"}; std::shared_ptr $audio; std::string $zoom_target = "a"; bool $moving = false; @@ -29,6 +29,7 @@ namespace storyboard { void reset(); void track_audio(); bool playing(); + void config_camera(cinematic::Camera &camera); }; }