so it's a game now

This commit is contained in:
Quinten Mennen 2025-06-03 22:22:04 +02:00
parent df57505ad3
commit 849d5c2cf7
34 changed files with 425 additions and 177 deletions

View File

@ -13,7 +13,9 @@
"mlx42_int.h": "c",
"glad.h": "c",
"game_menu.h": "c",
"game_manager.h": "c"
"game_manager.h": "c",
"collision.h": "c",
"monster.h": "c"
},
"cmake.ignoreCMakeListsMissing": true
}

View File

@ -1,12 +1,12 @@
# **************************************************************************** #
# #
# :::::::: #
# Makefile :+: :+: #
# +:+ #
# By: whaffman <whaffman@student.codam.nl> +#+ #
# +#+ #
# Created: 2024/10/15 11:48:46 by whaffman #+# #+# #
# Updated: 2025/05/29 12:58:16 by whaffman ######## odam.nl #
# ::: :::::::: #
# Makefile :+: :+: :+: #
# +:+ +:+ +:+ #
# By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ #
# +#+#+#+#+#+ +#+ #
# Created: 2024/10/15 11:48:46 by whaffman #+# #+# #
# Updated: 2025/06/03 21:48:38 by qmennen ### ########.fr #
# #
# **************************************************************************** #
@ -47,10 +47,10 @@ SOURCES = $(shell basename -a $(shell find $(SRC_PATH) -type f -name "*.c"))
# Build configurations
BUILD_CONFIGS = release debug asan tsan
release_CFLAGS = -Wall -Werror -Werror -flto -Ofast -march=native -mtune=native -ffast-math
release_CFLAGS = -Wall -Werror -Werror -flto -Ofast -march=native -mtune=native -ffast-math -DFULLSCREEN=0
unity_CFLAGS = -Wall -Werror -Werror -Ofast -march=native -mtune=native -ffast-math
debug_CFLAGS = -Wall -Werror -Werror -g3 -DDEBUG -DDBG='fprintf(stderr, RED "DEBUG: " RESET "%s:%d (%s)\n", __FILE__, __LINE__, __PRETTY_FUNCTION__);'
asan_CFLAGS = -Wall -Werror -Werror -flto -fsanitize=address,leak,undefined -g3
asan_CFLAGS = -Wall -Werror -Werror -flto -fsanitize=address,leak,undefined -g3 -DFULLSCREEN=0
tsan_CFLAGS = -Wall -Werror -Werror -fsanitize=thread -g3
RUN_ARGS=test.cub

BIN
assets/end_screen.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

BIN
assets/end_screen.xcf Normal file

Binary file not shown.

View File

@ -25,6 +25,7 @@ uniform float u_time;
uniform float u_battery;
uniform vec2 u_resolution;
uniform float u_hit_timer;
uniform int u_enabled;
float rand(vec2 co) {
return fract(sin(dot(co.xy, vec2(12.9898,78.233))) * 43758.5453);
@ -60,6 +61,10 @@ void main()
case 15: texColor = texture(Texture15, TexCoord); break;
default: texColor = vec4(1.0, 0.0, 0.0, 1.0); break;
}
if (u_enabled == 0) {
FragColor = texColor;
return;
}
if (TexIndex == 1) {
vec2 uv = gl_FragCoord.xy / u_resolution.xy;
uv.x *= u_resolution.x / u_resolution.y;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* collision.h :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/04/22 14:40:47 by qmennen #+# #+# */
/* Updated: 2025/05/23 15:11:20 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* collision.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/22 14:40:47 by qmennen #+# #+# */
/* Updated: 2025/06/03 21:24:43 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,7 +17,7 @@
int collision_horizontal(t_map *map, t_player *player, double xa);
int collision_vertical(t_map *map, t_player *player, double ya);
int collision_sprite(t_map *map, t_player *player, double xa, double ya);
int collision_sprite(t_game *game, double xa, double ya);
void collect(t_player *player);
#endif

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 12:22:29 by qmennen #+# #+# */
/* Updated: 2025/06/03 15:50:37 by qmennen ### ########.fr */
/* Updated: 2025/06/03 22:09:53 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -20,6 +20,10 @@
# define HEIGHT 1080
# define TITLE "Cub3D"
#ifndef FULLSCREEN
# define FULLSCREEN 1
#endif
# ifndef M_PI
# define M_PI 3.14159265358979323846
# endif
@ -34,6 +38,7 @@
# define CYAN "\033[0;36m"
# define WHITE "\033[0;37m"
# define MAX_SCREENSHOTS 3
# define NUM_KEYS 300
# define TILE_SIZE 8
# define MINIMAP_SIZE 300
@ -61,8 +66,11 @@
# include "game_menu.h"
# include "monster.h"
int initialize_cub3d(t_game **game, const char *mapfile);
int shader_init(t_game **game);
void set_uniforms(t_game *game);
int initialize_cub3d(t_game **game, const char *mapfile);
int shader_init(t_game **game);
void set_uniforms(t_game *game);
int load_uniforms(t_game **game);
void count_scores(t_game *game);
int count_tiles(t_map *map, t_tile tile_type);
#endif

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 15:46:16 by qmennen #+# #+# */
/* Updated: 2025/05/28 14:28:02 by qmennen ### ########.fr */
/* Updated: 2025/06/03 15:54:12 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -24,5 +24,6 @@ void print_scores(t_game *game);
void game_run(t_game *game);
void handle_battery(t_game *game);
void handle_record(t_game *game);
void handle_flash(t_sprite *sprite, t_game *game);
#endif

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/27 15:07:48 by qmennen #+# #+# */
/* Updated: 2025/05/28 14:53:54 by qmennen ### ########.fr */
/* Updated: 2025/06/03 19:15:44 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,6 +16,8 @@
# include "cub3d.h"
void menu_display(t_menu *menu, t_screen *screen);
void draw_end_screen(t_game_manager *manager, t_menu *menu);
t_menu *create_end_screen(t_game_manager *manager);
mlx_image_t *menu_load_background(mlx_t *mlx, char *background_path);
t_menu *create_main_menu(t_game_manager *manager);
t_menu *menu_create(t_game_manager *manager, char *b_path,

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* screen.h :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/04/15 15:30:34 by qmennen #+# #+# */
/* Updated: 2025/05/14 12:43:47 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* screen.h :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 15:30:34 by qmennen #+# #+# */
/* Updated: 2025/06/03 19:44:17 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -17,5 +17,6 @@
int screen_create(t_game **game);
int screen_display(t_screen *screen);
void fill_background(mlx_image_t *image, int color);
#endif

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 15:52:44 by qmennen #+# #+# */
/* Updated: 2025/06/03 14:41:00 by qmennen ### ########.fr */
/* Updated: 2025/06/03 21:55:47 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -120,6 +120,11 @@ typedef struct s_screen
mlx_image_t *hud;
unsigned int width;
unsigned int height;
int u_time_location;
int u_battery_location;
int u_resolution_location;
int u_hit_timer_location;
int u_enabled_location;
int flash;
} t_screen;
@ -135,6 +140,7 @@ typedef enum e_game_state
{
GAME_STATE_MENU,
GAME_STATE_PLAYING,
GAME_STATE_END_SCREEN,
} t_game_state;
typedef struct s_render
@ -151,16 +157,29 @@ typedef struct s_sprite_column
int x;
} t_sprite_column;
typedef struct s_scoreboard
{
int tiles_visited;
int total_tiles;
int collectibles;
int enemies;
mlx_image_t *tiles_text;
mlx_image_t *collectibles_text;
mlx_image_t *battery_text;
mlx_image_t *enemies_text;
} t_scoreboard;
typedef struct s_game
{
t_map *map;
t_player *player;
t_screen *screen;
t_keyboard *keyboard;
double elapsed_time;
int fps;
t_map *map;
t_player *player;
t_screen *screen;
t_keyboard *keyboard;
t_scoreboard *scoreboard;
mlx_image_t *screenshots[MAX_SCREENSHOTS];
struct s_game_manager *manager;
int fps;
int screenshot_idx;
} t_game;
typedef struct s_game_manager
@ -185,8 +204,6 @@ typedef struct s_menu
int num_options;
int hidden;
t_menu_item *items[MAX_MENU_OPTIONS];
// char *options[MAX_MENU_OPTIONS];
// mlx_image_t *option_images[MAX_MENU_OPTIONS];
mlx_image_t *selector;
mlx_image_t *background;

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/22 14:40:59 by qmennen #+# #+# */
/* Updated: 2025/06/03 15:18:54 by qmennen ### ########.fr */
/* Updated: 2025/06/03 22:12:38 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,11 +19,15 @@ void collect(t_player *player)
player->battery = 1.f;
}
int collision_sprite(t_map *map, t_player *player, double xa, double ya)
int collision_sprite(t_game *game, double xa, double ya)
{
t_player *player;
t_map *map;
t_sprite *sprites;
int i;
player = game->player;
map = game->map;
sprites = map->sprites;
i = 0;
while (i < map->n_sprites)
@ -35,13 +39,14 @@ int collision_sprite(t_map *map, t_player *player, double xa, double ya)
{
if (sprites[i].type == SPRITE_TYPE_ENEMY)
{
player->battery -= 0.0001;
player->battery -= 0.001;
player->hit_timer = .65f;
}
else
{
sprites[i].type = SPRITE_TYPE_COLLECTED;
collect(player);
game->scoreboard->collectibles++;
}
return (1);
}

23
src/game/flash.c Normal file
View File

@ -0,0 +1,23 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* flash.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 15:53:32 by qmennen #+# #+# */
/* Updated: 2025/06/03 22:18:26 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "game.h"
void handle_flash(t_sprite *sprite, t_game *game)
{
if (sprite->type == SPRITE_TYPE_ENEMY && game->screen->flash == 1
&& sprite->dist < 2.0)
{
sprite->type = SPRITE_TYPE_DISABLED;
game->scoreboard->enemies++;
}
}

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 15:46:08 by qmennen #+# #+# */
/* Updated: 2025/06/03 14:16:16 by qmennen ### ########.fr */
/* Updated: 2025/06/03 22:09:28 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,28 +19,31 @@ int game_create(t_game **game)
return (FAILURE);
ft_memset(*game, 0, sizeof(t_game));
(*game)->fps = 20;
return (SUCCESS);
(*game)->scoreboard = malloc(sizeof(t_scoreboard));
if (!(*game)->scoreboard)
{
return (free(*game), FAILURE);
}
return (SUCCESS);
}
void free_game(t_game **game)
void game_over(t_game_manager *manager)
{
if (game && *game)
{
if ((*game)->screen)
free((*game)->screen);
if ((*game)->player)
free((*game)->player);
if ((*game)->map)
free((*game)->map);
free(*game);
}
t_game *game;
game = manager->game;
game->screen->hud->instances[0].enabled = false;
game->screen->minimap->instances[0].enabled = false;
game->screen->img->instances[0].enabled = false;
manager->state = GAME_STATE_END_SCREEN;
manager->active_menu = &manager->end_screen;
set_uniforms(game);
}
void game_run(t_game *game)
{
static int fps = 0;
game->elapsed_time += game->screen->mlx->delta_time;
fps += (int)(1.f / game->screen->mlx->delta_time);
set_uniforms(game);
player_update(game, game->screen->mlx->delta_time);
@ -49,12 +52,15 @@ void game_run(t_game *game)
render_map(game);
if (game->player->is_moving)
{
game->screen->img->instances[0].x = sin(game->elapsed_time * 10) * 20;
game->screen->img->instances[0].y = cos(game->elapsed_time * 18) * 10;
game->screen->img->instances[0].x = sin(mlx_get_time() * 10) * 20;
game->screen->img->instances[0].y = cos(mlx_get_time() * 18) * 10;
}
handle_battery(game);
handle_record(game);
collision_sprite(game->map, game->player, 0, 0);
collision_sprite(game, 0, 0);
if (game->player->battery <= 0 || count_tiles(game->map, TILE_EMPTY) == 0)
game_over(game->manager);
}
void game_free(t_game *game)
@ -67,9 +73,6 @@ void game_free(t_game *game)
game->screen->hud = NULL;
}
mlx_delete_image(game->screen->mlx, game->screen->img);
mlx_close_window(game->screen->mlx);
mlx_terminate(game->screen->mlx);
free(game->screen);
}
if (game->player)
free(game->player);
@ -77,7 +80,6 @@ void game_free(t_game *game)
map_free(game->map);
if (game->keyboard)
free(game->keyboard);
free(game);
}
void game_terminate(t_game *game)

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* game_hud.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/05/28 14:26:29 by qmennen #+# #+# */
/* Updated: 2025/05/29 11:07:12 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* game_hud.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/28 14:26:29 by qmennen #+# #+# */
/* Updated: 2025/06/03 19:22:47 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -57,7 +57,8 @@ void handle_battery(t_game *game)
if (game->player->battery < 0)
{
game->player->battery = 0;
game_terminate(game);
game->manager->state = GAME_STATE_MENU;
// game_terminate(game);
}
draw_battery(game->screen->minimap, game->player->battery);
}
@ -68,7 +69,7 @@ void handle_record(t_game *game)
int x;
int y;
flash = ((int) game->elapsed_time) % 2;
flash = (int) mlx_get_time() % 2;
y = -15;
while (y <= 15)
{

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/14 20:08:27 by whaffman #+# #+# */
/* Updated: 2025/06/03 15:10:49 by qmennen ### ########.fr */
/* Updated: 2025/06/03 22:13:43 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* main.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/04/15 16:01:29 by qmennen #+# #+# */
/* Updated: 2025/06/03 13:43:05 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* main.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 16:01:29 by qmennen #+# #+# */
/* Updated: 2025/06/03 19:30:56 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -21,7 +21,6 @@ int main(int argc, char **argv)
game = NULL;
if (!valid_arguments(argc, argv))
return (EXIT_FAILURE);
shader_init(&game);
if (!initialize_cub3d(&game, argv[1]))
{
perror("initialize_cub3d");
@ -30,8 +29,9 @@ int main(int argc, char **argv)
}
manager = game_manager_create(game);
manager->menu = create_main_menu(manager);
manager->end_screen = create_end_screen(manager);
manager->active_menu = &manager->menu;
mlx_key_hook(game->screen->mlx, keyhandle, game);
mlx_key_hook(game->screen->mlx, keyhandle, manager);
mlx_loop_hook(game->screen->mlx, game_manager_update, manager);
mlx_loop(game->screen->mlx);
game_manager_destroy(manager);

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/27 13:48:18 by qmennen #+# #+# */
/* Updated: 2025/06/03 14:55:46 by qmennen ### ########.fr */
/* Updated: 2025/06/03 20:49:50 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -22,6 +22,7 @@ t_game_manager *game_manager_create(t_game *game)
manager->game = game;
manager->menu = NULL;
manager->state = GAME_STATE_MENU;
game->manager = manager;
return (manager);
}
@ -36,6 +37,8 @@ void game_manager_display(t_game_manager *manager)
menu_display(*(manager->active_menu), game->screen);
else if (manager->state == GAME_STATE_PLAYING)
game_run(game);
else if (manager->state == GAME_STATE_END_SCREEN)
draw_end_screen(manager, manager->end_screen);
}
void game_manager_update(void *param)
@ -58,9 +61,11 @@ void game_manager_destroy(t_game_manager *manager)
menu_free(manager->end_screen, manager->game->screen);
print_scores(manager->game);
if (manager->game)
{
game_free(manager->game);
}
mlx_close_window(manager->game->screen->mlx);
mlx_terminate(manager->game->screen->mlx);
free(manager->game->screen);
free(manager->game);
free(manager);
exit(EXIT_SUCCESS);
}

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/27 15:22:15 by qmennen #+# #+# */
/* Updated: 2025/05/28 15:03:04 by qmennen ### ########.fr */
/* Updated: 2025/06/03 20:35:05 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -38,7 +38,7 @@ void game_manager_handle_input(t_game_manager *manager)
if (get_key_up(manager->game, MLX_KEY_UP))
{
(*manager->active_menu)->selected_option--;
if (manager->menu->selected_option < 0)
manager->menu->selected_option = manager->menu->num_options - 1;
if ((*manager->active_menu)->selected_option < 0)
(*manager->active_menu)->selected_option = (*manager->active_menu)->num_options - 1;
}
}

120
src/menu/end_screen.c Normal file
View File

@ -0,0 +1,120 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* end_screen.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/06/03 16:20:35 by qmennen #+# #+# */
/* Updated: 2025/06/03 22:07:06 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "game_menu.h"
static void slideshow(t_game *game)
{
static int frame_idx = 0;
static int last_frame_time;
if (game->screenshots[frame_idx])
game->screenshots[frame_idx]->instances[0].enabled = true;
if (last_frame_time == 0)
last_frame_time = mlx_get_time();
if (mlx_get_time() - last_frame_time > 5 && frame_idx < game->screenshot_idx && frame_idx < MAX_SCREENSHOTS) {
game->screenshots[frame_idx++]->instances[0].enabled = true;
game->screenshots[frame_idx - 1]->instances[0].enabled = false;
last_frame_time = mlx_get_time();
frame_idx %= (MAX_SCREENSHOTS < game->screenshot_idx) * MAX_SCREENSHOTS + (MAX_SCREENSHOTS >= game->screenshot_idx) * game->screenshot_idx;
}
}
char *get_score_text(char *prefix, char *suffix, int score)
{
char *score_text;
char *score_complete;
char *score_value;
score_text = ft_itoa(score);
if (!score_text)
return (NULL);
score_value = ft_strjoin(prefix, score_text);
free(score_text);
if (!score_value)
return (NULL);
if (!suffix)
return (score_value);
score_complete = ft_strjoin(score_value, suffix);
free(score_value);
return (score_complete);
}
static mlx_image_t *draw_score_line(mlx_t *mlx, char *text, int x, int y)
{
mlx_image_t *image;
if (!text)
return (NULL);
image = mlx_put_string(mlx, text, x, y);
free(text);
return (image);
}
void draw_end_screen(t_game_manager *manager, t_menu *menu)
{
char *tiles_score;
char *battery_percentage;
char *collectibles_score;
char *enemies_score;
t_game *game;
if (!manager || !manager->game)
return ;
game = manager->game;
slideshow(game);
if (menu->hidden)
{
menu_toggle(menu, game->screen);
count_scores(game);
}
menu->selector->instances[0].y = manager->game->screen->height / 2
+ menu->selected_option * 50;
tiles_score = get_score_text("Discovered area: ", "%",
(double) game->scoreboard->tiles_visited / game->scoreboard->total_tiles * 100);
game->scoreboard->tiles_text = draw_score_line(game->screen->mlx,
tiles_score, 100, game->screen->height / 2 - 50);
battery_percentage = get_score_text("Battery percentage: ",
"%", (double) game->player->battery * 100);
game->scoreboard->battery_text = draw_score_line(game->screen->mlx,
battery_percentage, 100, game->screen->height / 2);
collectibles_score = get_score_text("Batteries found: ", NULL,
game->scoreboard->collectibles);
game->scoreboard->collectibles_text = draw_score_line(game->screen->mlx,
collectibles_score, 100, game->screen->height / 2 + 50);
enemies_score = get_score_text("Enemies defeated: ", NULL,
game->scoreboard->enemies);
game->scoreboard->enemies_text = draw_score_line(game->screen->mlx,
enemies_score, 100, game->screen->height / 2 + 100);
}
static void game_exit(struct s_menu_item *item, t_game_manager *manager)
{
(void)item;
game_manager_destroy(manager);
}
t_menu *create_end_screen(t_game_manager *manager)
{
const t_menu_item *menu_items[] = {
menu_item_create(manager->game->screen, "Room discovery: ", game_exit),
NULL
};
t_menu *menu;
menu = menu_create(manager, "assets/end_screen.png", menu_items);
menu->items[0]->image->instances[0].x = 100;
menu->items[0]->image->instances[0].y = manager->game->screen->height / 2;
if (!menu)
return (NULL);
return (menu);
}

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/28 14:14:11 by qmennen #+# #+# */
/* Updated: 2025/06/03 14:19:45 by qmennen ### ########.fr */
/* Updated: 2025/06/03 20:15:01 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -26,16 +26,8 @@ static void game_start(struct s_menu_item *item, t_game_manager *manager)
(void)item;
game = manager->game;
screen = game->screen;
if (mlx_image_to_window(screen->mlx, screen->minimap, 175, 575) < 0)
{
printf(RED "Failed to display buffer image\n" RESET);
game_terminate(game);
}
if (mlx_image_to_window(screen->mlx, screen->hud, 0, 0) < 0)
{
printf(RED "Failed to display buffer image\n" RESET);
game_terminate(game);
}
game->screen->minimap->instances[0].enabled = true;
game->screen->hud->instances[0].enabled = true;
menu_toggle(*(manager->active_menu), screen);
manager->state = GAME_STATE_PLAYING;
}
@ -50,7 +42,7 @@ t_menu *create_main_menu(t_game_manager *manager)
};
t_menu *menu;
menu = menu_create(manager, "./assets/menu_background.png", menu_items);
menu = menu_create(manager, "./assets/surveillor_background.png", menu_items);
if (!menu)
return (NULL);
return (menu);

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/27 14:31:53 by qmennen #+# #+# */
/* Updated: 2025/06/03 14:22:52 by qmennen ### ########.fr */
/* Updated: 2025/06/03 20:16:52 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -25,13 +25,14 @@ t_menu *menu_create(t_game_manager *manager, char *b_path,
if (b_path)
menu->background = menu_load_background(
manager->game->screen->mlx, b_path);
if (mlx_image_to_window(
if (b_path && mlx_image_to_window(
manager->game->screen->mlx, menu->background, 0, 0) < 0)
{
mlx_delete_image(manager->game->screen->mlx, menu->background);
return (free(menu), NULL);
}
menu->background->instances[0].enabled = false;
if (menu->background)
menu->background->instances[0].enabled = false;
menu->hidden = 1;
i = -1;
while (options[++i])
@ -52,13 +53,12 @@ void menu_display(t_menu *menu, t_screen *screen)
half_h = screen->height / 2;
if (menu->hidden)
menu_toggle(menu, screen);
menu->selector->instances[0].x = half_w - 100;
menu->selector->instances[0].x = 150;
menu->selector->instances[0].y = half_h + menu->selected_option * 50;
i = 0;
while (i < menu->num_options)
{
menu->items[i]->image->instances[0].x = (screen->width
- ft_strlen(menu->items[i]->text) * 10) / 2;
menu->items[i]->image->instances[0].x = 200;
menu->items[i]->image->instances[0].y = half_h + i * 50;
i++;
}
@ -93,9 +93,8 @@ void menu_free(t_menu *menu, t_screen *screen)
while (i < menu->num_options)
{
if (menu->items[i]->image)
{
mlx_delete_image(screen->mlx, menu->items[i]->image);
}
free(menu->items[i]);
i++;
}
if (menu->selector)

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/28 13:50:14 by qmennen #+# #+# */
/* Updated: 2025/05/28 15:12:45 by qmennen ### ########.fr */
/* Updated: 2025/06/03 16:23:36 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -24,6 +24,7 @@ t_menu_item *menu_item_create(t_screen *screen, const char *text,
item->text = (char *)text;
item->act = act;
item->image = mlx_put_string(screen->mlx, text, 0, 0);
// mlx_resize_image(item->image, 200, 50);
item->image->instances[0].enabled = false;
return (item);
}

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* parse_config_line.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/04/22 13:10:06 by whaffman #+# #+# */
/* Updated: 2025/06/03 14:40:15 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* parse_config_line.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/22 13:10:06 by whaffman #+# #+# */
/* Updated: 2025/06/03 16:16:56 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -16,7 +16,7 @@ mlx_texture_t *load_texture(const char *path)
{
mlx_texture_t *texture;
printf("Loading texture: |%s|\n", path);
// printf("Loading texture: |%s|\n", path);
texture = mlx_load_png(path);
if (texture == NULL)
{
@ -39,7 +39,7 @@ t_token_handler handle_config_token(const char *token, t_map *map)
int i;
i = 0;
printf("Token: %s\n", token);
// printf("Token: %s\n", token);
while (config_tokens[i] != NULL)
{
if (ft_strcmp(token, config_tokens[i]) == 0)

View File

@ -1,17 +1,54 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* render.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/04/15 16:28:10 by qmennen #+# #+# */
/* Updated: 2025/06/03 13:38:16 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* render.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 16:28:10 by qmennen #+# #+# */
/* Updated: 2025/06/03 22:17:23 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
#include "cub3d.h"
void create_screenshot(t_game *game)
{
int i;
int j;
int idx1;
int idx2;
mlx_image_t *screenshot;
if (!game->screenshots[game->screenshot_idx % MAX_SCREENSHOTS])
{
game->screenshots[game->screenshot_idx % MAX_SCREENSHOTS] = mlx_new_image(game->screen->mlx, game->screen->width / 3, game->screen->height / 3);
mlx_image_to_window(game->screen->mlx, game->screenshots[game->screenshot_idx % MAX_SCREENSHOTS], 1000, 250);
game->screenshots[game->screenshot_idx % MAX_SCREENSHOTS]->instances[0].enabled = false;
}
screenshot = game->screenshots[game->screenshot_idx % MAX_SCREENSHOTS];
if (!screenshot)
return ;
i = 0;
while (i < game->screen->height / 3)
{
j = 0;
while (j < game->screen->width / 3)
{
idx1 = (i * game->screen->width / 3 + j) * 4;
idx2 = (i * game->screen->img->width + j) * 12;
screenshot->pixels[idx1] = game->screen->img->pixels[idx2];
screenshot->pixels[idx1 + 1] = game->screen->img->pixels[idx2 + 1];
screenshot->pixels[idx1 + 2] = game->screen->img->pixels[idx2 + 2];
screenshot->pixels[idx1 + 3] = game->screen->img->pixels[idx2 + 3];
j++;
}
i++;
}
printf("Screenshot %d taken\n", game->screenshot_idx);
game->screenshot_idx++;
return ;
}
void flash(t_game *game)
{
mlx_image_t *img;
@ -21,7 +58,8 @@ void flash(t_game *game)
if (game->screen->flash == 0)
return ;
img = game->screen->img;
game->screen->flash--;
if (game->screen->flash == 2)
create_screenshot(game);
x = 0;
while (x < img->width)
{
@ -33,6 +71,7 @@ void flash(t_game *game)
}
x++;
}
game->screen->flash--;
}
void cast_rays(t_game *game)

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/08 12:23:17 by qmennen #+# #+# */
/* Updated: 2025/06/03 15:00:43 by qmennen ### ########.fr */
/* Updated: 2025/06/03 22:15:19 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -48,7 +48,7 @@ static void draw_sprite_column(
unsigned int color;
int frame;
frame = (game->elapsed_time * sprite->animation_speed);
frame = (mlx_get_time() * sprite->animation_speed);
frame %= sprite->n_frames;
inv_range.y = 1.0 / (column.end.y - column.start.y);
inv_range.x = 1.0 / (column.end.x - column.start.x);
@ -69,13 +69,6 @@ static void draw_sprite_column(
}
}
void handle_flash(t_sprite *sprite, t_game *game)
{
if (sprite->type == SPRITE_TYPE_ENEMY && game->screen->flash > 0
&& sprite->dist < 2.0)
sprite->type = SPRITE_TYPE_DISABLED;
}
void draw_sprite(t_game *game, t_sprite *sprite, t_render *render)
{
t_vec2_int start;

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 15:30:27 by qmennen #+# #+# */
/* Updated: 2025/06/03 15:47:36 by qmennen ### ########.fr */
/* Updated: 2025/06/03 20:20:36 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -23,7 +23,7 @@ int screen_create(t_game **game)
ft_memset(screen, 0, sizeof(t_screen));
screen->width = WIDTH;
screen->height = HEIGHT;
mlx_set_setting(MLX_FULLSCREEN, 1);
mlx_set_setting(MLX_FULLSCREEN, FULLSCREEN);
mlx = mlx_init(WIDTH, HEIGHT, TITLE, true);
if (!mlx)
return (FAILURE);
@ -41,18 +41,18 @@ int screen_create(t_game **game)
return (SUCCESS);
}
void fill_background(t_screen *screen, int color)
void fill_background(mlx_image_t *image, int color)
{
int i;
int j;
i = 0;
while (i < screen->width)
while (i < image->width)
{
j = 0;
while (j < screen->height)
while (j < image->height)
{
mlx_put_pixel(screen->background, i, j, color);
mlx_put_pixel(image, i, j, color);
j++;
}
i++;
@ -68,10 +68,7 @@ int center_window(t_screen *screen)
m_height = 0;
mlx_get_monitor_size(0, &m_width, &m_height);
if (m_width == 0 || m_height == 0)
{
printf(RED"Failed to retrieve monitor size to center window\n"RESET);
return (FAILURE);
}
mlx_set_window_pos(screen->mlx, (m_width - screen->width) / 2,
(m_height - screen->height) / 2);
return (SUCCESS);
@ -79,18 +76,21 @@ int center_window(t_screen *screen)
int screen_display(t_screen *screen)
{
fill_background(screen, 0x000000FF);
if (mlx_image_to_window(screen->mlx, screen->background, 0, 0) < 0)
int display_error;
fill_background(screen->background, 0x000000FF);
display_error = 0;
display_error |= mlx_image_to_window(screen->mlx, screen->background, 0, 0) < 0;
display_error |= mlx_image_to_window(screen->mlx, screen->img, 0, 0) < 0;
display_error |= mlx_image_to_window(screen->mlx, screen->minimap, 175, 575) < 0;
display_error |= mlx_image_to_window(screen->mlx, screen->hud, 0, 0) < 0;
if (display_error || !center_window(screen))
{
printf(RED"Failed to display buffer image\n"RESET);
printf(RED "Display failed to initialize\n" RESET);
return (FAILURE);
}
if (mlx_image_to_window(screen->mlx, screen->img, 0, 0) < 0)
{
printf(RED"Failed to display buffer image\n"RESET);
return (FAILURE);
}
if (!center_window(screen))
return (FAILURE);
screen->hud->instances[0].enabled = false;
screen->minimap->instances[0].enabled = false;
return (SUCCESS);
}

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/08 18:27:59 by qmennen #+# #+# */
/* Updated: 2025/06/03 14:41:38 by qmennen ### ########.fr */
/* Updated: 2025/06/03 19:34:08 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,14 +19,32 @@ void set_uniforms(t_game *game)
mlx_ctx_t *ctx;
ctx = (mlx_ctx_t *)game->screen->mlx->context;
glUniform1f(glGetUniformLocation(ctx->shaderprogram, "u_time"),
glfwGetTime());
glUniform1f(glGetUniformLocation(ctx->shaderprogram, "u_battery"),
game->player->battery);
glUniform2f(glGetUniformLocation(ctx->shaderprogram, "u_resolution"),
game->screen->width, game->screen->height);
glUniform1f(glGetUniformLocation(ctx->shaderprogram, "u_hit_timer"),
game->player->hit_timer);
glUniform1f(game->screen->u_time_location, (float)mlx_get_time());
glUniform1f(game->screen->u_battery_location, game->player->battery);
glUniform2f(game->screen->u_resolution_location,
(float)game->screen->width, (float)game->screen->height);
glUniform1f(game->screen->u_hit_timer_location, game->player->hit_timer);
glUniform1i(game->screen->u_enabled_location,
game->manager->state == GAME_STATE_PLAYING);
}
int load_uniforms(t_game **game)
{
mlx_ctx_t *ctx;
ctx = (mlx_ctx_t *)(*game)->screen->mlx->context;
(*game)->screen->u_time_location = glGetUniformLocation(ctx->shaderprogram, "u_time");
(*game)->screen->u_battery_location = glGetUniformLocation(ctx->shaderprogram, "u_battery");
(*game)->screen->u_hit_timer_location = glGetUniformLocation(ctx->shaderprogram, "u_hit_timer");
(*game)->screen->u_enabled_location = glGetUniformLocation(ctx->shaderprogram, "u_enabled");
(*game)->screen->u_resolution_location = glGetUniformLocation(ctx->shaderprogram, "u_resolution");
if ((*game)->screen->u_time_location < 0 ||
(*game)->screen->u_battery_location < 0 ||
(*game)->screen->u_hit_timer_location < 0 ||
(*game)->screen->u_enabled_location < 0 ||
(*game)->screen->u_resolution_location < 0)
return (FAILURE);
return (SUCCESS);
}
static const char *read_vertex_shader(void)

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/15 17:51:26 by qmennen #+# #+# */
/* Updated: 2025/04/17 19:57:35 by qmennen ### ########.fr */
/* Updated: 2025/06/03 16:11:46 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -14,9 +14,9 @@
void keyhandle(mlx_key_data_t keydata, void *param)
{
t_game *game;
t_game_manager *manager;
game = (t_game *)param;
manager = (t_game_manager *)param;
if (keydata.key == MLX_KEY_ESCAPE)
game_terminate(game);
game_manager_destroy(manager);
}

View File

@ -1,12 +1,12 @@
/* ************************************************************************** */
/* */
/* :::::::: */
/* initialize.c :+: :+: */
/* +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ */
/* +#+ */
/* Created: 2025/04/22 17:08:26 by qmennen #+# #+# */
/* Updated: 2025/06/03 13:41:33 by whaffman ######## odam.nl */
/* ::: :::::::: */
/* initialize.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/04/22 17:08:26 by qmennen #+# #+# */
/* Updated: 2025/06/03 19:31:25 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -47,8 +47,12 @@ int initialize_cub3d(t_game **game, const char *mapfile)
return (FAILURE);
if (!texture_load(*game))
return (FAILURE);
if (!shader_init(game))
return (FAILURE);
if (!screen_create(game))
return (FAILURE);
if (!load_uniforms(game))
return (FAILURE);
if (!keyboard_create(game))
return (FAILURE);
if (!init_temp(game))

View File

@ -6,7 +6,7 @@
/* By: qmennen <qmennen@student.codam.nl> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2025/05/25 20:54:23 by whaffman #+# #+# */
/* Updated: 2025/05/28 17:14:53 by qmennen ### ########.fr */
/* Updated: 2025/06/03 21:42:54 by qmennen ### ########.fr */
/* */
/* ************************************************************************** */
@ -63,3 +63,13 @@ void print_scores(t_game *game)
printf("Seen %d of %d tiles\n", visited, visited + empty);
printf("Collected items: %d\n", collected);
}
void count_scores(t_game *game)
{
t_scoreboard *scoreboard;
scoreboard = game->scoreboard;
scoreboard->tiles_visited = count_tiles(game->map, TILE_VISITED);
scoreboard->total_tiles = count_tiles(game->map, TILE_EMPTY) + scoreboard->tiles_visited;
scoreboard->collectibles = count_collected(game);
}