1
\$\begingroup\$

I am trying to create a raycasting engine using C and CSFML, I already have the walls and textures rendering done and right now I would like to be able to render sprites into the scene. The difficulty I'm facing currently is finding the x position of the sprite on the screen. I have already looked up a number of tutorials and it somewhat works but not completely. When I move the player left and right, the sprite position gets calculated right, but when I look on the left and right by changing the player camera angle, the sprites moves on the left or right. I can't figure out what's wrong.

Here's the code I'm using to find the sprite position on the screen, it is from Liam Wynn tutorial :

void draw_entity3d(core_t *c, entity_t *entity)
{
    sfVector2f h;
    sfVector2f sprite_screen;
    sfVector2f scale;

    h.x = entity->pos.x - c->player->pos.x;
    h.y = entity->pos.y - c->player->pos.y;
    float p = rad_to_deg(atan2(-h.y, h.x));
    if (p > 360)
        p -= 360;
    if (p < 0)
        p += 360;
    float q = ((rad_to_deg(c->player->angle) + (c->render3d.fov / 2))) - p;
    scale.x = 1000 / (dist_from(entity->pos, c->player->pos));
    scale.y = 1000 / (dist_from(entity->pos, c->player->pos));
    sprite_screen.x = q * (c->render.w_size.x / c->render3d.fov);
    sprite_screen.y = (c->render.w_size.y / 2);
    sfSprite_setPosition(entity->sprite, (sfVector2f){sprite_screen.x, 
    sprite_screen.y});
    sfSprite_setOrigin(entity->sprite, get_sprite_center(entity->sprite));
    sfSprite_setScale(entity->sprite, (sfVector2f){scale.x, scale.y});
    sfRenderWindow_drawSprite(c->render.window, entity->sprite, NULL);
}

Here is what it looks in game

\$\endgroup\$

1 Answer 1

0
\$\begingroup\$

I think in this line

float q = ((rad_to_deg(c->player->angle) + (c->render3d.fov / 2))) - p;

q should be between 0 and 1. From your code it seems q is between 0..360 (degrees). You should divide it by c->render3d.fov:

float q = (((rad_to_deg(c->player->angle) + (c->render3d.fov / 2))) - p) / c->render3d.fov;

In this way it is the linear scaling factor you need later:

sprite_screen.x = q * (c->render.w_size.x / c->render3d.fov);

Here you see that q==c->render3d.fov leads to sprite_screen.x = c->render.w_size.x

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .