diff --git a/.vscode/settings.json b/.vscode/settings.json index 0ff9eaf..660b980 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,8 @@ "glfw3.h": "c", "vec_math.h": "c", "texture.h": "c", - "libft.h": "c" + "libft.h": "c", + "render.h": "c" }, "cmake.ignoreCMakeListsMissing": true } \ No newline at end of file diff --git a/assets/battery.png b/assets/battery.png new file mode 100644 index 0000000..ebc8ad1 Binary files /dev/null and b/assets/battery.png differ diff --git a/inc/render.h b/inc/render.h index f985813..766e2a8 100644 --- a/inc/render.h +++ b/inc/render.h @@ -1,12 +1,12 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* render.h :+: :+: */ -/* +:+ */ -/* By: whaffman +#+ */ -/* +#+ */ -/* Created: 2025/04/15 16:28:16 by qmennen #+# #+# */ -/* Updated: 2025/05/04 13:21:04 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* render.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/15 16:28:16 by qmennen #+# #+# */ +/* Updated: 2025/05/08 14:50:38 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -22,6 +22,6 @@ void render_clear(t_screen *screen); void render_entities(t_game *game); void render_map(t_screen *screen, t_map *map); void cast_rays(t_game *game); - +void render_sprites(t_render* render, t_game *game); #endif diff --git a/inc/types.h b/inc/types.h index 19b93e7..6940a86 100644 --- a/inc/types.h +++ b/inc/types.h @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/15 15:52:44 by qmennen #+# #+# */ -/* Updated: 2025/05/06 20:03:48 by qmennen ### ########.fr */ +/* Updated: 2025/05/08 14:51:17 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -52,6 +52,15 @@ typedef struct s_player int is_moving; } t_player; +typedef struct s_sprite +{ + int n_frames; + double dist; + double cam_frac; + mlx_texture_t *texture; + t_vec2 pos; +} t_sprite; + typedef struct s_map { unsigned int width; @@ -64,6 +73,8 @@ typedef struct s_map mlx_texture_t *texture_floor; mlx_texture_t *texture_ceiling; mlx_texture_t *textures[4]; + t_sprite *sprites; + unsigned int n_sprites; unsigned int floor_color; unsigned int ceiling_color; } t_map; diff --git a/src/player.c b/src/player.c index e776425..97652ff 100644 --- a/src/player.c +++ b/src/player.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/15 18:53:19 by qmennen #+# #+# */ -/* Updated: 2025/05/06 19:54:42 by qmennen ### ########.fr */ +/* Updated: 2025/05/08 15:51:06 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -59,9 +59,15 @@ static void strave(t_map *map, t_player *player, int dir, double delta) xa = dir * perp(player->dir).x * player->speed * delta; ya = dir * perp(player->dir).y * player->speed * delta; if (xa != 0 && collision_horizontal(map, player, xa)) + { player->pos.x += xa; + player->is_moving = 1; + } if (ya != 0 && collision_vertical(map, player, ya)) + { + player->is_moving = 1; player->pos.y += ya; + } } static void rotate(t_player *player, double rot_speed) diff --git a/src/render/DDAscratch.c b/src/render/DDAscratch.c index 0161277..6d16a94 100644 --- a/src/render/DDAscratch.c +++ b/src/render/DDAscratch.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/05/02 11:58:09 by whaffman #+# #+# */ -/* Updated: 2025/05/06 19:56:47 by qmennen ### ########.fr */ +/* Updated: 2025/05/08 14:51:32 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -224,14 +224,15 @@ void draw_floor(t_game *game) void cast_rays(t_game *game) { int x; - t_render render; + t_render render[WIDTH]; x = 0; draw_floor(game); while (x < game->screen->width) { - render = cast_ray(game, x); - draw_line(game, render, x); + render[x] = cast_ray(game, x); + draw_line(game, render[x], x); x++; } + render_sprites(render, game); } diff --git a/src/render/render_sprite.c b/src/render/render_sprite.c new file mode 100644 index 0000000..d15a84d --- /dev/null +++ b/src/render/render_sprite.c @@ -0,0 +1,156 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* render_sprite.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/05/08 12:23:17 by qmennen #+# #+# */ +/* Updated: 2025/05/08 15:59:32 by qmennen ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "render.h" + +static void sort_sprites(t_game *game) +{ + t_sprite sprite_temp; + int n; + int i; + int new_n; + + n = game->map->n_sprites; + while (n > 1) + { + i = 1; + new_n = 0; + while (i < n - 1) + { + if (game->map->sprites[i - 1].dist < game->map->sprites[i].dist) + { + sprite_temp = game->map->sprites[i - 1]; + game->map->sprites[i - 1] = game->map->sprites[i]; + game->map->sprites[i] = sprite_temp; + new_n = i; + } + i++; + } + n = new_n; + } +} + +static void calculate_sprite_dist(t_game *game) +{ + int i; + t_vec2 player_pos; + + i = 0; + player_pos = game->player->pos; + while (i < game->map->n_sprites) + { + game->map->sprites[i].dist = dist_point_line(game->map->sprites[i].pos, + (t_vec2_line){player_pos, game->player->camera}); + i++; + } +} + +static void cam_fraction(t_game *game, t_sprite *sprite) +{ + t_vec2 ps; + double frac_cam; + double frac_sprite; + double denominator; + + ps = sub(sprite->pos, game->player->pos); + frac_cam = (ps.y * game->player->dir.x - ps.x * game->player->dir.y); + denominator = (ps.x * game->player->camera.y - ps.y * game->player->camera.x); + frac_sprite = (game->player->camera.y * game->player->dir.x - game->player->camera.x * game->player->dir.y); + if (denominator == 0 || (frac_sprite / denominator) < 0) + { + sprite->cam_frac = NAN; + return; + } + sprite->cam_frac = frac_cam / denominator; + if (sprite->cam_frac < -1 || sprite->cam_frac > 1) + { + sprite->cam_frac = NAN; + return; + } + return; +} + +unsigned int sample_texture_color(mlx_texture_t *texture, int x, int y, double dist) +{ + int index; + int alpha; + + alpha = 1.0 / dist * 255; + index = (x + y * texture->width) * texture->bytes_per_pixel; + if (texture->pixels[index + 3] == 0) + { + alpha = 0; + } + return texture->pixels[index] << 24 | texture->pixels[index + 1] << 16 | texture->pixels[index + 2] << 8 | alpha; +} + +void draw_sprite(t_game *game, t_sprite *sprite) +{ + double sprite_scale; + int x_start; + int y_start; + int x_end; + int y_end; + int x; + int y; + double tex_x; + double tex_y; + unsigned int color; + + if (isnan(sprite->cam_frac) || sprite->dist < 1) + return; + sprite_scale = (1 / sprite->dist) * 16; + printf("scale %f, dist: %f\n", sprite_scale, sprite->dist); + x_start = (game->screen->width / 2) * (1 + sprite->cam_frac) - ((sprite->texture->width * sprite_scale) / 2); + y_start = (game->screen->height / 2) - (sprite->texture->height * sprite_scale) / 2 ; + x_end = (game->screen->width / 2) * (1 + sprite->cam_frac) + ((sprite->texture->width * sprite_scale) / 2); + y_end = (game->screen->height / 2) + (sprite->texture->height * sprite_scale) / 2 ; + x = x_start; + y = y_start; + while (y < y_end) + { + if (y < 0 || y >= game->screen->height) + break; + x = (int)x_start; + while (x < x_end) + { + tex_x = ((double)((x - x_start) / (double)(x_end - x_start))) * sprite->texture->width; + tex_y = ((double)((y- y_start) / (double)(y_end - y_start))) * sprite->texture->height; + // printf("\e[1;1H\e[2J"); + // printf("x: %d, y: %d, tex_x: %d, tex_y: %d\n", x, y, (int) tex_x, (int) tex_y); + color = sample_texture_color(sprite->texture, (int)(tex_x), (int)(tex_y), sprite->dist); + if (x < 0 || x >= game->screen->width || y < 0 || y >= game->screen->height || (color & 0xFF) == 0) + { + x++; + continue; + } + mlx_put_pixel(game->screen->img, x, y, color); + x++; + } + y++; + } +} + +void render_sprites(t_render *render, t_game *game) +{ + int i; + + calculate_sprite_dist(game); + sort_sprites(game); + i = 0; + while (i < game->map->n_sprites) + { + cam_fraction(game, &game->map->sprites[i]); + draw_sprite(game, &game->map->sprites[i]); + i++; + } +} \ No newline at end of file diff --git a/src/screen.c b/src/screen.c index 31b05f8..2019167 100644 --- a/src/screen.c +++ b/src/screen.c @@ -6,7 +6,7 @@ /* By: qmennen +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/04/15 15:30:27 by qmennen #+# #+# */ -/* Updated: 2025/05/08 12:09:03 by qmennen ### ########.fr */ +/* Updated: 2025/05/08 15:51:30 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ @@ -35,7 +35,6 @@ int screen_create(t_game **game) screen->background = mlx_new_image(screen->mlx, WIDTH, HEIGHT); if (!screen->background) return (FAILURE); - screen->hud = mlx_texture_to_image(mlx, mlx_load_png("./assets/overlay.png")); (*game)->screen = screen; return (SUCCESS); } diff --git a/src/util/initialize.c b/src/util/initialize.c index 2b79530..72f289c 100644 --- a/src/util/initialize.c +++ b/src/util/initialize.c @@ -1,17 +1,32 @@ /* ************************************************************************** */ /* */ -/* :::::::: */ -/* initialize.c :+: :+: */ -/* +:+ */ -/* By: qmennen +#+ */ -/* +#+ */ -/* Created: 2025/04/22 17:08:26 by qmennen #+# #+# */ -/* Updated: 2025/05/07 11:35:18 by whaffman ######## odam.nl */ +/* ::: :::::::: */ +/* initialize.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: qmennen +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2025/04/22 17:08:26 by qmennen #+# #+# */ +/* Updated: 2025/05/08 14:52:45 by qmennen ### ########.fr */ /* */ /* ************************************************************************** */ #include "cub3d.h" +static int init_temp(t_game **game) +{ + (*game)->map->sprites = malloc(sizeof(t_sprite)); + if (!(*game)->map->sprites) + return (FAILURE); + (*game)->map->sprites[0].n_frames = 1; + (*game)->map->sprites[0].pos.x = 3.5; + (*game)->map->sprites[0].pos.y = 3.5; + (*game)->map->sprites[0].dist = 0; + (*game)->map->sprites[0].texture = mlx_load_png("./assets/battery.png"); + (*game)->map->n_sprites = 1; + (*game)->screen->hud = mlx_texture_to_image((*game)->screen->mlx, mlx_load_png("./assets/overlay.png")); + return (SUCCESS); +} + int initialize_cub3d(t_game **game, const char *mapfile) { if (!game_create(game)) @@ -26,6 +41,8 @@ int initialize_cub3d(t_game **game, const char *mapfile) return (FAILURE); if (!keyboard_create(game)) return (FAILURE); + if (!init_temp(game)) + return (FAILURE); if (!screen_display((*game)->screen)) return (FAILURE); mlx_key_hook((*game)->screen->mlx, keyhandle, *game);