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);
Related
I was making a little program to practice pointer usage and rendering.
I was trying to debug an Illegal memory access, and my program crashed.
The problem, is that it crashed and I had to force-quit the debugging session by pressing shift-f5
because my program was taking mouse focus, and I could not click anything.
Now my screen is constantly brighter than before, probably due to an draw operation that was supposed to draw a fullscreen white rectangle.
This will probably be fixed when I restart my PC.... but it is still a problem if this stacks, since I will have to restart every 3 debugging sessions to not burn my eyes.
Any advice on how to ENSURE my program releases resources?
Edit for reproducible example:
#include "SDL.h"
#include "SDL_render.h"
#include <stdio.h>
#include <iostream>
#include <list>
#include <string>
#include <ft2build.h>
#include <SDL_ttf.h>
#include <functional>
#include <memory>
#include FT_FREETYPE_H
struct element {
SDL_Rect* area;
SDL_Texture* texture;
SDL_Surface* surface;
std::string name = "";
std::function<void()> functionPointer;
element(SDL_Rect* rect, SDL_Texture* tex, SDL_Surface* surf, std::string elementName, std::function<void()> fp) {
area = rect;
texture = tex;
surface = surf;
name = elementName;
functionPointer = fp;
}
~element() {
SDL_FreeSurface(surface);
SDL_DestroyTexture(texture);
area = nullptr;
surface = nullptr;
texture = nullptr;
name = "";
functionPointer = nullptr;
}
};
struct screenVariables {
std::list<SDL_Texture*> textureList;
std::list<element*>& elementList;
SDL_Renderer* renderer;
std::list<SDL_Surface*> surfaceList;
screenVariables(std::list<SDL_Texture*> tex, std::list<element*> rec, SDL_Renderer* render,std::list<SDL_Surface*> surf) :
textureList(tex),elementList(rec), renderer(render),surfaceList(surf) {};
};
class gameHandler{
private:
SDL_Window* screen;
SDL_Renderer* renderer;
SDL_Texture* mainBlock;
bool saveAvailable = false;
bool quit = false;
std::list<SDL_Texture*> textureList;
std::list<element*> elementList;
std::list<SDL_Surface*> surfaceList;
screenVariables screenInfo{ textureList, elementList, renderer, surfaceList };
void nothing() {};
void continuePressed() {};
void newGame() {};
public:
gameHandler() {
SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS);
TTF_Init();
screen = SDL_CreateWindow("Game Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
1920, 1080,
SDL_WINDOW_FULLSCREEN | SDL_WINDOW_OPENGL);
renderer = SDL_CreateRenderer(screen, -1, 0);
mainBlock = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ABGR8888,
SDL_TEXTUREACCESS_TARGET, 1920, 1080);
}
//All methods that do operations on elements will operate on the LAST ADDED ELEMENT. Always create a new element and use push_back() to add it to the end.
//Everything commented out is not nessesary for reproduction, but
//will be left for reference.
/*bool showFirstElement(screenVariables& arg, const char* imgPath, SDL_Rect* area) {
SDL_Renderer* renderRef = arg.renderer;
//The following line means: end() returns an iterator, take the iterator and make it go back once, then deference it to get the value.
//This gets the value of the last added surface.
SDL_Surface* newSurface = *(--(arg.surfaceList.end()));
newSurface = SDL_LoadBMP(imgPath);
SDL_Texture* newTexture = *(--(arg.textureList.end()));
newTexture = SDL_CreateTextureFromSurface(renderRef, newSurface);
std::function<void()> nothingWrapper = [&]() { nothing(); };
element* toBeModified = *(--(arg.elementList.end()));
toBeModified->element::area = area;
toBeModified->texture = newTexture;
toBeModified->surface = newSurface;
toBeModified->name = imgPath;
toBeModified->functionPointer = nothingWrapper;
arg.elementList.push_back(toBeModified);
SDL_RenderCopy(renderRef, newTexture, NULL, area);
return true;
}
bool textOnElement(screenVariables& arg, const char* text,int points, element* el) {
SDL_Renderer* renderRef = arg.renderer;
TTF_Font* font = NULL;
SDL_Color textColor = { 0,0,0 };
font = TTF_OpenFont("TravelingTypewriter.ttf", points);
SDL_Surface* newSurface = *(--(arg.surfaceList.end()));
newSurface = TTF_RenderText_Solid(font,text,textColor);
SDL_Texture* newTexture = *(--(arg.textureList.end()));
newTexture = SDL_CreateTextureFromSurface(renderRef, newSurface);
el->surface = newSurface;
el->texture = newTexture;
SDL_RenderCopy(renderRef, newTexture, NULL, el->area);
return true;
}
element* checkClickedElement(screenVariables& arg, SDL_Point pos) {
for (element* i : arg.elementList) {
if (SDL_PointInRect(&pos, i->area)) {
return i;
}
return nullptr;
}
}
bool fillWithColor(screenVariables& arg, Uint32 red, Uint32 green, Uint32 blue, Uint32 alpha) {
SDL_Renderer* renderRef = arg.renderer;
SDL_Surface* surface = SDL_CreateRGBSurface(0, 1920, 1080, 8, red, green, blue, alpha);
SDL_Texture* texture = SDL_CreateTextureFromSurface(renderRef, surface);
SDL_Rect fullScreen = { 1920,1080 };
std::string name = "R" + std::to_string(red) + "G" + std::to_string(green) + "B" + std::to_string(blue);
std::function<void()> nothingWrapper = [&]() { nothing(); };
element newElement = element(&fullScreen, texture, surface, name, nothingWrapper);
SDL_RenderCopy(renderRef, texture, NULL, NULL);
return true;
}
bool fillElementPointer(screenVariables& arg, SDL_Point leftTop, SDL_Point rightBottom, std::function<void()> fp,std::string name,element* newElement) {
SDL_Rect newRect;
newRect.x = (leftTop.x + rightBottom.x) / 2;
newRect.y = (leftTop.y + rightBottom.y) / 2;
newRect.w = (rightBottom.x - leftTop.x);
newRect.h = (leftTop.y - rightBottom.y);
newElement = &element(&newRect, nullptr, nullptr, name, fp);
arg.elementList.push_back(newElement);
return true;
}
//This allows me to create pointers that will not go out of scope when methods return. Always use this method if the element you will create needs to presist through functions.
element* createElementPointer(){
element* newPointer = nullptr;
return newPointer;
}
int showMenu(screenVariables& arg) {
fillWithColor(arg, 255, 255, 255, 255);
SDL_Point leftTop = { 200,700 };
SDL_Point rightBottom = { 600,200 };
std::function<void()> nothingWrapper = [&]() { nothing(); };
element* titleText = createElementPointer();
if (!fillElementPointer(screenInfo, leftTop, rightBottom, nothingWrapper, "titleText", titleText)) {
std::cout << "createElement failed in showMenu()";
}
leftTop.y = 100;
rightBottom.x = 0;
element* continueOrStart = createElementPointer();
if (saveAvailable) {
std::function<void()> continueWrapper = [&]() { continuePressed(); };
if (!fillElementPointer(screenInfo, leftTop, rightBottom, continueWrapper, "continueButton", continueOrStart)) {
std::cout << "createElement failed in showMenu() saveAvailable.";
}
textOnElement(arg, "Continue", 16, continueOrStart);
}
else {
std::function<void()> newGameWrapper = [&]() { newGame(); };
if (!fillElementPointer(screenInfo, leftTop, rightBottom, newGameWrapper, "newGameButton", continueOrStart)) {
std::cout << "createElement failed in showMenu() !saveAvailable.";
}
textOnElement(arg, "New Game", 16, continueOrStart);
}
return 0;
}
void mainLoop() {
SDL_Event event;
showMenu(screenInfo);
while (!quit) {
SDL_RenderClear(renderer);
while (SDL_PollEvent(&event) != 0) {
switch (event.type)
{
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT) {
SDL_Point position = { event.button.x,event.button.y };
element* result = checkClickedElement(screenInfo, position);
if (result == nullptr) {
break;
}
else {
result->functionPointer();
}
}
break;
case SDL_QUIT:
quit = true;
break;
}
}
SDL_RenderPresent(renderer);
}
}
void clearResources() {
int index{ 0 };
for (element* i : screenInfo.elementList) {
delete i;
}
SDL_DestroyRenderer(renderer);
SDL_Quit();
} */
};
int main(int argc, char* argv[]) {
gameHandler handler; //This alone makes my screen brighter.
//Uncomment every function and let mainLoop() run, and it crashes.
//Although many attempts at making this exception safe, it did not work.
//handler.mainLoop();
return 0;
}
This is basically my code here, very simple just to load an image to display. But the first thing I open a window surface, the surface has characters like 'X','S' out of nowhere:
int main( int argc, char* args[] )
{
SDL_Init( SDL_INIT_VIDEO );
SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 0,
SDL_HWSURFACE | SDL_DOUBLEBUF );
SDL_WM_SetCaption( WINDOW_TITLE, 0 );
SDL_Surface* bitmap = SDL_LoadBMP("bat.bmp");
// Part of the bitmap that we want to draw
SDL_Rect source;
source.x = 24;
source.y = 63;
source.w = 65;
source.h = 44;
// Part of the screen we want to draw the sprite to
SDL_Rect destination;
destination.x = 100;
destination.y = 100;
destination.w = 65;
destination.h = 44;
SDL_Event event;
bool gameRunning = true;
int i=1000;
while (i)
{
if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
}
SDL_BlitSurface(bitmap, &source, screen, &destination);
SDL_Flip(screen);
i--;
}
SDL_FreeSurface(bitmap);
SDL_Quit();
return 0;
}
I'm currently having a problem with my pong game. I'm trying to smooth out the player movement (so it wont stutter so much when is moves, and no delay after first keypress)
This is my code so far, problem is while I've got the movement smoother the _paddle move too fast! and I don't now how to make it move slower!
Is there a way i can make the _paddle move slower or did i write the code wrong?
maingame.h
#pragma once
#include <iostream>
#include <SDL/SDL.h>
#include <string>
#include "maingame.h"
class maingame
{
public:
maingame();
~maingame();
//loads pictures
bool loadMedia(std::string path);
//init the system
void init();
//runs the game
void run();
//THE EPIC GAMELOOP
void gameloop();
//draw the screen
void draw();
void UserInput();
private:
//window
SDL_Window* _window;
//redenderer
SDL_Renderer* _rend;
//the screens surface
SDL_Surface* _screensurface;
//player, ai and the ball
SDL_Rect _paddle;
SDL_Rect _ai;
SDL_Rect _ball;
//checks if you pressed down the W or S button
bool keydown_w = false;
bool keydown_s = false;
//Event for the pall stuff
SDL_Event e;
};
maingame.c
#include "maingame.h"
/*
PONG V0.2
Black background - CHECK
paddle appear on screen - CHECK
other paddle appear on screen - CHECK
ball appear on screen - CHECK
move player paddle - CHECK
impossible to move outside of map - CHECK
movement smoother -
make ball go around -
collison with paddles -
keep scores -
show scores -
make a 2nd player chooseable -
*/
//screen width and height
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 768;
maingame::maingame()
{
_window = nullptr;
_rend = nullptr;
}
maingame::~maingame()
{
}
void maingame::init()
{
SDL_Init(SDL_INIT_EVERYTHING);
}
void maingame::run()
{
init();
//creating a windows
_window = SDL_CreateWindow("PONG", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
//create the render
_rend = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
//set out the player
_paddle.x = 100;
_paddle.y = (SCREEN_HEIGHT / 2) - 100;
_paddle.w = 20;
_paddle.h = 200;
//set out the ai
_ai.x = SCREEN_WIDTH - 100;
_ai.y = (SCREEN_HEIGHT / 2) - 100;
_ai.w = 20;
_ai.h = 200;
//set out the ball
_ball.x = SCREEN_WIDTH / 2 - 20;
_ball.y = (SCREEN_HEIGHT / 2) - 20;
_ball.w = 20;
_ball.h = 20;
draw();
gameloop();
}
void maingame::draw()
{
//make the render be black
SDL_SetRenderDrawColor(_rend, 0, 0, 0, 0);
//Clear the render with the color we set with SDL_SetRenderDrawColor, in this case black
SDL_RenderClear(_rend);
//make the next things we will render white
SDL_SetRenderDrawColor(_rend, 255, 255, 255, 0);
//make the paddle, ai and ball the color of SDL_SetRenderDrawColor, which is whites in this case
SDL_RenderFillRect(_rend, &_paddle);
SDL_RenderFillRect(_rend, &_ai);
SDL_RenderFillRect(_rend, &_ball);
//SDL_RenderDrawRect(_rend, &_paddle);
//Present the render, draw it to the screen
SDL_RenderPresent(_rend);
}
bool maingame::loadMedia(std::string path)
{
//Loading success flag
bool success = true;
SDL_Surface* pic;
//Load splash image
pic = SDL_LoadBMP(path.c_str());
if (pic == NULL)
{
printf("Unable to load image %s! SDL Error: %s\n", "02_getting_an_image_on_the_screen/hello_world.bmp", SDL_GetError());
success = false;
}
return success;
}
void maingame::gameloop()
{
const Uint8 *keys = SDL_GetKeyboardState(NULL);
bool keydown_w = false;
bool keydown_s = false;
while (true)
{
while (SDL_PollEvent(&e) != 0)
{
//pressed the X, quit the program
if (e.type == SDL_QUIT)
{
exit(1);
}
UserInput();
}
UserInput();
draw();
}
}
void maingame::UserInput()
{
float lol = 0;
//Pressed a key!
if (e.type == SDL_KEYDOWN)
{
//pressed W, move the player
if (e.key.keysym.sym == SDLK_w)
{
keydown_w = true;
}
//pressed S, move the player
else if (e.key.keysym.sym == SDLK_s)
{
keydown_s = true;
}
}
if (e.type == SDL_KEYUP)
{
std::cout << keydown_w << std::endl;
if (e.key.keysym.sym == SDLK_w)
keydown_w = false;
if (e.key.keysym.sym == SDLK_s)
keydown_s = false;
}
if (keydown_w)
{
if (_paddle.y > 1)
{
_paddle.y -= 1;
}
std::cout << keydown_w << std::endl;
}
if (keydown_s)
{
if (_paddle.y < SCREEN_HEIGHT - _paddle.h)
{
_paddle.y += 1;
}
}
}
It maybe bad programming practice to do so but the only way I would see getting around your problem is to add an SDL_Delay() in your gameloop function. I would suggest you use it as a temporary fix until you find an alternative solution. Hope this helps.
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.
I am working on building a game, and I get a compiling error apply_surface was not declared in this scope. the error is in line 95, in the function User::show().
EDIT: Now that it is fized, the image "baz", is not showing up on the screen. sorry for the edit.
/*This source code copyrighted by Lazy Foo' Productions (2004-2013)
and may not be redistributed without written permission.*/
//The headers
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include <string>
SDL_Surface *background = NULL;
SDL_Surface *screen = NULL;
SDL_Surface *baz = NULL;
SDL_Event event;
void cleanup()
{
SDL_FreeSurface(background);
SDL_FreeSurface(screen);
SDL_FreeSurface(baz);
SDL_Quit;
}
bool quit = false;
class User
{
private:
SDL_Surface *baz = NULL;
SDL_Surface *screen = NULL;
int x;
int y;
int xVel;
int yVel;
public:
void keys();
void move();
void show();
void user();
};
void User::keys()
{
while(quit == false)
if(SDL_PollEvent(&event))
{
if( event.type == SDL_QUIT )
quit = true;
}
Uint8 *keystates = SDL_GetKeyState(NULL);
if(keystates[SDLK_d] )
{
User::xVel+=50;
}
if(keystates[SDLK_a])
{
User::xVel-=50;
}
if(keystates[SDLK_s])
{
User::yVel+=50;
}
if(keystates[SDLK_w])
{
User::yVel-=50;
}
if(keystates[SDLK_ESCAPE])
{
cleanup();
}
}
void User::user()
{
x = 0;
y = 0;
xVel = 0;
yVel = 0;
}
void User::move()
{
x+=xVel;
y+=yVel;
x-=xVel;
}
void User::show()
{
apply_surface(x,y,baz,screen);
SDL_Flip( screen );
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{ //Temporary rectangle to hold the offsets
SDL_Rect offset;
//Get the offsets
offset.x = x;
offset.y = y; //Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
int main( int argc, char* argv[])
{
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(640,400,32,SDL_SWSURFACE);
background = IMG_Load("background.png");
baz = IMG_Load("baz.png");
apply_surface(0,0,background,screen);
SDL_Flip(screen);
while( quit == false )
{
User Baz;
Baz.user();
Baz.keys();
Baz.move();
Baz.show();
if(quit == true)
{
cleanup();
}
}
return 0;
}
your apply_surface() function is not declared within the scope
So move your code :
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination )
{ //Temporary rectangle to hold the offsets
SDL_Rect offset;
//Get the offsets
offset.x = x;
offset.y = y; //Blit the surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
to the top ( before you use it )
Or else
Add a function prototype at the top like this :
void apply_surface( int, int, SDL_Surface*, SDL_Surface*);