cub3d/src/render/render_sprite.c
Willem Haffmans d8bef01b32 FLASH
2025-05-29 09:53:10 +02:00

120 lines
3.5 KiB
C

/* ************************************************************************** */
/* */
/* :::::::: */
/* render_sprite.c :+: :+: */
/* +:+ */
/* By: whaffman <whaffman@student.codam.nl> +#+ */
/* +#+ */
/* 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++;
}
}