0
\$\begingroup\$

i am learning how to make a 2d game using sdl and c++ and am currently trying to rotate the sprite so that is always facing the cursor, my game is set up with an entity component system, i have a keyboardcontroller component where the game will use atan2 to work out the angle of the mouse to the sprite and rotate it to match when whenever the mouse is moved. i managed to get it to work but only on the sprites starting coordinates for some reason. all the things to do with drawing the sprite and animating it are stored in the spritecomponent, inside there is a draw() override function that is called for every sprite of every entity for every frame of the game, inside that there is member function of my texturemanager class, when it is called it uses sdl_rendercopyex to draw a sprite onto the renderer in the window. i then try to pass the angle to sdl_rendercopyex so that it changes every time the mouse is moved.

as stated it only seems to work around the starting position of the sprite, after moving away the rotation no longer works, just rotates very slightly but only in the sameish direction. to try and troubleshoot i made it print to the console the player sprite coords, the mouse cursor coords and the angle calculated from this, this all seemed correct, this is the code i wrote for the rotation angle, anglerot is the angle parameter of the texturemanager::draw() function passed to the sprite:

if(Game::event.type == SDL_MOUSEMOTION){
    Vector2D playerPos = entity->getComponent<TransformComponent>().position;
    int x1;
    int y1;
    int x = playerPos.x;
    int y = playerPos.y;
    SDL_GetMouseState(&x1 , &y1);
    int DeltaX;
    int DeltaY;
    double* result;
    DeltaX = playerPos.x -  x1 ;
    DeltaY = playerPos.y - y1;
    result = ((atan2(-DeltaX, DeltaY) * 180.00000) / 3.141592);
    sprite->anglerot = static_cast<int> (result);

    std::cout << "mouse cursor: " << x1 << " , " << y1 << '\n' << "player position: "         << playerPos.x << " " << playerPos.y << '\n' << "angle of rotation: " << result << std::endl;

As requested, inside my sprite component class i had a camera set up following the player like so:

destRect.x = static_cast(transform->position.x)- Game::camera.x;
destRect.y = static_cast(transform->position.y)- Game::camera.y;

where destRect is the rectangle in which my sprite is drawn.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

It turns out the issue came from what I thought was my player position used in the calculation. I had forgotten I had a camera that followed the player as it moved, so player position was relative to that in-game. Taking into account the camera position fully fixed the issue. Here is my updated code:

if(Game::event.type == SDL_MOUSEMOTION && Game::dead() == false){
Vector2D playerPos = entity->getComponent<TransformComponent>().position;
    int x1;
    int y1;
    SDL_GetMouseState(&x1 , &y1);
    int DeltaX;
    int DeltaY;
    double result;
    DeltaX =   x1 - (playerPos.x - Game::camera.x);
    DeltaY =  y1  - (playerPos.y - Game::camera.y) ;
    result = ((atan2(DeltaY, DeltaX) * 180.00000) / 3.141592) + 90;
          
    sprite-> anglerot = static_cast<int> (result);
\$\endgroup\$
1
  • \$\begingroup\$ That's actually what I suspected when I read that you take what is probably the world-space position of the entity and compare it to the screen-space position of the mouse cursor. But I would have been reluctant to answer that without asking first if your game even has camera movement that would make those two any different. \$\endgroup\$
    – Philipp
    Commented Apr 27, 2023 at 14:14

You must log in to answer this question.

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