Making a Pong ball reflect off the paddle I am currently making Pong in C++/SDL2 and after a while of tinkering, I have come up with a solution!

This function gets the hit position and returns the necessary direction change:

MoveDirection Ball::getHitPos(const Player&amp; player) const
{
    MoveDirection dir; //Direction of movement

    //If ball is moving left
    if (m_dir == MoveDirection::LEFT)
    {   
        std::cout &lt;&lt; "Yes";
        int hitPos = m_pos.y - player.getPos().y; //Get hit position
        int playerSize = player.getPos().h / 2; 
        int offSet = 25; //Enables to split up positions into three seperate parts
        //Calculate dir change
        if (hitPos &lt;= playerSize - offSet) {
            dir = MoveDirection::RIGHTUP;
        }
        else if (hitPos &gt;= playerSize + offSet) {
            dir = MoveDirection::RIGHTDOWN;
        }
        else {
            dir = MoveDirection::RIGHT;
        }
    }

    //If Ball is moving right
    if (m_dir == MoveDirection::RIGHT)
    {
        int hitPos = m_pos.y - player.getPos().y; //Get hit position
        int playerSize = player.getPos().h / 2;
        int offSet = 25; //Enables to split up positions into three seperate parts
        //Calculate dir change
        if (hitPos &lt;= playerSize - offSet) {
            dir = MoveDirection::LEFTUP;
        }
        else if (hitPos &gt;= playerSize + offSet) {
            dir = MoveDirection::LEFTDOWN;
        }
        else {
            dir = MoveDirection::LEFT;
        }
    }

    return dir;
}


Here are all of the possible movement directions:

enum class MoveDirection
{
    UP,
    DOWN,
    LEFT,
    RIGHT,
    LEFTUP, //Ball diagonal movement
    LEFTDOWN, //Ball diagonal movement
    RIGHTUP, //Ball diagonal movement
    RIGHTDOWN //Ball diagonal movement
};


And here is the height of the racket:

static constexpr int SIZE_HEIGHT = 75;


I must also note that m_pos is SDL_RECT and player.getPos().y is getting the y element of SDL_RECT.
Your ball can only move in the eight (semi)cardinal directions? It can't move at, say, a 30-degree angle?

Well, even so, it will simplify your code to treat the ball as if it can move in any direction. Either:

struct MoveDirection {
    double angle;
    double speed;
};


or more likely:

struct MoveDirection {
    double vx;
    double vy;
};


And then rewrite your getHitPos function as something more like

MoveDirection Ball::getHitPos(const Player&amp; player) const
{
    MoveDirection dir; //Direction of movement

    //If ball is moving left
    if (m_dir.vx &lt; 0)
    {   
        std::cout &lt;&lt; "Yes";
        int hitPos = m_pos.y - player.getPos().y; //Get hit position
        int playerSize = player.getPos().h / 2; 
        int offSet = 25; //Enables to split up positions into three seperate parts
        //Calculate dir change
        dir.vx = +1;
        if (hitPos &lt;= playerSize - offSet) {
            dir.vy = +1;
        }
        else if (hitPos &gt;= playerSize + offSet) {
            dir.vy = -1;
        }
        else {
            dir.vy = 0;
        }
    }
    else if (m_dir.vx &gt; 0)  // ball is moving right
...


Then just keep refactoring and turning branches into arithmetic expressions until you're happy. It might end up looking something like

MoveDirection result;
result.vx = -m_dir.vx;
const double hitPos = m_pos.y - player.getPos().y; //Get hit position
const double playerSize = player.getPos().h / 2;
result.vy = (hitPos &gt; playerSize + 25) - (hitPos &lt; playerSize - 25);
return result;