Porting Pong From Flash To C++ And SDL 2.0
The Pong Tutorial explained how to create a Pong game by using C++ pseudocode, but the implementation was done using Flash ActionScript 3. I have decided to create an actual C++ implementation using SDL 2.0. This tutorial shows some of the steps that are necessary to port the original Flash game to C++. Porting the code from ActionScript 3 to C++ is surprisingly easy.

Porting Pong From Flash To C++ And SDL 2.0
Choosing A Library
Flash includes a lot of standard libraries that enable you to quickly make a game by bundling functions that deal with graphics, audio and input. C++ is a lot more bare bones. It does not automatically have support for all the necessary features on its own, but there are a lot of external libraries that we can choose that do provide these features.
I have chosen to use the library SDL 2.0. It provides all of the features that are required and allows the game to be compiled for multiple platforms.
The Porting Process
For this tutorial I have decided to create a slimmed-down version of the original Pong game. The game implements all of the interactions, collisions and AI, but does not include a menu system, a scoring system or the sound effects. These features can easily be added or ported from the original game.
Most of the code is simply copied from my original tutorial with some minor syntactical changes. We do need to implement a basic framework using SDL that allows the code to run in the new environment of a desktop application.
Setting Up The Window
We need to initialize SDL and the video subsystem, so we can use the graphics functions to draw stuff on the screen. We need to create a window that contains everything and a renderer that actually draws the things. Next, we initialize some timing variables that are used to update the game-state and calculate the frames per second.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | bool Game::Init() { // Initialize SDL and the video subsystem SDL_Init(SDL_INIT_VIDEO); // Create window window = SDL_CreateWindow("Pong Example - Rembound.com", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL); if (!window) { // Error creating window return false; } // Create renderer renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (!renderer) { // Error creating renderer return false; } // Initialize timing lasttick = SDL_GetTicks(); fpstick = lasttick; fps = 0; framecount = 0; return true; } |
Drawing Stuff
SDL provides us functions to draw stuff on the screen. Before we draw anything ourselves, we must first clear the screen. We can now draw anything we want to the screen, but we can’t see our drawings yet. If we are done with drawing, the screen must be updated by SDL and it will present us our new image.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | void Game::Render(float delta) { // Clear the screen to black SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); // Render board and ball board->Render(delta); ball->Render(delta); // Render paddles for (unsigned int i=0; i<paddle.size(); i++) { paddle[i]->Render(delta); } // Update the screen SDL_RenderPresent(renderer); } |
Loading And Drawing Textures
In our Render function we want to draw our game-objects. SDL provides features to load textures by using an additional library: SDL_image. Here is an example of loading a PNG image file into a texture.
1 2 3 | SDL_Surface* surface = IMG_Load("ball.png"); texture = SDL_CreateTextureFromSurface(renderer, surface); SDL_FreeSurface(surface); |
The texture can be rendered to the screen on integer positions. We define a rectangle that indicates the destination of our texture on the screen. Our Ball class uses floating point numbers for its position, so we round them to the nearest integer to smooth the motion of the ball.
1 2 3 4 5 6 7 8 | void Ball::Render(float delta) { SDL_Rect rect; rect.x = (int)(x + 0.5f); // Round the float to the nearest integer rect.y = (int)(y + 0.5f); // Round the float to the nearest integer rect.w = width; rect.h = height; SDL_RenderCopy(renderer, texture, 0, &rect); } |
When the game exits, the texture needs to be cleaned.
1 | SDL_DestroyTexture(texture); |
Input And Events
This is a summary of our game loop. The game gets updated and system events are handled.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // Main loop while (1) { // Handler events SDL_Event e; if (SDL_PollEvent(&e)) { if (e.type == SDL_QUIT) { break; } } // (...) // Update and render the game Update(delta); Render(delta); } |
The mouse position is retrieved to allow interactions.
1 2 3 | // Get the mouse position int mx, my; SDL_GetMouseState(&mx, &my); |
Cleaning Up
When the game is about to exit, we need to do some cleaning up. We have to destroy the renderer and the window that we created earlier when initializing the game, to avoid memory leaks.
1 2 3 4 5 | void Game::Clean() { // Clean renderer and window SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); } |
Clean the rest of SDL.
1 | SDL_Quit(); |
Evaluation
The previous chapter explains all of the SDL features that are necessary to create a framework for our game. The actual game logic, the interactions between objects, the game world and the player, is mostly untouched from the original ActionScript 3 code. An explanation of the game logic can be found in The Pong Tutorial.
Download
The full source code and a Windows executable of this tutorial can be downloaded here. Included is a project file for the Code Blocks IDE. To compile the project, you need to install a compiler like MinGW and define the sdl2 global variable in the Code Blocks global variable editor. Alternatively, you can use Visual Studio Express and import the source files into a new project, followed by linking to the SDL2 and SDL2_image libraries. Details on how to compile the source code is out of the scope of this tutorial.