/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* algo.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: greg +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/10/01 16:24:58 by grobledo #+# #+# */ /* Updated: 2024/10/09 03:30:08 by greg ### ########.fr */ /* */ /* ************************************************************************** */ #include "algo.h" #include #include 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,1,1,1,1,1,0,0,0,0,1,0,1,0,1,0,0,0,1}, {1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1}, {1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,0,1,0,1,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,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,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} }; 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->movespeed = 0.1; ray->rotspeed = 0.1; return (0); } static int keypress(int keycode, t_ray *ray, int **worldMap) { //move forward if no wall in front of you if (keycode == 119) { if(worldMap[(int)(ray->posX + ray->dirX * ray->movespeed)][(int)(ray->posY)] == 0) ray->posX += ray->dirX * ray->movespeed; if(worldMap[(int)(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 (keycode == 115) { if(worldMap[(int)(ray->posX - ray->dirX * ray->movespeed)][(int)(ray->posY)] == 0) ray->posX -= ray->dirX * ray->movespeed; if(worldMap[(int)(ray->posX)][((int)ray->posY - (int)ray->dirY * (int)ray->movespeed)] == 0) ray->posY -= ray->dirY * ray->movespeed; } //rotate to the right if (keycode == 100) { //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 (keycode == 97) { //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); } int main(int /*argc*/, char */*argv*/[]) { t_ray ray; int x; double width; double 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); x = 0; width = 640; height = 480; void *mlx_ptr; void *win_ptr; mlx_ptr = mlx_init(); // Initialise la connexion à la MLX win_ptr = mlx_new_window(mlx_ptr, width, height, "cub3d"); 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; drawEnd = lineHeight / 2 + height / 2; if(drawEnd >= height) drawEnd = height - 1; int y = drawStart; while (y <= drawEnd) { mlx_pixel_put(mlx_ptr, win_ptr, x, y, 0xFF0000); y++; } x++; } //draw the pixels of the stripe as a vertical line //verLine(x, drawStart, drawEnd, color); */ // put image to window // destroy old image mlx_hook(win_ptr, 2, 1L<<0, keypress, &ray); 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