This project is inspired by the world-famous Wolfenstein 3D game, which was the first FPS ever. By the use of ray-casting, the player has a dynamic view inside a maze, in which they have to find their way. Cub3d is a playground to explore the playful practical applications of mathematics without having to understand the specifics. Mathematics are used as a tool to create elegant and efficient algorithms.
This project’s objectives:
- use of C
- use of basic algorithms
- information research etc.
- graphic skills: design, windows, colors, events, fill shapes, etc.
- mathematics in practice
- Clone this repository
git clone https://github.com/mariadaan/cub3d.git
- Create the executable by running make
make
- Execute cub3D with map of your choice (example maps are in the maps folder, use maps/map.cub)
./cub3D filename.cub
Run one of the following commands to try different cub3D environments!
- make residential
- make invalid
- make invalid_res
- make wrongarg
- make non
When you run the cub3d program, the following functions are called from the main.
- init_input: Checks user input. Has an argument with the name of the cub file been given? Does the file exist? If yes, the file will be parsed.
- parse_all: Saves cub file in one long string and calls other functions (parse_res, parse_color, parse_map, get_spawn_pos and parse_tex) to parse all parts of the information in the cub file. This information is saved in the t_info info struct.
- init_textures: Creates an image structure for every texture and saves them in t_tex tex with file_to_img.
- init_mlx: Create the window in which the cub3d project will be shown and create an image called img, that will be modified during the program. Also checks whether resolution is valid and modifies it if necessary in check_res.
- init_raycaster: Set the values that are used by the raycaster algorithm in render.c to the correct starting values. step_size can be modified to change walking speed. const_rad can be modified to change rotation speed. Depending on the spawn direction, player is rotated in the spawn_dir function.
- draw_img: Draws background using draw_bg. Loops over vertical lines to be drawn in image, does raycasting calculations for every line (set_ray_pos, set_ray_len, perform_dda and set_projection), and places the textures on the walls (draw_tex).
- show_img: Place the rendered image on the window so it can be shown.
The hook functions that are called in main make sure that any key press or key release is constantly checked for. When a key has been pressed, check_move moves the player position in the map. After this, draw_img and show_img will be called again to update the image that is shown in the window. This keeps happening until the key is released. When the key is released, moving will stop and the image will not be updated until a key is pressed again. When the esc button or the red cross in the upper left corner is pressed, the program will free all allocated memory and quit the program.
void *mlx; // connection to the correct graphical system,holds the location of our current MLX instance
void *img; // address of image
void *win; // address of
char *addr; // array of colors (length is width in pixels * bpp)
int bits_per_pixel; // usually 4 bytes per pixel
int line_length; // in bytes (width * bpp)
int endian; // order of bytes
int width; // in pixels
int height; // in pixels
// x and y exact player position
double pos_x;
double pos_y;
// direction vector (point straight in front of player)
double dir_x;
double dir_y;
// the 2d raycaster version of camera plane
double plane_x;
double plane_y;
// x-coordinate in camera plane (factor to multiply plane coordinates with)
double camera_x;
// The ray position contains both info about in which square of the map we are, and where in that square we are
double ray_dir_x;
double ray_dir_y;
// which box of the map we're in (just the coordinate of the square, not where in the square)
int map_x;
int map_y;
// length of ray from current position to next x or y-side
// x from pos to FIRST vertical line on the grid (after first hit, distance will remain stable)
double side_dist_x;
// y from pos to FIRST horizontal line on the grid
double side_dist_y;
// distance the ray has to travel to go from 1 x-side to the next x-side, or from 1 y-side to the next y-side.
// from side_dist_x till next vertical line
double delta_dist_x;
// from side_dist_y till next horizontal line
double delta_dist_y;
// length of full ray
double perp_wall_dist;
// what direction to step in x or y-direction (either +1 or -1, just to the next gridline)
int step_x;
int step_y;
// was there a wall hit?
int hit;
// was a NS or a EW wall hit? (0 = x wall hit, 1 = y wall hit)
int side;
double step_size; // constant value in squares
double const_rad; // constant value in radians
int line_height; // real wall height in pixels
int draw_start; // start y coordinate on image
int draw_end; // end y coordinate on image
double wall_x; // where exactly the wall was hit
int x_tex; // x coordinate on the texture
double y_tex; // y coordinate on the texture
double y_tex_step; // y coordinate step size
valgrind --log-file="memleak_logs" ./cub3D maps/jungle.cub