loading...

Using SDL2: Pong

noah11012 profile image Noah11012 Updated on ・2 min read

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:

#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:

#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:

#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.

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:

#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:

#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:

#include "paddle.hpp"

...

Paddle        m_left_paddle; 
Paddle        m_right_paddle;

pong.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.

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

Posted on by:

Discussion

pic
Editor guide
 

Hey, nice tutorial, thanks for sharing it.

The content of the paddle.hpp file here is wrong, I just thought I'd suggest an edit.

Cheers^