When I run this code (from the Lazy Foo SDL tutorial) the program immediately shuts down. Why is that? I'm sorry if it gets kind of messy because of the lack of comments, but I thought that it didn't really matter since there were comments on Lazy Foo's post. I get no errors when building it.
#include "SDL/SDL_image.h"
#include "SDL/SDL.h"
#include <string>
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;
SDL_Surface *image = NULL;
SDL_Surface *screen = NULL;
SDL_Event event;
SDL_Surface *load_image (std::string filename)
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;
loadedImage = IMG_Load( filename.c_str());
if(loadedImage != NULL)
{
optimizedImage = SDL_DisplayFormat (loadedImage);
SDL_FreeSurface(loadedImage);
}
return optimizedImage;
}
void apply_surface (int x, int y, SDL_Surface* source, SDL_Surface* destination)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface (source, NULL, destination, &offset);
}
bool init()
{
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
{
return false;
}
screen = SDL_SetVideoMode (SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE);
if (screen == NULL)
{
return false;
}
SDL_WM_SetCaption("Event test", NULL);
return true;
}
bool load_files()
{
image = load_image ("background.png");
if (image == NULL)
{
return false;
}
return true;
}
void clean_up()
{
SDL_FreeSurface(image);
SDL_Quit();
}
int main(int argc, char* args[])
{
bool quit = false;
if (init() == false)
{
return 1;
}
if (load_files() == false)
{
return 1;
}
apply_surface(0,0, image, screen);
if(SDL_Flip(screen) == -1)
{
return 1;
}
while(quit == false)
{
while (SDL_PollEvent(&event))
{
if(event.type == SDL_QUIT)
{
quit = true;
}
}
}
clean_up();
return 0;
}
If you're missing background.png, or any of the required DLL's in the executable directory, you can encounter weird crashes.
Being that this is one of the simpler programs in this series, I'd bet this is the issue. I've seen strange segfaults myself when I had a brain-fart and forgot a file, or it wasn't where the exe expected it to be.
Related
I'm trying to put an imagine on surface.
So it's showed a black screen when I'm load BMP and display bmp
here's my code:
#define SDL_MAIN_HANDLED
#include <iostream>
#include "SDL/include/SDL2/SDL.h"
const int screenWidth=640;
const int screenHeight=480;
SDL_Window* window=NULL;
SDL_Surface* screenSurface=NULL;
SDL_Surface* gHelloWorld = NULL;
bool init(){
bool good = true;
if(SDL_Init(SDL_INIT_VIDEO)<0){
std::cout<<"ERROR: Failed to initialize SDL " << SDL_GetError()<<"\n";
good = false;
}else{
//Create Window
window =SDL_CreateWindow("SDL Tutorial",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,screenWidth,screenHeight,SDL_WINDOW_SHOWN);
if (window ==NULL){
std::cout<<"ERROR: Failed to create "<<SDL_GetError() <<"\n";
good = false;
}else{
//Get window surface
screenSurface = SDL_GetWindowSurface( window );
}
}
return good;
}
void close(){
SDL_FreeSurface(gHelloWorld);
gHelloWorld = NULL;
SDL_DestroyWindow(window);
window=NULL;
SDL_Quit();
}
bool loadMedia(){
bool ok = true;
gHelloWorld=SDL_LoadBMP("hello_world.bmp");
if(gHelloWorld==NULL){
std::cout<<"ERROR: Failed to load "<<SDL_GetError()<<"\n";
ok = false;
}else{
std::cout<<"Loaded successfully "<<'\n';
}
return ok;
}
int main(){
SDL_Window* window=NULL;
SDL_Surface* screenSurface=NULL;
bool Init = init();
if(Init){
bool loadMed = loadMedia();
if(loadMed){
SDL_Rect area ={30,30,250,250};
SDL_BlitSurface(gHelloWorld,&area,screenSurface,&area);
SDL_UpdateWindowSurface(window); //
SDL_Event e; bool quit = false; while( quit == false ){ while( SDL_PollEvent( &e ) ){ if( e.type == SDL_QUIT ) quit = true; } }
}
}
close();
return 0;
}
And I'm using Cmake to link lib (dynamic linking)
I tried to write SDL_Rect , and its not work ;/
Your problem is that you are nulling your sufaces in the main function.
Here is a version of your code without that mistake:
#include <iostream>
#include "SDL/include/SDL2/SDL.h"
const int screenWidth=640;
const int screenHeight=480;
SDL_Window* window=NULL;
SDL_Surface* screenSurface=NULL;
SDL_Surface* gHelloWorld = NULL;
bool init(){
bool good = true;
if(SDL_Init(SDL_INIT_VIDEO)<0){
std::cout<<"ERROR: Failed to initialize SDL " << SDL_GetError()<<"\n";
good = false;
}else{
//Create Window
window =SDL_CreateWindow("SDL Tutorial",SDL_WINDOWPOS_UNDEFINED,SDL_WINDOWPOS_UNDEFINED,screenWidth,screenHeight,SDL_WINDOW_SHOWN);
if (window ==NULL){
std::cout<<"ERROR: Failed to create "<<SDL_GetError() <<"\n";
good = false;
}else{
//Get window surface
screenSurface = SDL_GetWindowSurface( window );
}
}
return good;
}
void close(){
SDL_FreeSurface(gHelloWorld);
gHelloWorld = NULL;
SDL_DestroyWindow(window);
window=NULL;
SDL_Quit();
}
bool loadMedia(){
bool ok = true;
gHelloWorld=SDL_LoadBMP("/tmp/image.bmp");
if(gHelloWorld==NULL){
std::cout<<"ERROR: Failed to load "<<SDL_GetError()<<"\n";
ok = false;
}else{
std::cout<<"Loaded successfully "<<'\n';
}
return ok;
}
int main(){
// your error was nulling your surfaces.
// SDL_Window* window=NULL;
// SDL_Surface* screenSurface=NULL;
bool Init = init();
if(Init){
bool loadMed = loadMedia();
if(loadMed){
SDL_Rect area ={30,30,250,250};
SDL_BlitSurface(gHelloWorld,&area,screenSurface,&area);
SDL_UpdateWindowSurface(window); //
SDL_Event e; bool quit = false; while( quit == false ){ while( SDL_PollEvent( &e ) ){ if( e.type == SDL_QUIT ) quit = true; } }
}
}
close();
return 0;
}
Also, I recommend that you make your surface updates inside your while loop because somethimes SDL don't render the first surface and you obta a false window.
Here is a good resource for learning SDL: https://lazyfoo.net/tutorials/SDL/
and on my GitHub I have a tool to give you an SDL example: https://github.com/Monsterduty/mktest.
Here's my header file:
#ifndef SOMETHING_H
#define SOMETHING_H
#include <SDL.h>
#include <stdio.h>
#include <string>
#pragma once
class Something {
public:
//Screen dimension constants
int SCREEN_WIDTHS;
int SCREEN_HEIGHTS;
//Starts up SDL and creates window
bool inits();
//Loads media
bool loadMediases();
//Frees media and shuts down SDL
void closes();
Something(int height);
int mains();
//Loads individual image
SDL_Surface* loadSurfaces(std::string path);
//The window we'll be rendering to
SDL_Window* gWindows;
//The surface contained by the window
SDL_Surface* gScreenSurfaces;
//The images that correspond to a keypress
SDL_Surface* gKeyPressSurfaceses[5];
//Current displayed image
SDL_Surface* gCurrentSurfaces;
};
#endif
Here's my cpp file:
//Using SDL, standard IO, and strings
#include <SDL.h>
#include <stdio.h>
#include <string>
#include "Something.h"
class Something {
public:
//Screen dimension constants
int SCREEN_WIDTHS = 640;
int SCREEN_HEIGHTS = 480;
//Key press surfaces constants
enum KeyPressSurfaceses
{
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL
};
//The window we'll be rendering to
SDL_Window* gWindows = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurfaces = NULL;
//The images that correspond to a keypress
SDL_Surface* gKeyPressSurfaceses[KEY_PRESS_SURFACE_TOTAL];
//Current displayed image
SDL_Surface* gCurrentSurfaces = NULL;
Something(int height) {
SCREEN_HEIGHTS = height;
}
bool inits()
{
//Initialization flag
bool success = true;
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Create window
gWindows = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTHS, SCREEN_HEIGHTS, SDL_WINDOW_SHOWN);
if (gWindows == NULL)
{
printf("Window could not be created! SDL Error: %s\n", SDL_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurfaces = SDL_GetWindowSurface(gWindows);
}
}
return success;
}
bool loadMedias()
{
//Loading success flag
bool success = true;
//Load default surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT] = loadSurfaces("resources/images/press.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT] == NULL)
{
printf("Failed to load default image!\n");
success = false;
}
//Load up surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_UP] = loadSurfaces("resources/images/up.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_UP] == NULL)
{
printf("Failed to load up image!\n");
success = false;
}
//Load down surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_DOWN] = loadSurfaces("resources/images/down.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_DOWN] == NULL)
{
printf("Failed to load down image!\n");
success = false;
}
//Load left surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_LEFT] = loadSurfaces("resources/images/left.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_LEFT] == NULL)
{
printf("Failed to load left image!\n");
success = false;
}
//Load right surface
gKeyPressSurfaceses[KEY_PRESS_SURFACE_RIGHT] = loadSurfaces("resources/images/right.bmp");
if (gKeyPressSurfaceses[KEY_PRESS_SURFACE_RIGHT] == NULL)
{
printf("Failed to load right image!\n");
success = false;
}
return success;
}
void closes()
{
//Deallocate surfaces
for (int i = 0; i < KEY_PRESS_SURFACE_TOTAL; ++i)
{
SDL_FreeSurface(gKeyPressSurfaceses[i]);
gKeyPressSurfaceses[i] = NULL;
}
//Destroy window
SDL_DestroyWindow(gWindows);
gWindows = NULL;
//Quit SDL subsystems
SDL_Quit();
}
SDL_Surface* loadSurfaces(std::string path)
{
//Load image at specified path
SDL_Surface* loadedSurface = SDL_LoadBMP(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", path.c_str(), SDL_GetError());
}
return loadedSurface;
}
int mains(int argc, char* args[])
{
//Start up SDL and create window
if (!inits())
{
printf("Failed to initialize!\n");
}
else
{
//Load media
if (!loadMedias())
{
printf("Failed to load media!\n");
}
else
{
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//Set default current surface
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT];
//While application is running
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
//User requests quit
if (e.type == SDL_QUIT)
{
quit = true;
}
//User presses a key
else if (e.type == SDL_KEYDOWN)
{
//Select surfaces based on key press
switch (e.key.keysym.sym)
{
case SDLK_UP:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_UP];
break;
case SDLK_DOWN:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_DOWN];
break;
case SDLK_LEFT:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_LEFT];
break;
case SDLK_RIGHT:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_RIGHT];
break;
default:
gCurrentSurfaces = gKeyPressSurfaceses[KEY_PRESS_SURFACE_DEFAULT];
break;
}
}
}
//Apply the current image
SDL_BlitSurface(gCurrentSurfaces, NULL, gScreenSurfaces, NULL);
//Update the surface
SDL_UpdateWindowSurface(gWindows);
}
}
}
//Free resources and close SDL
closes();
return 0;
}
};
Why does it keep throwing a "Class" type redefinition error? How can I fix this? I've tried everything but I just run into more problems. I saw some posts relating the issue to defining the class twice, but getting rid of the class definition in the cpp and using classname::functionname just causes more errors.
I know this is a stupid problem to have, I'm a beginning C++ programmer using tutorials and Visual Studio.
In your .cpp file you have completely redeclared class Something. That's not how you do it if you want to just put the implementations of functions in the .cpp file.
The syntax in there should be like:
bool Something::inits()
{
// implementation ...
}
bool Something::loadMedias()
{
// implementation ...
}
And so on
I've been using SDL for a little awhile and following Lazy Foo's tutorials. I have no problem loading images, animating sprites etc... but when I attempt to separate functions into different header files I'm unable to load an image.
I've looked about for on the internet for a few days now but haven't found an answer.
Sprite.cpp
#include "Sprite.h"
#include "Globals.h"
using namespace Globals;
Graphics sprite;
Sprite::Sprite(){}
bool Sprite::load()
{
bool success = true;
if(!sprite.loadImage("C:/SDL_Project/bin/Debug/PNG_transparency_demonstration_1.png"))
{
printf("Failed to load image!\n");
success = false;
}
return success;
}
void Sprite::renderSprite()
{
SDL_Rect* curSprite = &spriteClips[frames];
sprite.renderImage((SCREEN_WIDTH - curSprite->w) / 2, (SCREEN_HEIGHT - curSprite->h) / 2, curSprite);
}
Graphics.cpp
#include "Graphics.h"
#include "Globals.h"
using namespace Globals;
Graphics::Graphics()
{
hei = 0;
wid = 0;
texture = NULL;
win = SDL_CreateWindow("Foo", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(win && ren == NULL)
{
printf("Failed to create Window & Renderer!\n");
}
else
{
int imgFlags = IMG_INIT_PNG;
if( !(IMG_Init(imgFlags) &imgFlags))
{
printf("Image flags not initiated!\n");
}
}
}
Graphics::~Graphics(){}
SDL_Texture* Graphics::loadImage(std::string file)
{
SDL_Texture* newTxtr = NULL;
image = IMG_Load(file.c_str());
if(image == NULL)
{
printf("Unable to load image\n");
}
else
{
newTxtr = SDL_CreateTextureFromSurface(ren, image);
if(newTxtr == NULL)
{
printf("Unable to create texture!\n");
}
else
{
wid = image->w;
hei = image->h;
}
SDL_FreeSurface(image);
}
texture = newTxtr;
return texture;
}
void Graphics::free()
{
if(texture != NULL)
{
texture = NULL;
wid = 0;
hei = 0;
}
}
void Graphics::renderImage(int x, int y, SDL_Rect* clip)
{
SDL_Rect dstClip = {x, y, wid, hei};
if(clip != NULL)
{
dstClip.w = clip->w;
dstClip.h = clip->h;
}
SDL_RenderCopy(ren, texture, clip, &dstClip);
}
void Graphics::render()
{
SDL_RenderPresent(ren);
SDL_UpdateWindowSurface(win);
}
void Graphics::clearScreen()
{
SDL_RenderClear(ren);
}
SDL_Renderer* Graphics::getRenderer()
{
return ren;
}
void Graphics::closeGraphics()
{
IMG_Quit();
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
}
GameLoop.cpp
#include "GameLoop.h"
#include "Graphics.h"
#include "Sprite.h"
GameLoop::GameLoop()
{
if(SDL_Init(SDL_INIT_EVERYTHING)< 0)
{
printf("Failed to init\n");
}
else
{
this->loop();
}
}
GameLoop::~GameLoop(){}
void GameLoop::loop()
{
Graphics graphics;
SDL_Event e;
bool quit = false;
while(!quit)
{
while(SDL_PollEvent(&e)!= 0)
{
if(e.type == SDL_QUIT)
{
quit = true;
}
}
this->renderGraphics(graphics);
}
this->close(graphics);
}
void GameLoop::loadSprite()
{
Sprite sp;
sp.renderSprite();
}
void GameLoop::renderGraphics(Graphics& graphics)
{
SDL_SetRenderDrawColor(graphics.ren, 0x00, 0x00, 0x00, 0x00);
graphics.clearScreen();
graphics.render();
}
void GameLoop::close(Graphics& graphics)
{
SDL_Quit();
graphics.closeGraphics();
}
I've included all but one of the .cpp files.
Thanks.
Today I started a C++/SDL2 Snake clone, and I've been looking for ways to make my code neater, -particularly with classes. I tried to put all the SDL code used for the window/display in a class. When I run the code, the window closes instantly. From the error tests I set up in display.cpp, it also tells me through the console that SDL_UpdateWindowSurface() (in display.update()) is always returning -1. Why does this happen when I rearrange my code like this?
With this code I load an image in main() and display it through my class' function applySurface(). The idea is to have classes/objects for the game's grid/board, the snake, etc., -each calling applySurface() for their own images. Feel free to tell me if this is a bad idea altogether.
main.cpp:
#include <SDL.h>
#include "display.h"
SDL_Event event;
SDL_Surface* image = nullptr;
int main(int argc, char* args[])
{
Display display;
display.loadImage("image.bmp");
if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
return false;
bool quit = false;
while (!quit)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
quit = true;
}
display.applySurface(0, 0, image, display.windowSurface);
display.update();
}
SDL_FreeSurface(image);
SDL_Quit();
return 0;
}
display.h:
#pragma once
#include <SDL.h>
#include <string>
#include <iostream>
class Display
{
public:
SDL_Window* window;
SDL_Surface* windowSurface;
Display();
SDL_Surface *loadImage(std::string fileName);
void applySurface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip = nullptr);
void update();
~Display();
private:
const int WINDOW_WIDTH = 612;
const int WINDOW_HEIGHT = 632;
const int SCREEN_BPP = 2;
};
display.cpp:
#pragma once
#include "display.h"
Display::Display()
{
window = SDL_CreateWindow("Snake", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL)
std::cout << "Error: SDL_CreateWindow failed." << std::endl;
windowSurface = SDL_GetWindowSurface(window);
}
SDL_Surface* Display::loadImage(std::string fileName)
{
SDL_Surface* loadedImage = NULL;
SDL_Surface* optimizedImage = NULL;
loadedImage = SDL_LoadBMP(fileName.c_str());
if (loadedImage != NULL)
{
optimizedImage = SDL_ConvertSurface(loadedImage, windowSurface->format, 0);
SDL_FreeSurface(loadedImage);
if (optimizedImage != NULL)
SDL_SetColorKey(optimizedImage, SDL_TRUE, SDL_MapRGB(optimizedImage->format, 255, 255, 255));
}
return optimizedImage;
}
void Display::applySurface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *clip)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, clip, destination, &offset);
}
void Display::update()
{
if (SDL_UpdateWindowSurface(window) == -1)
std::cout << "Error: SDL_UpdateWindowSurface() failed." << std::endl;
}
Display::~Display()
{
SDL_FreeSurface(windowSurface);
windowSurface = NULL;
SDL_DestroyWindow(window);
window = NULL;
}
This is a valid use of classes to structure your code. SDL_Init needs to come before any other SDL functions, which means you're best off moving SDL_Init to the top of main or adding it to the display constructor. If you add it to the beginning of the display constructor this means that you can only have one display class object running at a time, which would likely be fine in this case.
I am creating a pong clone in C++ using SDL. The Paddles are ready and move according to the user input. What keeps worrying me is that the input is weird, I expected smooth movement of both the paddles but one paddle lags when the other paddle is moving and speeds up when the other is not moving. I doubt if this is caused by not capping FPS or by the weird way that I managed to get multiple input or both. Can anyone tell me what is wrong in my code and how to improve it?
My code:
#include <SDL/SDL.h>
#include <string>
#include "SDL/SDL_image.h"
#include <SDL/SDL_ttf.h>
bool quit = false;
bool keyheld[323]={false};
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int SCREEN_BPP = 32;
int paddle1x = 0;
int paddle1y = 50;
int paddle2x = 600;
int paddle2y = 500;
SDL_Color color = {255,255,255};
SDL_Event event;
SDL_Surface* screen = NULL;
SDL_Surface* timer = NULL;
SDL_Surface* background = NULL;
SDL_Surface* paddle1 =NULL;
SDL_Surface* paddle2 = NULL;
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination)
{
SDL_Rect offset;
offset.x = x;
offset.y = y;
SDL_BlitSurface(source, NULL,destination, &offset);
}
SDL_Surface *load_image(std::string filename)
{
SDL_Surface* loadedimage = NULL;
SDL_Surface* optimisedimage = NULL;
loadedimage= IMG_Load(filename.c_str());
optimisedimage= SDL_DisplayFormatAlpha(loadedimage);
SDL_FreeSurface(loadedimage);
return optimisedimage;
}
int main(int argc, char *args[])
{
bool quit = false;
bool keyheld[323]={false};
int p1score=0;
int p2score=0;
SDL_Init(SDL_INIT_EVERYTHING);
TTF_Init();
TTF_Font *font=NULL;
screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_SWSURFACE);
background = load_image("background.png");
apply_surface(0,0,background,screen);
paddle1 = load_image("paddle1.png");
apply_surface(paddle1x,paddle1y,paddle1,screen);
paddle2=load_image("paddle2.png");
apply_surface(paddle2x,paddle2y,paddle2,screen);
font = TTF_OpenFont("kremlin.ttf", 22);
timer = TTF_RenderText_Solid(font,"Test!",color);
apply_surface(0,0,timer,screen);
SDL_WM_SetCaption("PONG!",NULL);
SDL_Flip(screen);
while(quit==false)
{
if(SDL_PollEvent(&event))
{
SDLKey keyPressed = event.key.keysym.sym;
if(event.type==SDL_QUIT)
{
return 0;
}
else if(event.type==SDL_KEYDOWN)
{
keyheld[keyPressed] = true;
}
else if(event.type==SDL_KEYUP)
{
keyheld[keyPressed] = false;
}
}
if(keyheld[SDLK_LEFT])
{
paddle1x--;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
if(keyheld[SDLK_RIGHT])
{
paddle1x++;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
if(keyheld[SDLK_a])
{
paddle2x--;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
if(keyheld[SDLK_d])
{
paddle2x++;
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
}
apply_surface(0,0,timer,screen);
SDL_Flip(screen);
SDL_Delay(2);
}
return 0;
}
The problem is because you update the backbuffer for every type of paddle move. If both paddles move you end up updating it twice. This is where you are encountering the slowdown. You should only be updating the backbuffer once every frame. Like so:
if(keyheld[SDLK_LEFT])
{
paddle1x--;
}
if(keyheld[SDLK_RIGHT])
{
paddle1x++;
}
if(keyheld[SDLK_a])
{
paddle2x--;
}
if(keyheld[SDLK_d])
{
paddle2x++;
}
// Now we do the update. You can always add a flag to see if the update
// really needs to be done and skip it if it doesn't
apply_surface(0,0,background,screen);
apply_surface(paddle1x,paddle1y,paddle1,screen);
apply_surface(paddle2x,paddle2y,paddle2,screen);
apply_surface(0,0,timer,screen);
SDL_Flip(screen);
SDL_Delay(2);