Hi. I am trying to make a raycasting engine out of the Raycasting 3D Adventure code and got stuck in some code. It's clearly because I don't know enough about SFML or programing outside of Unity, which won't stop me from making my engine.
This is the code so far. Apparently there's no Resize function in SFML Vectors so I removed it from line 73.
// Raycasting 3D adventure game, based on http://lodev.org/cgtutor/raycasting.html
// Inspired by seeing https://github.com/TheMozg/awk-raycaster
//
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <stdlib.h>
#include <math.h>
#include <unordered_map>
#include <iostream>
#include <sstream>
#define texWidth 64
#define texHeight 64
#define mapWidth 24
#define mapHeight 24
std::string ConvertToString(int number){
std::ostringstream buff;
buff<<number;
return buff.str();
}
int worldMap[mapWidth][mapHeight]=
{
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1},
{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
int main()
{
sf::Texture texture;
if (!texture.loadFromFile("data/texture/walls.png")) {
fprintf(stderr, "Cannot open texture!\n");
return EXIT_FAILURE;
}
sf::RenderStates state(&texture);
int w = 1024, h = 576;
double posX = 22, posY = 12; //x and y start position
double dirX = -1, dirY = 0; //initial direction vector
double planeX = 0, planeY = 0.66; //the 2d raycaster version of camera plane
double time = 0; //time of current frame
double oldTime = 0; //time of previous frame
sf::Uint32 buffr[h][w];
sf::Vector2i theTexture[8];
for(int i = 0; i < 8; i++) theTexture[i] (texWidth * texHeight); // I think we need a doctor.
// Create the main window
sf::RenderWindow window(sf::VideoMode(w, h), "SFML window");
window.setFramerateLimit(60);
sf::Clock clock = sf::Clock();
sf::Time fps;
// Start the game loop
while (window.isOpen()) {
// Process events
sf::Event event;
while (window.pollEvent(event))
{
// Close window: exit
if (event.type == sf::Event::Closed)
window.close();
// Escape key: exit
if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
window.close();
}
window.clear();
for(int x = 0; x < w; x++)
{
//calculate ray position and direction
double cameraX = 2 * x / double(w) - 1; //x-coordinate in camera space
double rayPosX = posX;
double rayPosY = posY;
double rayDirX = dirX + planeX * cameraX;
double rayDirY = dirY + planeY * cameraX;
//which box of the map we're in
int mapX = int(rayPosX);
int mapY = int(rayPosY);
//length of ray from current position to next x or y-side
double sideDistX;
double sideDistY;
//length of ray from one x or y-side to next x or y-side
double deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
double deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
double perpWallDist;
//what direction to step in x or y-direction (either +1 or -1)
int stepX;
int stepY;
int hit = 0; //was there a wall hit?
int side; //was a NS or a EW wall hit?
//calculate step and initial sideDist
if (rayDirX < 0)
{
stepX = -1;
sideDistX = (rayPosX - mapX) * deltaDistX;
}
else
{
stepX = 1;
sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;
}
if (rayDirY < 0)
{
stepY = -1;
sideDistY = (rayPosY - mapY) * deltaDistY;
}
else
{
stepY = 1;
sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;
}
//perform DDA
while (hit == 0)
{
//jump to next map square, OR in x-direction, OR in y-direction
if (sideDistX < sideDistY)
{
sideDistX += deltaDistX;
mapX += stepX;
side = 0;
}
else
{
sideDistY += deltaDistY;
mapY += stepY;
side = 1;
}
//Check if ray has hit a wall
if (worldMap[mapX][mapY] > 0) hit = 1;
}
//Calculate distance projected on camera direction (oblique distance will give fisheye effect!)
if (side == 0)
perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);
else
perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);
//Calculate height of line to draw on screen
int lineHeight = abs(int(h / perpWallDist));
//calculate lowest and highest pixel to fill in current stripe
int drawStart = -lineHeight / 2 + h / 2;
if(drawStart < 0)drawStart = 0;
int drawEnd = lineHeight / 2 + h / 2;
if(drawEnd >= h)drawEnd = h - 1;
//choose wall color
//sf::Color color;
//switch(worldMap[mapX][mapY])
//{
// case 1: color = sf::Color::Red; break; //red
// case 2: color = sf::Color::Green; break; //green
// case 3: color = sf::Color::Blue; break; //blue
// case 4: color = sf::Color::White; break; //white
// default: color = sf::Color::Yellow; break; //yellow
//}
int texNum = worldMap[mapX] [mapY] - 1;
double wallX;
if(side == 0) wallX = posY + perpWallDist * rayDirY;
else wallX = posX + perpWallDist * rayDirX;
int texX = int(wallX * double(texWidth));
if(side == 0 && rayDirX > 0) texX = texWidth - texX - 1;
if(side == 1 && rayDirX < 0) texX = texWidth - texX - 1;
double step = 1.0 * texHeight / texHeight;
double texPos = (drawStart - h / 2 + lineHeight / 2) * step;
for (int y = drawStart; y<drawEnd; y++) {
int texY = (int)texPos & (texHeight - 1);
texPos += step;
sf::Uint32 color;
if(side == 1) color = (color >> 1) & 8355711;
}
//give x and y sides different brightness
//if (side == 1) {
// color = sf::Color(color.r/2, color.g/2, color.b/2);
//}
//draw the pixels of the stripe as a vertical line
//verLine(x, drawStart, drawEnd, color);
// sf::Vertex line[2] =
//{
// sf::Vertex(sf::Vector2f(x, drawStart), color),
// sf::Vertex(sf::Vector2f(x, drawEnd), color)
//};
// window.draw(line , 2, sf::Lines);
}
fps = clock.getElapsedTime();
float fpsValue = 1000000/fps.asMicroseconds();
clock.restart();
double moveSpeed = fps.asSeconds() * 5.0; //the constant value is in squares/second
double rotSpeed = fps.asSeconds() * 3.0; //the constant value is in radians/second
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left)) {
//both camera direction and camera plane must be rotated
double oldDirX = dirX;
dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed);
dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed);
double oldPlaneX = planeX;
planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed);
planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right)) {
//both camera direction and camera plane must be rotated
double oldDirX = dirX;
dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed);
dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed);
double oldPlaneX = planeX;
planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed);
planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Up)) {
if(worldMap[int(posX + dirX * moveSpeed)][int(posY)] == false) posX += dirX * moveSpeed;
if(worldMap[int(posX)][int(posY + dirY * moveSpeed)] == false) posY += dirY * moveSpeed;
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Down)) {
if(worldMap[int(posX - dirX * moveSpeed)][int(posY)] == false) posX -= dirX * moveSpeed;
if(worldMap[int(posX)][int(posY - dirY * moveSpeed)] == false) posY -= dirY * moveSpeed;
}
window.display();
window.clear();
}
return EXIT_SUCCESS;
}
Help is highly appreciated. Meerjel01