feat: raycasting part 2 (working great!)

This commit is contained in:
Floriansylvain
2025-12-28 16:42:47 +01:00
parent 4402ec9159
commit f59a48ed51
2 changed files with 50 additions and 29 deletions
+44 -18
View File
@@ -2,11 +2,12 @@
#include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Color.hpp>
#include <SFML/System/Vector2.hpp> #include <SFML/System/Vector2.hpp>
#include <SFML/Window/Mouse.hpp> #include <SFML/Window/Mouse.hpp>
#include <algorithm>
#include <cmath> #include <cmath>
Game::Game() Game::Game()
: gridLines(WIDTH, HEIGHT, 20.f), player(15.f, sf::Color::Green), : gridLines(WIDTH, HEIGHT, 20.f), player(15.f, sf::Color::Green),
rayVertices(sf::PrimitiveType::Lines) { rayVertices(sf::PrimitiveType::TriangleFan) {
window.create(sf::VideoMode({WIDTH, HEIGHT}), "SFML Game"); window.create(sf::VideoMode({WIDTH, HEIGHT}), "SFML Game");
window.setVerticalSyncEnabled(VSYNC); window.setVerticalSyncEnabled(VSYNC);
@@ -16,6 +17,8 @@ Game::Game()
worldView.setSize({(float)WIDTH, (float)HEIGHT}); worldView.setSize({(float)WIDTH, (float)HEIGHT});
worldView.setCenter({(float)WIDTH / 2.f, (float)HEIGHT / 2.f}); worldView.setCenter({(float)WIDTH / 2.f, (float)HEIGHT / 2.f});
lightColor = sf::Color(255, 255, 150, 50);
} }
void Game::run() { void Game::run() {
@@ -64,7 +67,7 @@ float Game::intersects(Ray ray, Wall wall) {
(ray.direction.x * wallVector.y) - (ray.direction.y * wallVector.x); (ray.direction.x * wallVector.y) - (ray.direction.y * wallVector.x);
if (determinator == 0) if (determinator == 0)
return false; return INFINITY;
auto rayDist = ((wall.start.x - ray.origin.x) * wallVector.y - auto rayDist = ((wall.start.x - ray.origin.x) * wallVector.y -
(wall.start.y - ray.origin.y) * wallVector.x); (wall.start.y - ray.origin.y) * wallVector.x);
@@ -81,18 +84,17 @@ float Game::intersects(Ray ray, Wall wall) {
return INFINITY; return INFINITY;
}; };
void Game::update(double dt) { sf::Vector2f Game::updateRay(sf::Vector2f &origin, sf::Vector2f &targetPoint,
debug.update(dt); float offset) {
player.update(dt, window, worldView);
// INIT/UPDATE RAYS -------
auto mousePos = sf::Mouse::getPosition(window);
auto mousePosWorld = window.mapPixelToCoords(mousePos, worldView);
rayVertices.clear();
for (sf::Vector2 targetPoint : walls.getPoints()) {
auto ray = Ray(mousePosWorld, targetPoint);
auto closestDist = 1.0f; 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()) { for (Wall wall : walls.get()) {
auto rayDist = intersects(ray, wall); auto rayDist = intersects(ray, wall);
@@ -101,14 +103,38 @@ void Game::update(double dt) {
}; };
} }
sf::Vector2f hitPoint = ray.origin + (ray.direction * closestDist); return ray.origin + (ray.direction * closestDist);
}
rayVertices.append({ray.origin, sf::Color::Blue}); void Game::update(double dt) {
rayVertices.append({hitPoint, sf::Color::Blue}); debug.update(dt);
player.update(dt, window, worldView);
// INIT/UPDATE RAYS ------------------------------------------
auto mousePos = sf::Mouse::getPosition(window);
auto mousePosWorld = window.mapPixelToCoords(mousePos, worldView);
rayVertices.clear();
hitPoints.clear();
for (sf::Vector2 targetPoint : walls.getPoints()) {
hitPoints.emplace_back(updateRay(mousePosWorld, targetPoint, 0.f));
hitPoints.emplace_back(updateRay(mousePosWorld, targetPoint, 0.001f));
hitPoints.emplace_back(updateRay(mousePosWorld, targetPoint, -0.001f));
} }
std::sort(hitPoints.begin(), hitPoints.end(),
[mousePosWorld](sf::Vector2f a, sf::Vector2f b) -> bool {
auto angleA = atan2(mousePosWorld.y - a.y, mousePosWorld.x - a.x);
auto angleB = atan2(mousePosWorld.y - b.y, mousePosWorld.x - b.x);
return angleA < angleB;
});
// TODO: implement 3-rays trick to have softer angles rayVertices.append({mousePosWorld, lightColor});
// ----------------- for (auto hitPoint : hitPoints) {
rayVertices.append({hitPoint, lightColor});
}
rayVertices.append({hitPoints[0], lightColor});
// -----------------------------------------------------------
}; };
void Game::render() { void Game::render() {
+5 -10
View File
@@ -12,7 +12,7 @@
#include "Player.hpp" #include "Player.hpp"
#include "Walls.hpp" #include "Walls.hpp"
constexpr bool VSYNC = true; constexpr bool VSYNC = false;
constexpr int WIDTH = 1920; constexpr int WIDTH = 1920;
constexpr int HEIGHT = 1080; constexpr int HEIGHT = 1080;
constexpr int DEBUG_REFRESH_RATE_IN_MS = 250; constexpr int DEBUG_REFRESH_RATE_IN_MS = 250;
@@ -21,15 +21,6 @@ constexpr float ASPECT = 16.f / 9.f;
struct Ray { struct Ray {
sf::Vector2f origin; sf::Vector2f origin;
sf::Vector2f direction; sf::Vector2f direction;
float angle;
Ray(sf::Vector2f origin, sf::Vector2f target) {
this->origin = origin;
this->direction = target - origin;
angle = direction.angleTo(origin).asDegrees();
};
Ray(float angle, float length) {}; // TODO
}; };
class Game { class Game {
@@ -47,8 +38,12 @@ private:
Walls walls; Walls walls;
sf::VertexArray rayVertices; sf::VertexArray rayVertices;
std::vector<sf::Vector2f> hitPoints;
sf::Color lightColor;
float intersects(Ray ray, Wall wall); float intersects(Ray ray, Wall wall);
sf::Vector2f updateRay(sf::Vector2f &origin, sf::Vector2f &targetPoint,
float offset);
void onResize(); void onResize();
void processEvents(); void processEvents();