42_cub3d/algo.c
2024-10-03 19:00:43 +02:00

194 lines
5.3 KiB
C

/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* algo.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: greg <greg@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/10/01 16:24:58 by grobledo #+# #+# */
/* Updated: 2024/10/03 18:59:06 by greg ### ########.fr */
/* */
/* ************************************************************************** */
#include "algo.h"
static int initalgo(t_ray *ray)
{
ray->posX = 2;
ray->posY = 2;
ray->dirX = -1;
ray->dirY = 0;
ray->planeX = 0;
ray->planeY = 0.66; // FOV de 66 degres
ray->currtime = 0;
ray->oldtime = 0;
ray->movespeed = 0.1;
ray->rotspeed = 0.1;
return (0);
}
int algo()
{
t_ray ray;
int x;
double width;
int height;
// quelle box sur la map on est
int mapX;
int mapY;
// wall hit and if yes in wich direction
int hit;
int side;
initalgo(&ray);
// init image;
x = 0;
width = 640;
height = 480;
while (x < width)
{
// position et direction du rayon
ray.cameraX = 2 * x / width - 1;
ray.raydirX = ray.dirX + ray.planeX * ray.cameraX;
ray.raydirY = ray.dirY + ray.planeY * ray.cameraX;
mapX = (int)ray.posX;
mapY = (int)ray.posY;
ray.deltadistX = (ray.raydirX == 0) ? 1e30 : fabs(1 / ray.raydirX);
ray.deltadistY = (ray.raydirY == 0) ? 1e30 : fabs(1 / ray.raydirY);
hit = 0;
//calculate step and initial sideDist
if (ray.raydirX < 0)
{
ray.stepX = -1;
ray.sidedistX = (ray.posX - mapX) * ray.deltadistX;
}
else
{
ray.stepX = 1;
ray.sidedistX = (mapX + 1.0 - ray.posX) * ray.deltadistX;
}
if (ray.raydirY < 0)
{
ray.stepY = -1;
ray.sidedistY = (ray.posY - mapY) * ray.deltadistY;
}
else
{
ray.stepY = 1;
ray.sidedistY = (mapY + 1.0 - ray.posY) * ray.deltadistY;
}
while(hit == 0)
{
//jump to next map square, either in x-direction, or in y-direction
if(ray.sidedistX < ray.sidedistY)
{
ray.sidedistX += ray.deltadistX;
mapX += ray.stepX;
side = 0;
}
else
{
ray.sidedistY += ray.deltadistY;
mapY += ray.stepY;
side = 1;
}
//Check if ray has hit a wall
if(worldMap[mapX][mapY] == 1)
hit = 1;
}
if(side == 0)
ray.perpwalldist = (ray.sidedistX - ray.deltadistX);
else
ray.perpwalldist = (ray.sidedistY - ray.deltadistY);
//Calculate height of line to draw on screen
int lineHeight = (int)(height / ray.perpwalldist);
lineHeight = (int)(height / ray.perpwalldist);
//calculate lowest and highest pixel to fill in current stripe
int drawStart;
drawStart = -lineHeight / 2 + height / 2;
if(drawStart < 0)
drawStart = 0;
int drawEnd;
if(drawEnd >= height)
drawEnd = height - 1;
/*mlx fontction color
give x and y sides different brightness
if (side == 1) {color = color / 2;}
//draw the pixels of the stripe as a vertical line
verLine(x, drawStart, drawEnd, color); */
//timing for input to dissociate speed from speed processor (same speed on all pc)
ray.oldtime = ray.currtime;
ray.currtime = getTicks();
// put image to window
// destroy old image
// hook event
readKeys();
//move forward if no wall in front of you
if (keyDown(move_up))
{
if(worldMap[(ray.posX + ray.dirX * ray.movespeed)][(int)(ray.posY)] == 0)
ray.posX += ray.dirX * ray.movespeed;
if(worldMap[(ray.posX)][((int)ray.posY + (int)ray.dirY * (int)ray.movespeed)] == 0)
ray.posY += ray.dirY * ray.movespeed;
}
//move backwards if no wall behind you
if (keyDown(moove_down))
{
if(worldMap[(ray.posX - ray.dirX * ray.movespeed)][(int)(ray.posY)] == 0)
ray.posX -= ray.dirX * ray.movespeed;
if(worldMap[(ray.posX)][((int)ray.posY - (int)ray.dirY * (int)ray.movespeed)] == 0)
ray.posY -= ray.dirY * ray.movespeed;
}
//rotate to the right
if (keyDown(moove_right))
{
//both camera direction and camera plane must be rotated
ray.oldDirX = ray.dirX;
ray.dirX = ray.dirX * cos(-ray.rotspeed) - ray.dirY * sin(-ray.rotspeed);
ray.dirY = ray.oldDirX * sin(-ray.rotspeed) + ray.dirY * cos(-ray.rotspeed);
ray.oldPlaneX = ray.planeX;
ray.planeX = ray.planeX * cos(-ray.rotspeed) - ray.planeY * sin(-ray.rotspeed);
ray.planeY = ray.oldPlaneX * sin(-ray.rotspeed) + ray.planeY * cos(-ray.rotspeed);
}
//rotate to the left
if (keyDown(moove_left))
{
//both camera direction and camera plane must be rotated
ray.oldDirX = ray.dirX;
ray.dirX = ray.dirX * cos(ray.rotspeed) - ray.dirY * sin(ray.rotspeed);
ray.dirY = ray.oldDirX * sin(ray.rotspeed) + ray.dirY * cos(ray.rotspeed);
ray.oldPlaneX = ray.planeX;
ray.planeX = ray.planeX * cos(ray.rotspeed) - ray.planeY * sin(ray.rotspeed);
ray.planeY = ray.oldPlaneX * sin(ray.rotspeed) + ray.planeY * cos(ray.rotspeed);
}
}
return (0);
}
// https://github.com/iciamyplant/Cub3d-Linux
// https://lodev.org/cgtutor/raycasting.html
// https://www.youtube.com/watch?v=js7HW65MmNw&list=PL0H9-oZl_QOHM34HvD3DiGmwmj5X7GvTW