120 lines
3.5 KiB
C
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++;
|
|
}
|
|
}
|