diff --git a/src/Game.cpp b/src/Game.cpp index aa377d8..1b9212e 100644 --- a/src/Game.cpp +++ b/src/Game.cpp @@ -1,13 +1,10 @@ #include "Game.hpp" +#include "Lighting.hpp" #include #include #include -#include -#include -Game::Game() - : gridLines(WIDTH, HEIGHT, 20.f), player(15.f, sf::Color::Green), - rayVertices(sf::PrimitiveType::TriangleFan) { +Game::Game() : gridLines(WIDTH, HEIGHT, 20.f), player(15.f, sf::Color::Green) { window.create(sf::VideoMode({WIDTH, HEIGHT}), "SFML Game"); window.setVerticalSyncEnabled(VSYNC); @@ -17,8 +14,6 @@ Game::Game() worldView.setSize({(float)WIDTH, (float)HEIGHT}); worldView.setCenter({(float)WIDTH / 2.f, (float)HEIGHT / 2.f}); - - lightColor = sf::Color(255, 255, 150, 50); } void Game::run() { @@ -61,80 +56,10 @@ void Game::processEvents() { }; }; -float Game::intersects(Ray ray, Wall wall) { - auto wallVector = wall.end - wall.start; - auto determinator = - (ray.direction.x * wallVector.y) - (ray.direction.y * wallVector.x); - - if (determinator == 0) - return INFINITY; - - auto rayDist = ((wall.start.x - ray.origin.x) * wallVector.y - - (wall.start.y - ray.origin.y) * wallVector.x); - rayDist /= determinator; - - auto wallDist = (wall.start.x - ray.origin.x) * ray.direction.y - - (wall.start.y - ray.origin.y) * ray.direction.x; - wallDist /= determinator; - - if (rayDist > 0 && wallDist >= 0 && wallDist <= 1) { - return rayDist; - } - - return INFINITY; -}; - -sf::Vector2f Game::updateRay(sf::Vector2f &origin, sf::Vector2f &targetPoint, - float offset) { - auto closestDist = 1.0f; - auto maxDist = 3000.0f; - - float angle = - std::atan2(targetPoint.y - origin.y, targetPoint.x - origin.x) + offset; - - sf::Vector2f direction = {std::cos(angle) * maxDist, - std::sin(angle) * maxDist}; - Ray ray = {origin, direction}; - - for (Wall wall : walls.get()) { - auto rayDist = intersects(ray, wall); - if (rayDist < closestDist) { - closestDist = rayDist; - }; - } - - return ray.origin + (ray.direction * closestDist); -} - void Game::update(double dt) { debug.update(dt); player.update(dt, window, worldView); - - // INIT/UPDATE RAYS ------------------------------------------ - sf::Vector2 playerPosition = player.position; - rayVertices.clear(); - hitPoints.clear(); - - for (sf::Vector2 targetPoint : walls.getPoints()) { - hitPoints.emplace_back(updateRay(playerPosition, targetPoint, 0.f)); - hitPoints.emplace_back(updateRay(playerPosition, targetPoint, 0.001f)); - hitPoints.emplace_back(updateRay(playerPosition, targetPoint, -0.001f)); - } - std::sort(hitPoints.begin(), hitPoints.end(), - [playerPosition](sf::Vector2f a, sf::Vector2f b) -> bool { - auto angleA = - atan2(playerPosition.y - a.y, playerPosition.x - a.x); - auto angleB = - atan2(playerPosition.y - b.y, playerPosition.x - b.x); - return angleA < angleB; - }); - - rayVertices.append({playerPosition, lightColor}); - for (auto hitPoint : hitPoints) { - rayVertices.append({hitPoint, lightColor}); - } - rayVertices.append({hitPoints[0], lightColor}); - // ----------------------------------------------------------- + lighting.update(dt, player.position, walls); }; void Game::render() { @@ -145,10 +70,7 @@ void Game::render() { debug.render(window); player.render(window); walls.render(window); - - // RENDER RAYS ------- - window.draw(rayVertices); - // ----------------- + lighting.render(window); window.display(); }; diff --git a/src/Game.hpp b/src/Game.hpp index 7fb6299..517e7f7 100644 --- a/src/Game.hpp +++ b/src/Game.hpp @@ -9,6 +9,7 @@ #include "DebugUI.hpp" #include "GridLines.hpp" +#include "Lighting.hpp" #include "Player.hpp" #include "Walls.hpp" @@ -18,11 +19,6 @@ constexpr int HEIGHT = 1080; constexpr int DEBUG_REFRESH_RATE_IN_MS = 250; constexpr float ASPECT = 16.f / 9.f; -struct Ray { - sf::Vector2f origin; - sf::Vector2f direction; -}; - class Game { public: Game(); @@ -36,14 +32,7 @@ private: DebugUI debug; GridLines gridLines; Walls walls; - - sf::VertexArray rayVertices; - std::vector hitPoints; - sf::Color lightColor; - - float intersects(Ray ray, Wall wall); - sf::Vector2f updateRay(sf::Vector2f &origin, sf::Vector2f &targetPoint, - float offset); + Lighting lighting; void onResize(); void processEvents(); diff --git a/src/Lighting.cpp b/src/Lighting.cpp new file mode 100644 index 0000000..239f639 --- /dev/null +++ b/src/Lighting.cpp @@ -0,0 +1,81 @@ +#include "Lighting.hpp" +#include +#include + +Lighting::Lighting() : rayVertices(sf::PrimitiveType::TriangleFan) { + lightColor = sf::Color(255, 255, 150, 50); +}; + +float Lighting::intersects(Ray ray, Wall wall) { + auto wallVector = wall.end - wall.start; + auto determinator = + (ray.direction.x * wallVector.y) - (ray.direction.y * wallVector.x); + + if (determinator == 0) + return INFINITY; + + auto rayDist = ((wall.start.x - ray.origin.x) * wallVector.y - + (wall.start.y - ray.origin.y) * wallVector.x); + rayDist /= determinator; + + auto wallDist = (wall.start.x - ray.origin.x) * ray.direction.y - + (wall.start.y - ray.origin.y) * ray.direction.x; + wallDist /= determinator; + + if (rayDist > 0 && wallDist >= 0 && wallDist <= 1) { + return rayDist; + } + + return INFINITY; +}; + +sf::Vector2f Lighting::updateRay(Walls &walls, sf::Vector2f &origin, + sf::Vector2f &targetPoint, float offset) { + auto closestDist = 1.0f; + auto maxDist = 3000.0f; + + float angle = + std::atan2(targetPoint.y - origin.y, targetPoint.x - origin.x) + offset; + + sf::Vector2f direction = {std::cos(angle) * maxDist, + std::sin(angle) * maxDist}; + Ray ray = {origin, direction}; + + for (Wall wall : walls.get()) { + auto rayDist = intersects(ray, wall); + if (rayDist < closestDist) { + closestDist = rayDist; + }; + } + + return ray.origin + (ray.direction * closestDist); +} + +void Lighting::update(double dt, sf::Vector2f &playerPosition, Walls &walls) { + rayVertices.clear(); + hitPoints.clear(); + + for (sf::Vector2 targetPoint : walls.getPoints()) { + hitPoints.emplace_back(updateRay(walls, playerPosition, targetPoint, 0.f)); + hitPoints.emplace_back( + updateRay(walls, playerPosition, targetPoint, 0.001f)); + hitPoints.emplace_back( + updateRay(walls, playerPosition, targetPoint, -0.001f)); + } + std::sort(hitPoints.begin(), hitPoints.end(), + [playerPosition](sf::Vector2f a, sf::Vector2f b) -> bool { + auto angleA = + atan2(playerPosition.y - a.y, playerPosition.x - a.x); + auto angleB = + atan2(playerPosition.y - b.y, playerPosition.x - b.x); + return angleA < angleB; + }); + + rayVertices.append({playerPosition, lightColor}); + for (auto hitPoint : hitPoints) { + rayVertices.append({hitPoint, lightColor}); + } + rayVertices.append({hitPoints[0], lightColor}); +} + +void Lighting::render(sf::RenderWindow &window) { window.draw(rayVertices); }; diff --git a/src/Lighting.hpp b/src/Lighting.hpp new file mode 100644 index 0000000..3e6cc9e --- /dev/null +++ b/src/Lighting.hpp @@ -0,0 +1,29 @@ +#ifndef LIGHTING_HPP +#define LIGHTING_HPP + +#include "Walls.hpp" +#include +#include + +struct Ray { + sf::Vector2f origin; + sf::Vector2f direction; +}; + +class Lighting { +public: + Lighting(); + + float intersects(Ray ray, Wall wall); + sf::Vector2f updateRay(Walls &walls, sf::Vector2f &origin, + sf::Vector2f &targetPoint, float offset); + void update(double dt, sf::Vector2f &playerPosition, Walls &walls); + void render(sf::RenderWindow &window); + +private: + sf::VertexArray rayVertices; + std::vector hitPoints; + sf::Color lightColor; +}; + +#endif // LIGHTING_HPP \ No newline at end of file