Using SDL2: Pong
Tags: cpp, sdl, pong
Published: 2018-11-09 22:37:53

We're going to jump straight in and make a Pong clone in SDL2 and C++. I've already created three files: main.cpp, pong.hpp, and pong.cpp. Main.cpp only has one job: create an instance of a `Pong` class and call the method `game_loop()`.

main.cpp:

```cpp
#include "pong.hpp"  
                     
int main()           
{                    
    Pong pong;       
    pong.game_loop();
}                    
```

The `Pong` class that resides in pong.cpp handles our window, renderer, window events and eventually more as we progress through this article.

pong.hpp:

```cpp
#pragma once                                
                                            
#include <SDL2/SDL.h>                       
                                            
class Pong                                  
{                                           
public:                                     
    Pong();                                 
    ~Pong() = default;                      
                                            
    void game_loop();                       
    void update(double delta_time);         
    void draw();                            
                                            
private:                                    
    SDL_Window   *m_game_window;            
    SDL_Event     m_game_window_event;      
    SDL_Renderer *m_game_window_renderer;   
};                                          
```

pong.cpp:

```cpp
#include "pong.hpp"                                            
                                                               
Pong::Pong()                                                   
{                                                              
    SDL_CreateWindowAndRenderer(680, 480, SDL_WINDOW_RESIZABLE,
 &m_game_window, &m_game_window_renderer);                     
}                                                              
                                                               
void Pong::game_loop()                                         
{                                                              
    bool keep_running = true;                                  
    while(keep_running)                                        
    {                                                          
        while(SDL_PollEvent(&m_game_window_event) > 0)         
        {                                                      
            switch(m_game_window_event.type)                   
            {                                                  
                case SDL_QUIT:                                 
                    keep_running = false;                      
            }                                                  
        }                                                      
                                                               
        update(1.0/60.0);                                      
        draw();                                                
    }                                                          
}                                                              
                                                               
void Pong::update(double delta_time)                           
{                                                              
                                              
}                                             
                                              
void Pong::draw()                             
{                                             
    SDL_RenderClear(m_game_window_renderer);  
                                              
    SDL_RenderPresent(m_game_window_renderer);
}                                             

```

In the constructor, we initialize both the window and renderer using `SDL_CreateWindowAndRenderer()`. It's a shortcut to creating a window and then creating the renderer from the window. We also allow resizing of the window in case the user is not satisfied with the default dimensions. This has an implication that we must talk about. If we allow resizing of the window, this means our objects in the game will change dimension/shape. We need an independent resolution from the window dimensions. With SDL2 being a fairly low level library, this is easy to accomplish. In the constructor, add the function `SDL_RenderSetLogicalSize()` that takes a pointer to an `SDL_Renderer` and two arguments for the width and height.

```cpp
SDL_RenderSetLogicalSize(m_game_window_renderer, 400, 400);
```

The next order of business is to create the paddles. Like always, we'll create a class to manage the position, updates and drawing to the screen.

paddle.hpp:

```cpp
#pragma once                             
                                         
#include <SDL2/SDL.h>                    
#include "paddle.hpp"                    
                                         
class Pong                               
{                                        
public:                                  
    Pong();                              
    ~Pong() = default;                   
                                         
    void game_loop();                    
    void update(double delta_time);      
    void draw();                         
                                         
private:                                 
    SDL_Window   *m_game_window;         
    SDL_Event     m_game_window_event;   
    SDL_Renderer *m_game_window_renderer;
                                         
    Paddle        m_left_paddle;         
    Paddle        m_right_paddle;        
};                                       
```

paddle.cpp:

```cpp
#include "paddle.hpp"                            
                                                 
Paddle::Paddle(int x, int y)                     
{                                                
    m_position.x = x;                            
    m_position.y = y;                            
    m_position.w = 50;                           
    m_position.h = 100;                          
}                                                
                                                 
void Paddle::handle_input(SDL_Event const &event)
{                                                
                                                 
}                                                
                                                 
void Paddle::update(double delta_time)           
{                                                
                                                 
}                                                
                                                 
void Paddle::draw()                              
{                                                
                                                 
}                                                
```

We also add the `Paddle` classes to the private section of the `Pong` class and initialize them in the constructor initialization list:

pong.hpp:

```cpp
#include "paddle.hpp"

...

Paddle        m_left_paddle; 
Paddle        m_right_paddle;

```

pong.cpp:

```cpp
Pong::Pong(): m_left_paddle(0, (400 / 2) - 50), m_right_paddle(400 - 50, (400 / 2) - 50)
{
    ...
}                                                                                
```

In the game loop of `Pong`, any events that are not handled by `Pong` itself should be sent to the other objects in the game like the paddles.

```cpp
while(SDL_PollEvent(&m_game_window_event) > 0)       
{                                                    
    switch(m_game_window_event.type)                 
    {                                                
        ...                   
    }                                                
                                                     
    m_left_paddle.handle_input(m_game_window_event); 
    m_right_paddle.handle_input(m_game_window_event);
}                                                    

```

## What's next?

In the next part, we'll get the left and right paddles moving up and down the screen.

Like always, the source code for this series can be found at my Github repository:

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