From 51bb74e2d705f4fc074363b9d2afc7d3de729767 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Thu, 1 Jan 2026 12:59:39 -0500 Subject: [PATCH] Better working camera that is constrained in the bounds, but the animations don't follow the bounding. --- boss/fight.cpp | 1 + boss/ui.cpp | 8 +++++- boss/ui.hpp | 1 + camera.cpp | 63 ++++++++++++++++++++++++++++++++++++++--------- camera.hpp | 10 +++++--- scene.cpp | 27 +++++++++++++------- scene.hpp | 8 +++--- storyboard/ui.cpp | 6 ++--- storyboard/ui.hpp | 2 +- 9 files changed, 93 insertions(+), 33 deletions(-) diff --git a/boss/fight.cpp b/boss/fight.cpp index 18dadfb..b9f8fe8 100644 --- a/boss/fight.cpp +++ b/boss/fight.cpp @@ -107,6 +107,7 @@ namespace boss { state(State::END); } else { $ui.status(L"PLAYER REQUESTS", L"COMMIT"); + $ui.reset_camera(); $battle.ap_refresh(); $battle.clear_requests(); state(State::PLAYER_REQUESTS); diff --git a/boss/ui.cpp b/boss/ui.cpp index 11cf2f9..9580fc6 100644 --- a/boss/ui.cpp +++ b/boss/ui.cpp @@ -106,12 +106,18 @@ namespace boss { $arena.play_animations(); } - void UI::damage(const std::string& actor, const std::string& target, int amount) { + void UI::damage(const string& actor, const std::string& target, int amount) { if(amount > 0) { $arena.attach_text(target, fmt::format("{}", amount)); $arena.apply_effect(actor, "flame"); + fmt::println("CAMERA zooming by 0.7 to {}", target); + $arena.zoom(target, 0.8f); } else { $arena.attach_text(actor, "MISSED"); } } + + void UI::reset_camera() { + $arena.reset($view_texture); + } } diff --git a/boss/ui.hpp b/boss/ui.hpp index 6ab2881..f7c703a 100644 --- a/boss/ui.hpp +++ b/boss/ui.hpp @@ -39,5 +39,6 @@ namespace boss { void update_stats(); void play_animations(); void damage(const std::string& actor, const std::string& target, int amount); + void reset_camera(); }; } diff --git a/camera.cpp b/camera.cpp index dfd0b65..0498e87 100644 --- a/camera.cpp +++ b/camera.cpp @@ -4,9 +4,10 @@ #include #include "components.hpp" #include "config.hpp" +#include namespace cinematic { - using components::Animation, std::string; + using components::Animation, std::string, std::min, std::clamp; struct CameraManager { std::unordered_map animations; @@ -27,13 +28,38 @@ namespace cinematic { } } - Camera::Camera() : - anim(MGR.animations.at("pan")) + Camera::Camera(sf::Vector2f size) : + anim(MGR.animations.at("shake")), + base_size(size), + size(size) { } - void Camera::resize(float width, float height) { - size = {width, height}; + void Camera::update_camera_bounds(sf::Vector2f size) { + // camera bounds now constrains the x/y so that the mid-point + // of the size won't go too far outside of the frame + camera_bounds = { + {size.x / 2.0f, size.y / 2.0f}, + {base_size.x - size.x / 2.0f, base_size.y - size.y / 2.0f} + }; + + fmt::println("!!!!! CAMERA BOUNDS camera_bounds={},{},{},{}", + camera_bounds.position.x, camera_bounds.position.y, + camera_bounds.size.x, camera_bounds.size.y); + } + + void Camera::scale(float ratio) { + size.x = base_size.x * ratio; + size.y = base_size.y * ratio; + update_camera_bounds(size); + } + + void Camera::resize(float width) { + dbc::check(width <= base_size.x, "invalid width for camera"); + + size.x = width; + size.y = base_size.y * (width / base_size.x); + update_camera_bounds(size); } void Camera::style(const std::string &name) { @@ -41,11 +67,23 @@ namespace cinematic { } void Camera::position(float x, float y) { - aimed_at = {x, y}; + aimed_at.x = clamp(x, camera_bounds.position.x, camera_bounds.size.x); + aimed_at.y = clamp(y, camera_bounds.position.y, camera_bounds.size.y); + + fmt::println("!!! CAMERA POSITION aimed_at={},{}; x/y={},{}; camera_bounds={},{},{},{}", + aimed_at.x, aimed_at.y, x, y, + camera_bounds.position.x, camera_bounds.position.y, + camera_bounds.size.x, camera_bounds.size.y); } void Camera::move(float x, float y) { - going_to = {x, y}; + going_to.x = clamp(x, camera_bounds.position.x, camera_bounds.size.x); + going_to.y = clamp(y, camera_bounds.position.y, camera_bounds.size.y); + + fmt::println("!!!! CAMERA MOVE going_to={},{}; x/y={},{}; camera_bounds={},{},{},{}", + going_to.x, going_to.y, x, y, + camera_bounds.position.x, camera_bounds.position.y, + camera_bounds.size.x, camera_bounds.size.y); // BUG: annoying special case if(anim.motion == ease::SLIDE) { @@ -56,11 +94,14 @@ namespace cinematic { } } - void Camera::reset(sf::RenderTexture& target, float width, float height) { - size = {width, height}; - aimed_at = {width/2, height/2}; - going_to = {width/2, height/2}; + void Camera::reset(sf::RenderTexture& target) { + size = {base_size.x, base_size.y}; + aimed_at = {base_size.x/2, base_size.y/2}; + going_to = {base_size.x/2, base_size.y/2}; view = {aimed_at, size}; + camera_bounds = {{0,0}, base_size}; + + // BUG: is getDefaultView different from view? target.setView(target.getDefaultView()); } diff --git a/camera.hpp b/camera.hpp index a6c894a..ee4f1e8 100644 --- a/camera.hpp +++ b/camera.hpp @@ -6,20 +6,24 @@ namespace cinematic { struct Camera { components::Animation anim; sf::View view; + sf::Vector2f base_size{SCREEN_WIDTH, SCREEN_HEIGHT}; sf::Vector2f size{SCREEN_WIDTH, SCREEN_HEIGHT}; + sf::FloatRect camera_bounds{{0,0},{SCREEN_WIDTH, SCREEN_HEIGHT}}; sf::Vector2f aimed_at{0,0}; sf::Vector2f going_to{0,0}; - Camera(); + Camera(sf::Vector2f base_size); - void resize(float width, float height); + void resize(float width); + void scale(float ratio); void position(float x, float y); void move(float x, float y); bool playing(); void render(sf::RenderTexture& target); void play(); void style(const std::string &name); - void reset(sf::RenderTexture& target, float width, float height); + void reset(sf::RenderTexture& target); + void update_camera_bounds(sf::Vector2f size); }; void init(); diff --git a/scene.cpp b/scene.cpp index b5371e1..c32422e 100644 --- a/scene.cpp +++ b/scene.cpp @@ -36,7 +36,7 @@ namespace scene { Engine::Engine(components::AnimatedScene& scene) : $scene(scene) { - $camera.style("shake"); + $camera.style("dolly"); for(auto& config : $scene.actors) { auto element = config_scene_element(config, false, false); @@ -161,17 +161,26 @@ namespace scene { return pos; } - void Engine::zoom(int mid_x, int mid_y, int width, int height) { - $camera.resize(float(width), float(height)); - $camera.move(float(mid_x), float(mid_y)); + void Engine::zoom(float mid_x, float mid_y, float scale) { + $camera.scale(scale); + $camera.move(mid_x, mid_y); + $camera.play(); } - void Engine::zoom(const std::string &cell_name) { - auto& cell = $ui.cell_for(cell_name); - zoom(cell.w, cell.h, cell.mid_x, cell.mid_y); + void Engine::zoom(const std::string &actor, 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; + + fmt::println("CAMERA in scene::Engine I'm zooming {} by {} @ {},{} size {},{}; going_to mid={},{}", + actor, scale, config.pos.x, config.pos.y, + bounds.size.x, bounds.size.y, mid_x, mid_y); + + zoom(mid_x, mid_y, scale); } - void Engine::reset(sf::RenderTexture& view, float width, float height) { - $camera.reset(view, width, height); + void Engine::reset(sf::RenderTexture& view) { + $camera.reset(view); } } diff --git a/scene.hpp b/scene.hpp index 1be458e..b36c226 100644 --- a/scene.hpp +++ b/scene.hpp @@ -34,7 +34,7 @@ namespace scene { std::unordered_map $actor_name_ids; std::vector $fixtures; std::vector $actors; - cinematic::Camera $camera; + cinematic::Camera $camera{{BOSS_VIEW_WIDTH, BOSS_VIEW_HEIGHT}}; Engine(components::AnimatedScene& scene); @@ -51,8 +51,8 @@ namespace scene { void play_animations(); void apply_effect(const std::string& actor, const std::string& shader); Element& actor_config(const std::string& actor); - void zoom(const std::string& cell); - void reset(sf::RenderTexture& view, float width, float height); - void zoom(int mid_x, int mid_y, int width, int height); + void zoom(const std::string& actor, float scale=0.9f); + void zoom(float mid_x, float mid_y, float scale); + void reset(sf::RenderTexture& view); }; } diff --git a/storyboard/ui.cpp b/storyboard/ui.cpp index fa662f6..a6d95c3 100644 --- a/storyboard/ui.cpp +++ b/storyboard/ui.cpp @@ -93,13 +93,11 @@ namespace storyboard { void UI::zoom(const std::string &cell_name) { auto& cell = $ui.cell_for(cell_name); - $camera.resize(float(cell.w), float(cell.h)); + $camera.resize(float(cell.w)); $camera.move(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); + $camera.reset($view_texture); } } diff --git a/storyboard/ui.hpp b/storyboard/ui.hpp index 87a7d19..06ad6c4 100644 --- a/storyboard/ui.hpp +++ b/storyboard/ui.hpp @@ -10,7 +10,7 @@ namespace storyboard { guecs::UI $ui; sf::RenderTexture $view_texture; sf::Sprite $view_sprite; - cinematic::Camera $camera; + cinematic::Camera $camera{{SCREEN_WIDTH, SCREEN_HEIGHT}}; std::shared_ptr $audio; std::string $zoom_target = "a"; bool $moving = false;