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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.