Clean-up: Change indentation to tabs
This commit is contained in:
parent
66ec111f5d
commit
41437cd259
6 changed files with 301 additions and 301 deletions
|
@ -8,31 +8,31 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules" ${CMAKE_MODULE_PATH})
|
||||||
find_package(SFML COMPONENTS system window graphics network audio REQUIRED)
|
find_package(SFML COMPONENTS system window graphics network audio REQUIRED)
|
||||||
|
|
||||||
if(NOT SFML_FOUND)
|
if(NOT SFML_FOUND)
|
||||||
message(FATAL_ERROR "SFML could not be found")
|
message(FATAL_ERROR "SFML could not be found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(LIBS
|
set(LIBS
|
||||||
sfml-window
|
sfml-window
|
||||||
sfml-graphics)
|
sfml-graphics)
|
||||||
|
|
||||||
find_package(ImGui QUIET)
|
find_package(ImGui QUIET)
|
||||||
find_package(ImGui-SFML QUIET)
|
find_package(ImGui-SFML QUIET)
|
||||||
|
|
||||||
if(NOT ImGui_FOUND OR NOT ImGui-SFML_FOUND OR NO_IMGUI)
|
if(NOT ImGui_FOUND OR NOT ImGui-SFML_FOUND OR NO_IMGUI)
|
||||||
message("*Not* building with ImGui")
|
message("*Not* building with ImGui")
|
||||||
else ()
|
else ()
|
||||||
message("Building with ImGui")
|
message("Building with ImGui")
|
||||||
add_compile_definitions(IMGUI)
|
add_compile_definitions(IMGUI)
|
||||||
set(LIBS ${LIBS}
|
set(LIBS ${LIBS}
|
||||||
ImGui-SFML::ImGui-SFML)
|
ImGui-SFML::ImGui-SFML)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_compile_options(-Wall -Wextra)
|
add_compile_options(-Wall -Wextra)
|
||||||
|
|
||||||
add_executable(raycasting
|
add_executable(raycasting
|
||||||
main.cpp
|
main.cpp
|
||||||
Player.cpp
|
Player.cpp
|
||||||
World.cpp
|
World.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(raycasting ${LIBS})
|
target_link_libraries(raycasting ${LIBS})
|
||||||
|
|
26
Player.cpp
26
Player.cpp
|
@ -10,21 +10,21 @@ Player::Player(float x, float y, float alpha) : x(x), y(y), orientation(alpha)
|
||||||
|
|
||||||
void Player::move(float dx, float dy)
|
void Player::move(float dx, float dy)
|
||||||
{
|
{
|
||||||
x += dx;
|
x += dx;
|
||||||
y += dy;
|
y += dy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::rotate(float alpha)
|
void Player::rotate(float alpha)
|
||||||
{
|
{
|
||||||
orientation += fmodf(alpha, 360);
|
orientation += fmodf(alpha, 360);
|
||||||
if(orientation > 360)
|
if(orientation > 360)
|
||||||
{
|
{
|
||||||
orientation -= 360;
|
orientation -= 360;
|
||||||
}
|
}
|
||||||
else if(orientation < 0)
|
else if(orientation < 0)
|
||||||
{
|
{
|
||||||
orientation += 360;
|
orientation += 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Rotate the movement vector along the new angle, assumes that the only
|
* Rotate the movement vector along the new angle, assumes that the only
|
||||||
|
@ -33,9 +33,9 @@ void Player::rotate(float alpha)
|
||||||
float prevSpeedX = currentMoveSpeedX;
|
float prevSpeedX = currentMoveSpeedX;
|
||||||
float prevSpeedY = currentMoveSpeedY;
|
float prevSpeedY = currentMoveSpeedY;
|
||||||
currentMoveSpeedX = cosf(-alpha * deg_to_rad) * prevSpeedX
|
currentMoveSpeedX = cosf(-alpha * deg_to_rad) * prevSpeedX
|
||||||
- sinf(-alpha * deg_to_rad) * prevSpeedY;
|
- sinf(-alpha * deg_to_rad) * prevSpeedY;
|
||||||
currentMoveSpeedY = sinf(-alpha * deg_to_rad) * prevSpeedX
|
currentMoveSpeedY = sinf(-alpha * deg_to_rad) * prevSpeedX
|
||||||
+ cosf(-alpha * deg_to_rad) * prevSpeedY;
|
+ cosf(-alpha * deg_to_rad) * prevSpeedY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::updateSpeed(float localX, float localY) {
|
void Player::updateSpeed(float localX, float localY) {
|
||||||
|
|
32
Player.h
32
Player.h
|
@ -11,28 +11,28 @@ static constexpr float deg_to_rad = 3.14159265/180;
|
||||||
|
|
||||||
class Player {
|
class Player {
|
||||||
public:
|
public:
|
||||||
Player(float x, float y, float alpha);
|
Player(float x, float y, float alpha);
|
||||||
|
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
float orientation;
|
float orientation;
|
||||||
|
|
||||||
float moveSpeed = 5;
|
float moveSpeed = 5;
|
||||||
float rotationSpeed = 180;
|
float rotationSpeed = 180;
|
||||||
|
|
||||||
float currentMoveSpeedX = 0;
|
float currentMoveSpeedX = 0;
|
||||||
float currentMoveSpeedY = 0;
|
float currentMoveSpeedY = 0;
|
||||||
|
|
||||||
float currentRotationSpeed = 0;
|
float currentRotationSpeed = 0;
|
||||||
|
|
||||||
/* View properties. */
|
/* View properties. */
|
||||||
float fov = 70;
|
float fov = 70;
|
||||||
float sensorSize = 0.035; /* 35mm, about equivalent to human eye ? */
|
float sensorSize = 0.035; /* 35mm, about equivalent to human eye ? */
|
||||||
float focalLength = sensorSize / (2*tanf((fov*deg_to_rad)/2));
|
float focalLength = sensorSize / (2*tanf((fov*deg_to_rad)/2));
|
||||||
|
|
||||||
void move(float dx, float dy);
|
void move(float dx, float dy);
|
||||||
void rotate(float alpha);
|
void rotate(float alpha);
|
||||||
void updateSpeed(float localX, float localY);
|
void updateSpeed(float localX, float localY);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
368
World.cpp
368
World.cpp
|
@ -14,22 +14,22 @@ World::World(int w, int h, sf::Color groundColor, sf::Color ceilingColor, std::v
|
||||||
player(0,0,0), w(w), h(h), map(std::move(worldMap)),
|
player(0,0,0), w(w), h(h), map(std::move(worldMap)),
|
||||||
groundColor(groundColor), ceilingColor(ceilingColor)
|
groundColor(groundColor), ceilingColor(ceilingColor)
|
||||||
{
|
{
|
||||||
map.resize(w*h,BlockType::WALL);
|
map.resize(w*h,BlockType::WALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
int World::getW() const
|
int World::getW() const
|
||||||
{
|
{
|
||||||
return w;
|
return w;
|
||||||
}
|
}
|
||||||
|
|
||||||
int World::getH() const
|
int World::getH() const
|
||||||
{
|
{
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockType World::getBlock(int x, int y) const
|
BlockType World::getBlock(int x, int y) const
|
||||||
{
|
{
|
||||||
return map[x + w*y];
|
return map[x + w*y];
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockType World::getBlock(float x, float y) const
|
BlockType World::getBlock(float x, float y) const
|
||||||
|
@ -39,176 +39,176 @@ BlockType World::getBlock(float x, float y) const
|
||||||
|
|
||||||
void World::setBlock(BlockType block, int x, int y, int width, int height)
|
void World::setBlock(BlockType block, int x, int y, int width, int height)
|
||||||
{
|
{
|
||||||
for(int i = 0;i<height;i++)
|
for(int i = 0;i<height;i++)
|
||||||
{
|
{
|
||||||
for(int j = 0;j<width;j++)
|
for(int j = 0;j<width;j++)
|
||||||
{
|
{
|
||||||
if(x+j<w && y+i < h)
|
if(x+j<w && y+i < h)
|
||||||
{
|
{
|
||||||
map.at((y+i)*w+x+j) = block;
|
map.at((y+i)*w+x+j) = block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& ostream, World const& world)
|
std::ostream& operator<<(std::ostream& ostream, World const& world)
|
||||||
{
|
{
|
||||||
for(int i = 0;i<world.w*world.h;i++)
|
for(int i = 0;i<world.w*world.h;i++)
|
||||||
{
|
{
|
||||||
if(i%world.w == 0)
|
if(i%world.w == 0)
|
||||||
{
|
{
|
||||||
ostream << std::endl;
|
ostream << std::endl;
|
||||||
}
|
}
|
||||||
switch(world.getBlock(i%world.w,i/world.w))
|
switch(world.getBlock(i%world.w,i/world.w))
|
||||||
{
|
{
|
||||||
case BlockType::AIR:
|
case BlockType::AIR:
|
||||||
{
|
{
|
||||||
if(static_cast<int>(world.player.x) == i%world.w && static_cast<int>(world.player.y) == i/world.h)
|
if(static_cast<int>(world.player.x) == i%world.w && static_cast<int>(world.player.y) == i/world.h)
|
||||||
{
|
{
|
||||||
ostream << "P";
|
ostream << "P";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ostream << " ";
|
ostream << " ";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BlockType::WALL:
|
case BlockType::WALL:
|
||||||
{
|
{
|
||||||
ostream << "W";
|
ostream << "W";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BlockType::DOOR:
|
case BlockType::DOOR:
|
||||||
{
|
{
|
||||||
ostream << "D";
|
ostream << "D";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BlockType::WINDOW:
|
case BlockType::WINDOW:
|
||||||
{
|
{
|
||||||
ostream << "W";
|
ostream << "W";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(ostream);
|
return(ostream);
|
||||||
}
|
}
|
||||||
|
|
||||||
float World::castRay(float originX, float originY, float orientation) const
|
float World::castRay(float originX, float originY, float orientation) const
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Reference used for ray intersection computations :
|
* Reference used for ray intersection computations :
|
||||||
* https://web.archive.org/web/20220628034315/https://yunes.informatique.univ-paris-diderot.fr/wp-content/uploads/cours/INFOGRAPHIE/08-Raycasting.pdf
|
* https://web.archive.org/web/20220628034315/https://yunes.informatique.univ-paris-diderot.fr/wp-content/uploads/cours/INFOGRAPHIE/08-Raycasting.pdf
|
||||||
* The logic is as follows :
|
* The logic is as follows :
|
||||||
* - This computes one set of point per edge crossings (horizontal/vertical)
|
* - This computes one set of point per edge crossings (horizontal/vertical)
|
||||||
* - The origin not being confined to the grid, offsets are computed to
|
* - The origin not being confined to the grid, offsets are computed to
|
||||||
* align the intersections properly
|
* align the intersections properly
|
||||||
* - The intersections are at multiples of the tangent of the relevant
|
* - The intersections are at multiples of the tangent of the relevant
|
||||||
* angle for the axis of interest, and simply on successive edges of
|
* angle for the axis of interest, and simply on successive edges of
|
||||||
* the grid for the other one
|
* the grid for the other one
|
||||||
* - Depending on the orientation, signs must be taken into account
|
* - Depending on the orientation, signs must be taken into account
|
||||||
* to work 360°
|
* to work 360°
|
||||||
* - Those formulas consider regular axes (x→,y↑), however the world is
|
* - Those formulas consider regular axes (x→,y↑), however the world is
|
||||||
* built around left-handed axes (x→,y↓), so the rendered world is
|
* built around left-handed axes (x→,y↓), so the rendered world is
|
||||||
* mirrored. This also explains some weird signs for rotations.
|
* mirrored. This also explains some weird signs for rotations.
|
||||||
*/
|
*/
|
||||||
/* Offsets to get back on the grid from the ray's origin. */
|
/* Offsets to get back on the grid from the ray's origin. */
|
||||||
float hOffsetX;
|
float hOffsetX;
|
||||||
float hOffsetY;
|
float hOffsetY;
|
||||||
float vOffsetX;
|
float vOffsetX;
|
||||||
float vOffsetY;
|
float vOffsetY;
|
||||||
|
|
||||||
/* Signs controlling the direction of travel. */
|
/* Signs controlling the direction of travel. */
|
||||||
float hDir;
|
float hDir;
|
||||||
float vDir;
|
float vDir;
|
||||||
/* Need offset for rounding in the right direction ? */
|
/* Need offset for rounding in the right direction ? */
|
||||||
float hRound;
|
float hRound;
|
||||||
float vRound;
|
float vRound;
|
||||||
|
|
||||||
float rads = orientation * deg_to_rad;
|
float rads = orientation * deg_to_rad;
|
||||||
/* Used for vertical intersections. */
|
/* Used for vertical intersections. */
|
||||||
float rads_offset = (90 - orientation) * deg_to_rad;
|
float rads_offset = (90 - orientation) * deg_to_rad;
|
||||||
|
|
||||||
/* Tangents used for the different axes. */
|
/* Tangents used for the different axes. */
|
||||||
float hTan = tanf(rads);
|
float hTan = tanf(rads);
|
||||||
float vTan = tanf(rads_offset);
|
float vTan = tanf(rads_offset);
|
||||||
|
|
||||||
/* Check if cos > 0 for horizontal hits formulas. */
|
/* Check if cos > 0 for horizontal hits formulas. */
|
||||||
if (orientation < 90 || orientation > 270) {
|
if (orientation < 90 || orientation > 270) {
|
||||||
hOffsetX = ceilf(originY) - originY;
|
hOffsetX = ceilf(originY) - originY;
|
||||||
hOffsetY = ceilf(originY);
|
hOffsetY = ceilf(originY);
|
||||||
hDir = +1;
|
hDir = +1;
|
||||||
hRound = 0;
|
hRound = 0;
|
||||||
} else {
|
} else {
|
||||||
hOffsetX = originY - floorf(originY);
|
hOffsetX = originY - floorf(originY);
|
||||||
hOffsetY = floorf(originY);
|
hOffsetY = floorf(originY);
|
||||||
hDir = -1;
|
hDir = -1;
|
||||||
hRound = -1;
|
hRound = -1;
|
||||||
}
|
}
|
||||||
hTan *= hDir;
|
hTan *= hDir;
|
||||||
hOffsetX *= hTan;
|
hOffsetX *= hTan;
|
||||||
|
|
||||||
/* Check if sin > 0 for vertical hits formulas. */
|
/* Check if sin > 0 for vertical hits formulas. */
|
||||||
if (orientation < 180) {
|
if (orientation < 180) {
|
||||||
vOffsetX = ceilf(originX);
|
vOffsetX = ceilf(originX);
|
||||||
vOffsetY = ceilf(originX) - originX;
|
vOffsetY = ceilf(originX) - originX;
|
||||||
vDir = 1;
|
vDir = 1;
|
||||||
vRound = 0;
|
vRound = 0;
|
||||||
} else {
|
} else {
|
||||||
vOffsetX = floorf(originX);
|
vOffsetX = floorf(originX);
|
||||||
vOffsetY = originX - floorf(originX);
|
vOffsetY = originX - floorf(originX);
|
||||||
vDir = -1;
|
vDir = -1;
|
||||||
vRound = -1;
|
vRound = -1;
|
||||||
}
|
}
|
||||||
vTan *= vDir;
|
vTan *= vDir;
|
||||||
vOffsetY *= vTan;
|
vOffsetY *= vTan;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we have all the constants and deltas to work with, cast the ray.
|
* Now we have all the constants and deltas to work with, cast the ray.
|
||||||
* Generated points follow the formulas :
|
* Generated points follow the formulas :
|
||||||
* - h-intersect : (originX + hOffsetX + hTan*i, hOffsetY + hDir*i)
|
* - h-intersect : (originX + hOffsetX + hTan*i, hOffsetY + hDir*i)
|
||||||
* - v-intersect : (vOffsetX + vDir*i, originY + vOffsetY + vTan*i)
|
* - v-intersect : (vOffsetX + vDir*i, originY + vOffsetY + vTan*i)
|
||||||
*/
|
*/
|
||||||
int i = 0;
|
int i = 0;
|
||||||
float hCheckX = originX + hOffsetX;
|
float hCheckX = originX + hOffsetX;
|
||||||
float hCheckY = hOffsetY;
|
float hCheckY = hOffsetY;
|
||||||
/* Bounds + sanity check. */
|
/* Bounds + sanity check. */
|
||||||
while (hCheckX >= 0 && hCheckX <= static_cast<float>(w) &&
|
while (hCheckX >= 0 && hCheckX <= static_cast<float>(w) &&
|
||||||
hCheckY >= 0 && hCheckY <= static_cast<float>(h) && i < h) {
|
hCheckY >= 0 && hCheckY <= static_cast<float>(h) && i < h) {
|
||||||
if (getBlock(floorf(hCheckX), floorf(hCheckY) + hRound) == BlockType::WALL) {
|
if (getBlock(floorf(hCheckX), floorf(hCheckY) + hRound) == BlockType::WALL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
hCheckX += hTan;
|
hCheckX += hTan;
|
||||||
hCheckY += hDir;
|
hCheckY += hDir;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
float vCheckX = vOffsetX;
|
float vCheckX = vOffsetX;
|
||||||
float vCheckY = originY + vOffsetY;
|
float vCheckY = originY + vOffsetY;
|
||||||
|
|
||||||
/* Bounds + sanity check. */
|
/* Bounds + sanity check. */
|
||||||
while (vCheckX >= 0 && vCheckX < static_cast<float>(w) &&
|
while (vCheckX >= 0 && vCheckX < static_cast<float>(w) &&
|
||||||
vCheckY >= 0 && vCheckY < static_cast<float>(h) && i < w) {
|
vCheckY >= 0 && vCheckY < static_cast<float>(h) && i < w) {
|
||||||
if (getBlock(floorf(vCheckX) + vRound, floorf(vCheckY)) == BlockType::WALL) {
|
if (getBlock(floorf(vCheckX) + vRound, floorf(vCheckY)) == BlockType::WALL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
vCheckX += vDir;
|
vCheckX += vDir;
|
||||||
vCheckY += vTan;
|
vCheckY += vTan;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We may or may not have hit something. Check which coordinates are closest
|
* We may or may not have hit something. Check which coordinates are closest
|
||||||
* and use those for computing the apparent size on screen.
|
* and use those for computing the apparent size on screen.
|
||||||
*/
|
*/
|
||||||
float hDist = sqrtf((originX - hCheckX)*(originX - hCheckX) +
|
float hDist = sqrtf((originX - hCheckX)*(originX - hCheckX) +
|
||||||
(originY - hCheckY)*(originY - hCheckY));
|
(originY - hCheckY)*(originY - hCheckY));
|
||||||
float vDist = sqrtf((originX - vCheckX)*(originX - vCheckX) +
|
float vDist = sqrtf((originX - vCheckX)*(originX - vCheckX) +
|
||||||
(originY - vCheckY)*(originY - vCheckY));
|
(originY - vCheckY)*(originY - vCheckY));
|
||||||
|
|
||||||
return hDist > vDist ? vDist : hDist;
|
return hDist > vDist ? vDist : hDist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::fillColumn(sf::RenderWindow& window, unsigned int column,
|
void World::fillColumn(sf::RenderWindow& window, unsigned int column,
|
||||||
|
@ -227,51 +227,51 @@ void World::render(sf::RenderWindow& window) const
|
||||||
{
|
{
|
||||||
float windowX = static_cast<float>(window.getSize().x);
|
float windowX = static_cast<float>(window.getSize().x);
|
||||||
float windowY = static_cast<float>(window.getSize().y);
|
float windowY = static_cast<float>(window.getSize().y);
|
||||||
/*
|
/*
|
||||||
* Draw ground and sky planes through half of the screen, as the walls
|
* Draw ground and sky planes through half of the screen, as the walls
|
||||||
* will get drawn over them.
|
* will get drawn over them.
|
||||||
* This doesn't work if we support textures/levels.
|
* This doesn't work if we support textures/levels.
|
||||||
*/
|
*/
|
||||||
sf::RectangleShape ground = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f));
|
sf::RectangleShape ground = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f));
|
||||||
ground.setFillColor(groundColor);
|
ground.setFillColor(groundColor);
|
||||||
ground.setPosition(0,windowY/2.0f);
|
ground.setPosition(0,windowY/2.0f);
|
||||||
|
|
||||||
sf::RectangleShape ceiling = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f));
|
sf::RectangleShape ceiling = sf::RectangleShape(sf::Vector2f(windowX,windowY/2.0f));
|
||||||
ceiling.setFillColor(ceilingColor);
|
ceiling.setFillColor(ceilingColor);
|
||||||
|
|
||||||
window.draw(ground);
|
window.draw(ground);
|
||||||
window.draw(ceiling);
|
window.draw(ceiling);
|
||||||
|
|
||||||
const float worldToCamera = (player.focalLength*2)/player.sensorSize;
|
const float worldToCamera = (player.focalLength*2)/player.sensorSize;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Throw rays and draw walls over the ceiling and ground.
|
* Throw rays and draw walls over the ceiling and ground.
|
||||||
* Only throws in the plane, which doesn't work for levels/3D.
|
* Only throws in the plane, which doesn't work for levels/3D.
|
||||||
*/
|
*/
|
||||||
for(unsigned int i = 0 ; i < window.getSize().x ; i++)
|
for(unsigned int i = 0 ; i < window.getSize().x ; i++)
|
||||||
{
|
{
|
||||||
float deltaAngle = (player.fov/windowX) * (static_cast<float>(i)-windowX/2.0f);
|
float deltaAngle = (player.fov/windowX) * (static_cast<float>(i)-windowX/2.0f);
|
||||||
float rayAngle = player.orientation + deltaAngle;
|
float rayAngle = player.orientation + deltaAngle;
|
||||||
if (rayAngle < 0) {
|
if (rayAngle < 0) {
|
||||||
rayAngle += 360;
|
rayAngle += 360;
|
||||||
} else if (rayAngle > 360) {
|
} else if (rayAngle > 360) {
|
||||||
rayAngle -= 360;
|
rayAngle -= 360;
|
||||||
}
|
}
|
||||||
float obstacleScale = worldToCamera / castRay(player.x, player.y, rayAngle);
|
float obstacleScale = worldToCamera / castRay(player.x, player.y, rayAngle);
|
||||||
/* 2 Is wall height in meters. */
|
/* 2 Is wall height in meters. */
|
||||||
fillColumn(window, i, obstacleScale);
|
fillColumn(window, i, obstacleScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::step(const float& stepTime) {
|
void World::step(const float& stepTime) {
|
||||||
player.move(player.currentMoveSpeedX*stepTime,
|
player.move(player.currentMoveSpeedX*stepTime,
|
||||||
player.currentMoveSpeedY*stepTime);
|
player.currentMoveSpeedY*stepTime);
|
||||||
/* Undo last move if the player would end up in a wall. */
|
/* Undo last move if the player would end up in a wall. */
|
||||||
if (getBlock(player.x, player.y) != BlockType::AIR) {
|
if (getBlock(player.x, player.y) != BlockType::AIR) {
|
||||||
player.move(-player.currentMoveSpeedX*stepTime,
|
player.move(-player.currentMoveSpeedX*stepTime,
|
||||||
-player.currentMoveSpeedY*stepTime);
|
-player.currentMoveSpeedY*stepTime);
|
||||||
}
|
}
|
||||||
player.rotate(player.currentRotationSpeed*stepTime);
|
player.rotate(player.currentRotationSpeed*stepTime);
|
||||||
|
|
||||||
#ifdef IMGUI
|
#ifdef IMGUI
|
||||||
if (ImGui::Begin("MapEdit")) {
|
if (ImGui::Begin("MapEdit")) {
|
||||||
|
|
66
World.h
66
World.h
|
@ -14,54 +14,54 @@
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
|
|
||||||
enum class BlockType {
|
enum class BlockType {
|
||||||
AIR,
|
AIR,
|
||||||
WALL,
|
WALL,
|
||||||
DOOR,
|
DOOR,
|
||||||
WINDOW,
|
WINDOW,
|
||||||
};
|
};
|
||||||
|
|
||||||
class World {
|
class World {
|
||||||
public:
|
public:
|
||||||
Player player;
|
Player player;
|
||||||
|
|
||||||
World(int w, int h,
|
World(int w, int h,
|
||||||
sf::Color groundColor = Colors::Ground,
|
sf::Color groundColor = Colors::Ground,
|
||||||
sf::Color ceilingColor = Colors::Ceiling,
|
sf::Color ceilingColor = Colors::Ceiling,
|
||||||
std::vector<BlockType> worldMap = {});
|
std::vector<BlockType> worldMap = {});
|
||||||
int getW() const;
|
int getW() const;
|
||||||
int getH() const;
|
int getH() const;
|
||||||
|
|
||||||
inline BlockType getBlock(int x, int y) const;
|
inline BlockType getBlock(int x, int y) const;
|
||||||
inline BlockType getBlock(float x, float y) const;
|
inline BlockType getBlock(float x, float y) const;
|
||||||
void setBlock(BlockType block, int x, int y, int width = 1, int height = 1);
|
void setBlock(BlockType block, int x, int y, int width = 1, int height = 1);
|
||||||
|
|
||||||
void render(sf::RenderWindow&) const;
|
void render(sf::RenderWindow&) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Move the world one step forward.
|
* Move the world one step forward.
|
||||||
* @param stepTime delta time since last step, in seconds
|
* @param stepTime delta time since last step, in seconds
|
||||||
*/
|
*/
|
||||||
void step(const float& stepTime);
|
void step(const float& stepTime);
|
||||||
|
|
||||||
friend std::ostream& operator<<(std::ostream& ostream, World const & world);
|
friend std::ostream& operator<<(std::ostream& ostream, World const & world);
|
||||||
private:
|
private:
|
||||||
int w;
|
int w;
|
||||||
int h;
|
int h;
|
||||||
std::vector<BlockType> map;
|
std::vector<BlockType> map;
|
||||||
|
|
||||||
sf::Color groundColor;
|
sf::Color groundColor;
|
||||||
sf::Color ceilingColor;
|
sf::Color ceilingColor;
|
||||||
|
|
||||||
void fillColumn(sf::RenderWindow&, unsigned int column, float scale,
|
void fillColumn(sf::RenderWindow&, unsigned int column, float scale,
|
||||||
sf::Color fillColor = Colors::Wall) const;
|
sf::Color fillColor = Colors::Wall) const;
|
||||||
/**
|
/**
|
||||||
* Cast a ray from a given position and return its distance to the origin.
|
* Cast a ray from a given position and return its distance to the origin.
|
||||||
* @param originX Ray X origin, strictly positive
|
* @param originX Ray X origin, strictly positive
|
||||||
* @param originY Ray Y origin, strictly positive
|
* @param originY Ray Y origin, strictly positive
|
||||||
* @param orientation Angle to cast to, in degrees between 0 and 360
|
* @param orientation Angle to cast to, in degrees between 0 and 360
|
||||||
* @return Distance of the hit to the origin.
|
* @return Distance of the hit to the origin.
|
||||||
*/
|
*/
|
||||||
float castRay(float originX, float originY, float orientation) const;
|
float castRay(float originX, float originY, float orientation) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
86
main.cpp
86
main.cpp
|
@ -12,13 +12,13 @@
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
World world(32,32);
|
World world(32,32);
|
||||||
world.setBlock(BlockType::AIR,1,1,30,30);
|
world.setBlock(BlockType::AIR,1,1,30,30);
|
||||||
world.setBlock(BlockType::WALL,4,4,2,2);
|
world.setBlock(BlockType::WALL,4,4,2,2);
|
||||||
world.player.move(2,2);
|
world.player.move(2,2);
|
||||||
std::cout << world << std::endl;
|
std::cout << world << std::endl;
|
||||||
|
|
||||||
sf::RenderWindow window(sf::VideoMode(1000,1000),"Da raycasting");
|
sf::RenderWindow window(sf::VideoMode(1000,1000),"Da raycasting");
|
||||||
#ifdef IMGUI
|
#ifdef IMGUI
|
||||||
if (!ImGui::SFML::Init(window)) {
|
if (!ImGui::SFML::Init(window)) {
|
||||||
std::cout << "Failed to init Dear ImGui SFML" << std::endl;
|
std::cout << "Failed to init Dear ImGui SFML" << std::endl;
|
||||||
|
@ -31,12 +31,12 @@ int main()
|
||||||
|
|
||||||
// window.setFramerateLimit(60);
|
// window.setFramerateLimit(60);
|
||||||
|
|
||||||
sf::Event event{};
|
sf::Event event{};
|
||||||
sf::Clock frameTime;
|
sf::Clock frameTime;
|
||||||
while (window.isOpen())
|
while (window.isOpen())
|
||||||
{
|
{
|
||||||
while (window.pollEvent(event))
|
while (window.pollEvent(event))
|
||||||
{
|
{
|
||||||
if (event.type == sf::Event::Closed) {
|
if (event.type == sf::Event::Closed) {
|
||||||
window.close();
|
window.close();
|
||||||
continue;
|
continue;
|
||||||
|
@ -56,43 +56,43 @@ int main()
|
||||||
if (io.WantCaptureMouse || io.WantCaptureKeyboard)
|
if (io.WantCaptureMouse || io.WantCaptureKeyboard)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
if (event.type == sf::Event::KeyPressed) {
|
if (event.type == sf::Event::KeyPressed) {
|
||||||
switch (event.key.code) {
|
switch (event.key.code) {
|
||||||
case sf::Keyboard::Key::Escape:
|
case sf::Keyboard::Key::Escape:
|
||||||
window.close();
|
window.close();
|
||||||
break;
|
break;
|
||||||
case sf::Keyboard::Key::Left:
|
case sf::Keyboard::Key::Left:
|
||||||
world.player.currentRotationSpeed = -world.player.rotationSpeed;
|
world.player.currentRotationSpeed = -world.player.rotationSpeed;
|
||||||
break;
|
break;
|
||||||
case sf::Keyboard::Key::Right:
|
case sf::Keyboard::Key::Right:
|
||||||
world.player.currentRotationSpeed = world.player.rotationSpeed;
|
world.player.currentRotationSpeed = world.player.rotationSpeed;
|
||||||
break;
|
break;
|
||||||
case sf::Keyboard::Key::Up:
|
case sf::Keyboard::Key::Up:
|
||||||
world.player.updateSpeed(1, 0);
|
world.player.updateSpeed(1, 0);
|
||||||
break;
|
break;
|
||||||
case sf::Keyboard::Key::Down:
|
case sf::Keyboard::Key::Down:
|
||||||
world.player.updateSpeed(-1, 0);
|
world.player.updateSpeed(-1, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (event.type == sf::Event::KeyReleased) {
|
else if (event.type == sf::Event::KeyReleased) {
|
||||||
switch (event.key.code) {
|
switch (event.key.code) {
|
||||||
case sf::Keyboard::Key::Left:
|
case sf::Keyboard::Key::Left:
|
||||||
case sf::Keyboard::Key::Right:
|
case sf::Keyboard::Key::Right:
|
||||||
world.player.currentRotationSpeed = 0;
|
world.player.currentRotationSpeed = 0;
|
||||||
break;
|
break;
|
||||||
case sf::Keyboard::Key::Up:
|
case sf::Keyboard::Key::Up:
|
||||||
case sf::Keyboard::Key::Down:
|
case sf::Keyboard::Key::Down:
|
||||||
world.player.updateSpeed(0, 0);
|
world.player.updateSpeed(0, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
window.clear();
|
window.clear();
|
||||||
const sf::Time& deltaT = frameTime.restart();
|
const sf::Time& deltaT = frameTime.restart();
|
||||||
|
|
||||||
#ifdef IMGUI
|
#ifdef IMGUI
|
||||||
|
@ -100,7 +100,7 @@ int main()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
world.step(deltaT.asSeconds());
|
world.step(deltaT.asSeconds());
|
||||||
world.render(window);
|
world.render(window);
|
||||||
|
|
||||||
#ifdef IMGUI
|
#ifdef IMGUI
|
||||||
// ImGui::ShowDemoWindow();
|
// ImGui::ShowDemoWindow();
|
||||||
|
@ -126,11 +126,11 @@ int main()
|
||||||
ImGui::SFML::Render(window);
|
ImGui::SFML::Render(window);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
window.display();
|
window.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IMGUI
|
#ifdef IMGUI
|
||||||
ImGui::SFML::Shutdown();
|
ImGui::SFML::Shutdown();
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue