/* ************************************************************************** */ /* */ /* :::::::: */ /* render_sprite.c :+: :+: */ /* +:+ */ /* By: whaffman +#+ */ /* +#+ */ /* Created: 2025/05/08 12:23:17 by qmennen #+# #+# */ /* Updated: 2025/05/29 09:47:41 by whaffman ######## odam.nl */ /* */ /* ************************************************************************** */ #include "render.h" static void get_start_end(t_game *game, t_sprite *sprite, t_vec2_int *start, t_vec2_int *end) { double sprite_scale; sprite_scale = game->screen->height / sprite->dist / sprite->texture->height; start->x = 0.5 * (game->screen->width * (1.0 + sprite->cam_frac) - sprite->texture->width / sprite->n_frames * sprite_scale); start->y = 0.5 * (game->screen->height - sprite->texture->height * sprite_scale); end->x = start->x; end->x += sprite->texture->width / sprite->n_frames * sprite_scale; end->y = start->y + sprite->texture->height * sprite_scale; } static int sprite_visible(t_game *game, t_sprite *sprite, t_render *render, int x) { return (!isnan(sprite->cam_frac) && sprite->dist > 0.5 && x > 0 && x < game->screen->width && sprite->dist <= render[x].perp_dist); } static void draw_sprite_column( t_game *game, t_sprite *sprite, t_render *render, t_sprite_column column) { t_vec2_int tex; t_vec2 inv_range; int y; unsigned int color; inv_range.y = 1.0 / (column.end.y - column.start.y); inv_range.x = 1.0 / (column.end.x - column.start.x); sprite->alpha = calculate_alpha(column.start.x, column.start.y, sprite->dist); tex.x = column.x - column.start.x; tex.x *= sprite->texture->width / sprite->n_frames; tex.x *= inv_range.x; y = column.start.y; while (y < column.end.y) { tex.y = (y - column.start.y) * sprite->texture->height; tex.y *= inv_range.y; color = sample_texture_color(sprite, tex, (int)(game->elapsed_time * sprite->animation_speed) % sprite->n_frames); if (y > 0 && y < game->screen->height && (color & 0xFF) != 0) mlx_put_pixel(game->screen->img, column.x, y, color); y++; } } void handle_flash(t_sprite *sprite, t_game *game) { if (sprite->type == SPRITE_TYPE_ENEMY && game->screen->flash > 0) sprite->type = SPRITE_TYPE_COLLECTED; } void draw_sprite(t_game *game, t_sprite *sprite, t_render *render) { t_vec2_int start; t_vec2_int end; t_sprite_column column; int x; if (isnan(sprite->cam_frac) || sprite->dist <= 0.5) return ; get_start_end(game, sprite, &start, &end); x = start.x; while (x < end.x) { if (sprite_visible(game, sprite, render, x)) { handle_flash(sprite, game); column.start = start; column.end = end; column.x = x; draw_sprite_column(game, sprite, render, column); } x++; } } 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) { if (game->map->sprites[i].type == SPRITE_TYPE_COLLECTED) { i++; continue ; } cam_fraction(game, &game->map->sprites[i]); draw_sprite(game, &game->map->sprites[i], render); i++; } }