Sign in to follow this  
ultrasurge

need help with SDL and pong

Recommended Posts

Hey again, I am still pretty new to SDL and im playing around with the graphics, im not actually making pong yet, just trying to figure out some of aspects of SDL. my problem is that I have made moving paddles w/ keyboard input, and barrers on the top and bottom, I have also made a ball move around the screen, but I cannot figure out how to make the paddle move as the ball is moving around, basically put them together and make them work. I dont know if im supposed to make a surface to the ball, and a surface for the paddles or somethign to do with events, please advise, i'll post the code if you need, ill be back to check in two hours or so. thanks

Share this post


Link to post
Share on other sites
Well, if you want an unbeatable computer take the computer's paddle and make it constantly the Y of the ball! Now, if you take that and tone it down a bit, maybe set a maximum speed for the computer and constantly move the computer's paddle's Y to the ball's Y at it's maximum speed, you have a game!

Share this post


Link to post
Share on other sites
yeah, i figured out the game dynamics, where the ball should go and things like that, and i don't really want a unbeatable computer, my problem is that i can't make the keyboard input work with a moving ball, when i try this the keyboard doesn't let the ball move properly, any ideas?

Share this post


Link to post
Share on other sites
Try creating two surfaces - one for the ball and one for the paddle. Create variables (integers or floats) for the positions of the paddles and ball, and another set of variables for the velocity of the ball. Update those only. When it comes time to draw, use the positions of the objects to create destination rectangles.

//Globals
float LeftPaddlePosX;
float LeftPaddlePosY;
float RightPaddlePosX;
float RightPaddlePosY;
float BallPosX;
float BallPosY;
float BallVelX;
float BallVelY;

// Update positions
BallPosX += BallVelX;
BallPosY += BallVelY;
// Use AI to move left paddle. Keyboard to move right paddle

// Draw scene
SDL_Rect destrect = SDL_Rect (LeftPaddlePosX, LeftPaddlePosY, LeftPaddlePosX + paddleWidth, LeftPaddlePosY + paddleheight);
sdl_blit (leftpaddle, 0, screen, destrect);
SDL_Rect destrect = SDL_Rect (RightPaddlePosX, RightPaddlePosY, RightPaddlePosX + paddleWidth, RightPaddlePosY + paddleheight);
sdl_blit (rightpaddle, 0, screen, destrect);
SDL_Rect destrect = SDL_Rect (BallPosX, BallPosY, BallPosX + ballWidth, BallPosY + ballheight);
sdl_blit (ball, 0, screen, destrect);

If this doesn't work, would you mind posting your code for the main game loop and event processor? I just want to make sure that you are not waiting for events to occur before you update your game.

Share this post


Link to post
Share on other sites
first of all, thanks for the detailed reply skittleo, thats my exact problem, and by the way you wrote that explanation it seems like I haven't even structured my program efficiently, Im going to post my code, hopefully you can help me out with it, otherwise thanks again for the help,


#include <SDL/SDL.h>
#include <stdlib.h>

const int SCREEN_WIDTH=640;
const int SCREEN_HEIGHT=480;

SDL_Surface* r_pDisplaySurface = NULL;
SDL_Surface* r_pBitmapSurface = NULL;
SDL_Rect r_SrcRect,r_DstRect;

SDL_Surface* g_pDisplaySurface = NULL;
SDL_Surface* g_pBitmapSurface = NULL;
SDL_Event g_Event;
SDL_Event r_Event;

SDL_Rect g_SrcRect,g_DstRect;

SDL_Event keyevent;


int main(int argc, char* argv[])
{

Uint8* keys;
if (SDL_Init(SDL_INIT_VIDEO)==-1)
{
fprintf(stderr,"Could not initialize SDL!\n");
}

atexit(SDL_Quit);

g_pDisplaySurface=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);
g_pBitmapSurface=SDL_LoadBMP("paddle.bmp");
g_SrcRect.w=g_DstRect.w=g_pBitmapSurface->w;
g_SrcRect.h=g_DstRect.h=g_pBitmapSurface->h;
g_SrcRect.x=g_SrcRect.y=0;

r_pDisplaySurface=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);
r_pBitmapSurface=SDL_LoadBMP("ball.bmp");
r_SrcRect.w=r_DstRect.w=r_pBitmapSurface->w;
r_SrcRect.h=r_DstRect.h=r_pBitmapSurface->h;
r_SrcRect.x=r_SrcRect.y=0;


int a,b,c=0;
int done=0;


while(done == 0)
{
SDL_Event event;

while ( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT ) { done = 1; }

if ( event.type == SDL_KEYDOWN )
{
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
}
}


g_DstRect.x=0;
r_DstRect.x=30;
r_DstRect.y=50;
// r_DstRect.x=50;
//r_DstRect.y=50;


keys = SDL_GetKeyState(NULL);
//---------------------------------------trying to do the movement of ball
for (a=1; a<=20; a++)
{
r_DstRect.x += a;

SDL_BlitSurface(r_pBitmapSurface,&r_SrcRect,r_pDisplaySurface,&r_DstRect);
SDL_UpdateRect(r_pDisplaySurface,0,0,0,0);

}
//---------------------------------------trying to do the movement of ball

if ( keys[SDLK_UP] && g_DstRect.y>-30 ) { g_DstRect.y -= 12; }
if ( keys[SDLK_DOWN] && g_DstRect.y<380 ) { g_DstRect.y += 12; }

