Using SDL2: Pong 2
Tags: cpp, sdl
Published: 2018-11-19 02:46:22

Continuing from where we left off, the `Paddle` class was created to handle several aspects of a paddle. Currently, three methods were made to manage a specific matter regarding your paddles:

1. `handle_input()`

Any events not handled by the main window will be addressed in `Paddle` if the class so does desires.

2. `update()`

Updates the state of our paddles including the position, and when we get to it, collision.

3. `draw()`

Draws a representation of a paddle namely with a rectangle.

The `Paddle` class also contains a state for the position and is made up these private method variables:

```cpp
double m_y;
Type      m_type;
Direction m_direction;
SDL_Rect  m_position;
```

If you have followed this series from at least the post [Using SDL2: Moving an image](https://dev.to/noah11012/using-sdl2-scaling-and-moving-an-image-pj) you will know we encountered a problem with how C++ does arithmetic operations with different types. E.g. adding a `double` to an `int` will have the `int` operand _promoted_ to a `double`. The gist of the problem is that the frame rate is capped at 60 fps by passing in `1.0/60.0` to `update()` in the main update loop of `Pong`. This number is approximately equal to `0.0167` which you will notice is a floating point number. Trying to store a floating point number in a variable that is only intended to hold integer values will truncate the fractional part of the floating point number. To rectify this problem, we have an additional variable to first hold the result of the new position then store it in the correct `SDL_Rect` member variable. That way the fractional part is preserved in the `double` variable.

Still with me?

Good.

Additional attributes to the `Paddle` class is the `m_direction` and `m_type`. The first one is an `enum` class used to hold the current direction to paddle is heading. The second distinguishes itself from the other paddle. We will need this to keep track of what paddle we are handling events for.

```cpp
enum class Type {LEFT, RIGHT};
enum class Direction {NONE, UP, DOWN};
```

The logic we use to move the paddles is the following:

```cpp
void Paddle::handle_input(SDL_Event const &event)
{
    switch(event.type)
    {
        case SDL_KEYDOWN:
            Uint8 const *keys = SDL_GetKeyboardState(nullptr);

            if(m_type == Type::LEFT)
            {
                if(keys[SDL_SCANCODE_W])
                {
                    m_direction = Direction::UP;
                }
                else if(keys[SDL_SCANCODE_S])
                {
                    m_direction = Direction::DOWN;
                }
            } else if(m_type == Type::RIGHT)
            {
                if(keys[SDL_SCANCODE_UP])
                {
                    m_direction = Direction::UP;
                }
                else if(keys[SDL_SCANCODE_DOWN])
                {
                    m_direction = Direction::DOWN;
                }
            }
    }
}
```

For the update function:

```cpp
void Paddle::update(double delta_time)
{
    if(m_direction == Direction::UP)
    {
        m_y = m_y - 5.0 * delta_time;
        m_position.y = m_y;
    }
    else if(m_direction == Direction::DOWN)
    {
        m_y = m_y + 5.0 * delta_time;
        m_position.y = m_y;
    }
}
```

And finally, the draw function:

```cpp
void Paddle::draw(SDL_Renderer *renderer)
{
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRect(renderer, &m_position);
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
}
```

SDL2 allows drawing primitives like rectangles. We use a filled rectangle in this situation, however, if your need is an outline of a rectangle, use `SDL_RenderDrawRect()`.

Compile and run.

![](https://thepracticaldev.s3.amazonaws.com/i/madjwskza2hixq0o6t3l.png)

## What's next

In the next post we will get the ball on screen and maybe get collision detection working.

Github repository: https://github.com/Noah11012/sdl2-tutorial-code