diff options
author | Paul Oliver <contact@pauloliver.dev> | 2024-02-29 19:27:35 +0100 |
---|---|---|
committer | Paul Oliver <contact@pauloliver.dev> | 2024-02-29 19:27:49 +0100 |
commit | 17909d029c6a8872b2fddf4e171d7925bbbe9c5c (patch) | |
tree | cbb08af84cd68d24acc362d593a2048b0fa79689 /Simulation/Camera.cpp |
Diffstat (limited to 'Simulation/Camera.cpp')
-rw-r--r-- | Simulation/Camera.cpp | 241 |
1 files changed, 241 insertions, 0 deletions
diff --git a/Simulation/Camera.cpp b/Simulation/Camera.cpp new file mode 100644 index 0000000..84b98a8 --- /dev/null +++ b/Simulation/Camera.cpp @@ -0,0 +1,241 @@ +#include "Camera.hpp" +#include "SimBase.hpp" + +void Camera::create(SimBase *sim) +{ + hSim = sim; + + defaultZoom = hSim->prms.worldRad / 200.f; + zoom = defaultZoom; + prevZoom = zoom; + trgtZoom = zoom; + + step = 1; + update(); +} + + +void Camera::onResize() +{ + sf::View view = hSim->window.getView(); + sf::Vector2u winSize = hSim->window.getSize(); + view.setSize(winSize.x * zoom, winSize.y * zoom); + view.setCenter(currentCrds); + hSim->window.setView(view); +} + + +void Camera::onClick() +{ + prevZoom = zoom; + trgtZoom = zoom; + + prevCrds = currentCrds; + + sf::Vector2f mousePos = hSim->window.mapPixelToCoords(sf::Mouse::getPosition(hSim->window)); + b2Vec2 b2MousePos(mousePos.x, mousePos.y); + b2Vec2 additive(0.001f, 0.001f); + b2AABB aabb; + aabb.upperBound = b2MousePos + additive; + aabb.lowerBound = b2MousePos - additive; + + QueryCallback callback; + callback.m_point = b2MousePos; + hSim->tank.world.QueryAABB(&callback, aabb); + + if (callback.m_fixture) + { + trgtBody = callback.m_fixture->GetBody(); + } + else + { + trgtCrds = mousePos; + trgtBody = nullptr; + } + + isOnFollow = false; + step = Params::CAM_STEPS; +} + + +void Camera::shift(const sf::Vector2f &newTrgtCrds, int zoomInOut, bool release) +{ + if (!release && trgtBody) + { + prevCrds = sf::Vector2f(trgtBody->GetPosition().x, trgtBody->GetPosition().y); + currentCrds = sf::Vector2f(trgtBody->GetPosition().x, trgtBody->GetPosition().y); + trgtCrds = sf::Vector2f(trgtBody->GetPosition().x, trgtBody->GetPosition().y); + isOnFollow = true; + } + else + { + trgtBody = nullptr; + prevCrds = currentCrds; + trgtCrds = newTrgtCrds; + isOnFollow = false; + } + + prevZoom = zoom; + if (zoomInOut) + { + if (zoomInOut == 1) + { + trgtZoom = zoom - 0.2f * zoom; + } + else if (zoomInOut == -1) + { + trgtZoom = zoom + 0.2f * zoom; + } + else if (zoomInOut == -2) + { + trgtZoom = defaultZoom; + } + } + else + { + trgtZoom = zoom; + } + + step = Params::CAM_STEPS; +} + +void Camera::update() +{ + if (trgtBody || step) + { + if (!step) + { + currentCrds = sf::Vector2f(trgtBody->GetPosition().x, trgtBody->GetPosition().y); + } + else + { + if (trgtBody) + { + trgtCrds = sf::Vector2f(trgtBody->GetPosition().x, trgtBody->GetPosition().y); + if (isOnFollow) + { + prevCrds = trgtCrds; + } + } + + float f1 = (step - 1.f) / (float)Params::CAM_STEPS; + float f2 = 1.f - f1; + + currentCrds = prevCrds * f1 + trgtCrds * f2; + zoom = prevZoom * f1 + trgtZoom * f2; + + if (currentCrds.x * currentCrds.x + currentCrds.y * currentCrds.y > hSim->prms.worldRad * hSim->prms.worldRad) + { + float angle = atanf(currentCrds.y / currentCrds.x); + currentCrds.y = sinf(angle) * hSim->prms.worldRad * (currentCrds.x > 1.f ? 1.f : -1.f); + currentCrds.x = cosf(angle) * hSim->prms.worldRad * (currentCrds.x > 1.f ? 1.f : -1.f); + } + + if (zoom > defaultZoom) + { + zoom = defaultZoom; + } + if (zoom < Params::MAX_ZOOM) + { + zoom = Params::MAX_ZOOM; + } + + --step; + } + + sf::View view = hSim->window.getView(); + view.setCenter(currentCrds); + view.setSize(hSim->window.getSize().x * zoom, hSim->window.getSize().y * zoom); + hSim->window.setView(view); + } + + // Prepare low zoom graphics + hSim->tank.worldEdges.setOutlineThickness(zoom * 2.f); + + if (zoom > Params::ZAPPER_RAD / 2.f) + { + if (zoom > Params::ZAPPER_RAD * 2.f) + { + setCenterRad(hSim->zapperPoint, zoom); + hSim->zapperPoint.setFillColor(hSim->prms.zapperColor); + } + else + { + setCenterRad(hSim->zapperPoint, Params::ZAPPER_RAD); + hSim->zapperPoint.setFillColor(hSim->prms.zapperColor); + } + } + else + { + setCenterRad(hSim->zapperShell, hSim->prms.ZAPPER_RAD - zoom * 2.f); + hSim->zapperShell.setOutlineThickness(zoom * 2.f); + } + + if (zoom > Params::PELLET_RAD / 2.f) + { + if (zoom > Params::PELLET_RAD * 2.f) + { + setCenterRad(hSim->pelletPoint, zoom); + hSim->pelletPoint.setFillColor(hSim->prms.pelletColor); + } + else + { + setCenterRad(hSim->pelletPoint, Params::PELLET_RAD); + hSim->pelletPoint.setFillColor(hSim->prms.pelletColor); + } + } + else + { + setCenterRad(hSim->pelletShell, hSim->prms.PELLET_RAD - zoom * 2.f); + hSim->pelletShell.setOutlineThickness(zoom * 2.f); + } + + if (zoom > Params::CORPSE_RAD / 2.f) + { + if (zoom > Params::CORPSE_RAD * 2.f) + { + setCenterRad(hSim->corpsePoint, zoom); + hSim->corpsePoint.setFillColor(hSim->prms.corpseColor); + } + else + { + setCenterRad(hSim->corpsePoint, Params::CORPSE_RAD); + hSim->corpsePoint.setFillColor(hSim->prms.corpseColor); + } + } + else + { + setCenterRad(hSim->corpseShell, hSim->prms.CORPSE_RAD - zoom * 2.f); + hSim->corpseShell.setOutlineThickness(zoom * 2.f); + } + + if (zoom > Params::EGG_RAD / 2.f) + { + if (zoom > Params::EGG_RAD * 2.f) + { + setCenterRad(hSim->eggPoint, zoom); + hSim->eggPoint.setFillColor(hSim->guppN); + } + else + { + setCenterRad(hSim->eggPoint, Params::EGG_RAD); + hSim->eggPoint.setFillColor(hSim->guppN); + } + } + else + { + setCenterRad(hSim->guppieEgg, hSim->prms.EGG_RAD - zoom * 2.f); + hSim->guppieEgg.setOutlineThickness(zoom * 2.f); + } + + if (zoom > Params::GUPPIE_RAD) + { + setCenterRad(hSim->guppiePoint, zoom); + } + + else if (zoom > 0.02f) + { + setCenterRad(hSim->guppieShell, Params::GUPPIE_RAD - zoom); + hSim->guppieShell.setOutlineThickness(zoom); + } +} |