SDL_BlitSurface(g_pBitmapSurface,&g_SrcRect,g_pDisplaySurface,&g_DstRect);
SDL_UpdateRect(g_pDisplaySurface,0,0,0,0);


}
return(0);

}






ps sorry for lack of comments ;-)

Share this post


Link to post
Share on other sites
Heh I see your problem. Your ball code and paddle code are intertwined in a way that would produce very strange results .

First, notice how you reset destrect each frame. You want your ball and paddle positions to be persistent AND independent of each other. So you'll need some globals to fix that like I recommended. Don't use the destination rectangle to store the ball and paddle positions. Use it to draw the balls and paddles.

Second, you shouldn't be updating the screen more than once per frame. That while loop where you update the ball position needs to be removed.

Your final code should look similar to this. I based it off of your code. Read through it and see if it makes sense. This code holds no guarantee of working.


#include <SDL/SDL.h>
#include <stdlib.h>

////// GLOBALS

const int SCREEN_WIDTH=640;
const int SCREEN_HEIGHT=480;

SDL_Surface* r_pDisplaySurface = NULL;
SDL_Surface* r_pBitmapSurface = NULL;
SDL_Rect r_SrcRect,r_DstRect;

SDL_Surface* g_pDisplaySurface = NULL;
SDL_Surface* g_pBitmapSurface = NULL;
SDL_Event g_Event;
SDL_Event r_Event;

SDL_Rect g_SrcRect,g_DstRect;

SDL_Event keyevent;

float LeftPaddlePosX;
float LeftPaddlePosY;
float RightPaddlePosX;
float RightPaddlePosY;
float BallPosX;
float BallPosY;
float BallVelX;
float BallVelY;

int main(int argc, char* argv[])
{

Uint8* keys;
if (SDL_Init(SDL_INIT_VIDEO)==-1)
{
fprintf(stderr,"Could not initialize SDL!\n");
}

atexit(SDL_Quit);

g_pDisplaySurface=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);
g_pBitmapSurface=SDL_LoadBMP("paddle.bmp");
g_SrcRect.w=g_DstRect.w=g_pBitmapSurface->w;
g_SrcRect.h=g_DstRect.h=g_pBitmapSurface->h;
g_SrcRect.x=g_SrcRect.y=0;

r_pDisplaySurface=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,0,SDL_ANYFORMAT);
r_pBitmapSurface=SDL_LoadBMP("ball.bmp");
r_SrcRect.w=r_DstRect.w=r_pBitmapSurface->w;
r_SrcRect.h=r_DstRect.h=r_pBitmapSurface->h;
r_SrcRect.x=r_SrcRect.y=0;

int a,b,c=0;
int done=0;

// Set initial component positions
LeftPaddlePosX = 50;
LeftPaddlePosY = 100;
BallPosX = 150;
BallPosY = 250;
BallVelX = 0.25f;
BallVelY = 0.25f;

while(done == 0)
{
SDL_Event event;

while ( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT ) { done = 1; }

if ( event.type == SDL_KEYDOWN )
{
if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; }
}
}

keys = SDL_GetKeyState(NULL);

// Move the ball
BallPosX += BallVelX;
BallPosY += BallVelY;

// Draw the ball
g_DstRect.x = BallPosX
g_DstRect.y = BallPosY
SDL_BlitSurface(r_pBitmapSurface,&r_SrcRect,r_pDisplaySurface,&r_DstRect);
SDL_UpdateRect(r_pDisplaySurface,0,0,0,0);


// Move the paddle
if ( keys[SDLK_UP] && LeftPaddlePosY >-30 ) { LeftPaddlePosY -= 12; }
if ( keys[SDLK_DOWN] && LeftPaddlePosY <380 ) LeftPaddlePosY += 12; }

// Draw the paddle
g_DstRect.x = LeftPaddlePosX;
g_DstRect.y = LeftPaddlePosY;
SDL_BlitSurface(g_pBitmapSurface,&g_SrcRect,g_pDisplaySurface,&g_DstRect);

// Update the screen
SDL_UpdateRect(g_pDisplaySurface,0,0,0,0);

}

// TODO: HERE YOU NEED TO CLEAN UP ALL OF YOUR RESOURCES

return(0);
}


Share this post


Link to post
Share on other sites
hey

thanks for the reply, i think i understand the way sdl works now, im sure i'll be able to figure it out now, ill reply once im finished or if i have another question.

thanks again.

Share this post


Link to post
Share on other sites
k, i got the ball to move with the paddle, what is with the lag tho? the ball slows down then the paddle slows down and vice versa.. im thinkin i need to do some kind of resource clearing or something like skittleo said

// TODO: HERE YOU NEED TO CLEAN UP ALL OF YOUR RESOURCES

but I don't quite know how to do that, any help would be appreciated.

thanks in advance

Share this post


Link to post
Share on other sites
btw i just tried a double buff:

g_pDisplaySurface=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,32,SDL_DOUBLEBUF);
r_pDisplaySurface=SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,32,SDL_DOUBLEBUF);

it helped smooth out a little bit, but not as much as i like, it still slows down
any ideas,
thanks

Share this post


Link to post
Share on other sites
Because you use a while loop to process your messages, this means that if you get a lot of window messages, as you might with constant key input, then you will spend a lot of time processing them. Try changing while to if SDL_PollEvent and see if that helps any.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this