Sign in to follow this  

Quick Question in SDL

This topic is 4514 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Ok, I'm making my pong game in SDL, i'm now at the point to move the ball around. Give it a random vector at start and calculate the next vecto when it's hit something depending of the angle... I was wondering how exactly how i do that in SDL, i got no trouble animating the bar and setting up limit, but how can i animate an object always ( until it goes on the "win limit" ) If anyone has explanation or maybe a tutorials i would be happy. And also I would like also how exactly work the "colision" between the ball and the bar, since the limit on the side are static it's not hard to say you can't go any further but since the bar keep moving it's a bit harder. thank

Share this post


Link to post
Share on other sites
i'v came up with something like that but it doens't seem to be working exactly like i want, the ball move way to fast.


void Move_Ball(int x, int y)
{
while ( !Check_Win(xpos3, ypos3) )
{
xpos3 +=2;
ypos3 +=2;
}
}

bool Check_Win(int x, int y)
{
bool bOk = false;

if ( y <= 0 )
{
bOk = true;
iPlayer1Score++;
}
else
{
if ( y >= 640)
{
bOk = true;
iPlayer2Score++;
}
}
return bOk;
}



If anyone have another idea ^^

Share this post


Link to post
Share on other sites
I found the funtion SDL_GetTicks(); and i think i could use it to make the ball move slower, but I'm not exactly sure how to use that, if someone know about it could you explain me please?


Now look like that

void Move_Ball(int x, int y)
{
float fTicks = SDL_GetTicks();
while ( !Check_Win(xpos3, ypos3) )
{
if ( SDL_GetTicks() > fTicks+0.0001 )
{
xpos3 +=25;
ypos3 +=25;
fTicks = SDL_GetTicks();
}
}
}


Share this post


Link to post
Share on other sites
Quote:
Original post by Ekim_Gram
1) Don't just post four times in your own topic, use the edit feature.

2) You may want to check out this article on frame based movement.


1. Sorry, tough people wouldn't see if i only edit i'll just say i did edit in title next time.

2. I took a look on your link, but that doens't seem to help me, i'm not sure what it do exactly, and how to make it work like i want.

I found 2 things thatm might help me :

Uint32 SDL_GetTicks(void);
void SDL_Delay(Uint32 ms);

but i don't know how to make one of them work corectly.

Share this post


Link to post
Share on other sites
Don't use delay.

The following is an except from my Tetris clone


float Start_Time = 0;
void Drop()
{
if((SDL_GetTicks() - Start_Time) > (1000))
{
Piece.Move(0,1); // Move the piece down
Start_Time = SDL_GetTicks();
}
}


If 1000 miliseconds/1 second has passed, the piece would move down 1 unit (32 pixels in my case).

Share this post


Link to post
Share on other sites
I understand what you have wrote, and how it should act, but since i did add it to my code it's load my system real bad and the game run, but i can't move anything and when i try to close the window i get an error.

Here's my code


void Move_Ball(int x, int y)
{
float Start_Time = 0;

//float fTicks = SDL_GetTicks();
while ( !Check_Win(xpos3, ypos3) )
{
if((SDL_GetTicks() - Start_Time) > (1000))
{
xpos3 +=2;
ypos3 +=2;
Start_Time = SDL_GetTicks();
}
}
}



is it because of my while that would be looping so fast that my system become loaded?

Share this post


Link to post
Share on other sites
Sure


#include <SDL.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <conio.h>

using namespace std;

void Init_SDL();
//void DrawPixel(SDL_Surface *screen, int x, int y,Uint8 R, Uint8 G, Uint8 B);
//void Draw_Bg(SDL_Surface *screen);
void Slock(SDL_Surface *screen);
void Sulock(SDL_Surface *screen);
void Init_Images();
void Draw_Start();
void Draw_BG();
void DrawIMG(SDL_Surface *img, int x, int y);
void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2);
void Draw_scenes();
bool Check_Limits_Left(int x);
bool Check_Limits_Right(int x);
void Move_Ball(int x, int y);
bool Check_Win(int x, int y);


SDL_Surface *screen;
SDL_Surface *back;
SDL_Surface *Palette1;
SDL_Surface *Palette2;
SDL_Surface *Balle;
SDL_Surface *Start;

int xpos=260,ypos=460;
int xpos2=260,ypos2=20;
int xpos3=260,ypos3=220;

Uint32 SDL_GetTicks(void);



int iPlayer1Score = 0;
int iPlayer2Score = 0;

string sLastWinner = "";
string sPlayer1 = "Player1";
string sPlayer2 = "Player2";






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

char cChoice;


Init_SDL();
Init_Images();
Draw_Start();
Draw_BG();


int iDone=0;

//Uint8* keys2;

while(iDone == 0)
{
SDL_Event event;
Uint8* keys;
keys = SDL_GetKeyState(NULL);
while ( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT ) { iDone = 1; }

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

//keys2 = SDL_GetKeyState(NULL);
//if ( keys[SDLK_UP] ) { ypos -= 1; }
//if ( keys[SDLK_DOWN] ) { ypos += 1; }

//Player 1
if ( keys[SDLK_LEFT] && (!Check_Limits_Left(xpos)) )
{
xpos -= 6;
}

if ( keys[SDLK_RIGHT]&& (!Check_Limits_Right(xpos)) )
{
xpos += 6;
}

//Player 2

if ( keys[SDLK_a] && (!Check_Limits_Left(xpos2)) )
{
xpos2 -= 6;
}
if ( keys[SDLK_s] && (!Check_Limits_Right(xpos2)) )
{
xpos2 += 6;
}

Draw_scenes();
Move_Ball(xpos3,ypos3);
}

return 0;
}

void Init_SDL()
{
if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0 )
{
cout << "Can't init SDL" << endl << SDL_GetError();
}

screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);

if ( screen == NULL )
{
cout << "Can't set resolution to 640x480x32" << endl << SDL_GetError();
}

}

void Slock(SDL_Surface *screen)
{
if ( SDL_MUSTLOCK(screen) )
{
if ( SDL_LockSurface(screen) < 0 )
{
return;
}
}
}

void Sulock(SDL_Surface *screen)
{
if ( SDL_MUSTLOCK(screen) )
{
SDL_UnlockSurface(screen);
}
}

void Init_Images()
{
back = SDL_LoadBMP("BG.bmp");
Palette1 = SDL_LoadBMP("Palette1.bmp");
Palette2 = SDL_LoadBMP("Palette2.bmp");
Balle = SDL_LoadBMP("Balle.bmp");
Start = SDL_LoadBMP("StartMenu.bmp");

}

void Draw_Start()
{
DrawIMG(Start, 0,0);
}

void Draw_BG()
{
Slock(screen);
DrawIMG(back, 0, 0);
Sulock(screen);
}

void DrawIMG(SDL_Surface *img, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
}

void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_Rect dest2;
dest2.x = x2;
dest2.y = y2;
dest2.w = w;
dest2.h = h;
SDL_BlitSurface(img, &dest2, screen, &dest);
}

void Draw_scenes()
{
Slock(screen);
Draw_BG();
DrawIMG(back,xpos-2,ypos-2,150,160,xpos-2,ypos-2);
DrawIMG(Palette1, xpos,ypos);
DrawIMG(Palette2, xpos2,ypos2);
DrawIMG(Balle, xpos3, ypos3);
SDL_Flip(screen);
Sulock(screen);
}

bool Check_Limits_Left(int x)
{
bool bOk = false;

if ( x <= 0 )
{
bOk = true;
}

return bOk;
}

bool Check_Limits_Right(int x)
{
bool bOk = false;

if ( x >= 520 )
{
bOk = true;
}

return bOk;
}

void Move_Ball(int x, int y)
{
float Start_Time = 0;

//float fTicks = SDL_GetTicks();
while ( !Check_Win(xpos3, ypos3) )
{
if((SDL_GetTicks() - Start_Time) > (1000))
{
xpos3 +=2;
ypos3 +=2;
Start_Time = SDL_GetTicks();
}
}
}

bool Check_Win(int x, int y)
{
bool bOk = false;

if ( y <= 0 )
{
bOk = true;
iPlayer1Score++;
xpos3 = 260;
ypos3 = 220;
Draw_scenes();
}
else
{
if ( y >= 640)
{
bOk = true;
iPlayer2Score++;
xpos3 = 260;
ypos3 = 220;
Draw_scenes();
}
}
return bOk;
}



My code became a bit messy with all the change i tried to fix the speed of the ball, if there is something you don't understand in my logic ask.

Share this post


Link to post
Share on other sites
Alright, just by looking at your code I've come across a bunch of problems.

1) You need to call SDL_FreeSurface on all of your sources to clean up all the used memory when the program is done.

2) Get rid of the locking and unlocking of the screen surface. You don't need it, it's wasting resources and code.

3) You don't need the second DrawIMG function with all those parameters. That's for blitting a part of a surface on to another part of a surface.

4) Your DrawScene function doesn't need the call to DrawIMG right after DrawBG.

void Draw_scenes()
{
Draw_BG();
DrawIMG(Palette1, xpos,ypos);
DrawIMG(Palette2, xpos2,ypos2);
DrawIMG(Balle, xpos3, ypos3);
SDL_Flip(screen);
}
5) You should really think of giving your variables better names. Just by reading your code and seeing variables like xpos2, and ypos3 makes your code rather cryptic and doesn't allow for simple understanding of what they do.

Share this post


Link to post
Share on other sites
I'v removed the insane amount of lag by changing my code of my Move_Ball a bit it is now


void Move_Ball(int x, int y)
{
float Start_Time = 0;


if((SDL_GetTicks() - Start_Time) > (10))
{
while ( !Check_Win(xpos3, ypos3) )
{
xpos3 +=2;
ypos3 +=2;
}
Start_Time = SDL_GetTicks();
}
}



I just switched the if and the while so the while isn't always being in use for nothing.

1. How exactly i do that? and when the program is done? Like when i close the game?

2. Yes i was supose to get ride of it but i didn't because i forgot.

3. Alright i didn't know that.

4. If i remove the DrawIMG my image won't load? Or did i missunderstood what you mean.

5. Yes i know some variables name aren't significativ, those xpos and the like are from code of a tutorials i took, else they all should be alright, i got really rude teacher about that. :)

And also my ball is still not moving right now :( but i'm gona fix my code a bit before i try again.

Share this post


Link to post
Share on other sites
Alright i have cleared the useless code and fixed variable names, if something is still not right, feel free to tell me.

I also did add this SDL_FreeSurface like you told me, not sure if i did it right tho.

Here the new code


#include <SDL.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <conio.h>

using namespace std;

void Init_SDL();
void Init_Images();
void Draw_Start();
void Draw_BG();
void DrawIMG(SDL_Surface *img, int x, int y);
void Draw_scenes();
bool Check_Limits_Left(int x);
bool Check_Limits_Right(int x);
void Move_Ball(int x, int y);
bool Check_Win(int x, int y);
void SDL_FreeSurface(SDL_Surface *surface);

SDL_Surface *screen;
SDL_Surface *Background;
SDL_Surface *BarPlayer1;
SDL_Surface *BarPlayer2;
SDL_Surface *Ball;
SDL_Surface *Start;

int BgXposition = 0, BgYposition = 0; //X and Y Start position for the Background
int Player1Xposition = 260, Player1Yposition = 460; // X,Y Start position for the player1 bar
int Player2Xposition = 260, Player2Yposition = 20; // X,Y start position for the player2 bar
int BallXposition = 260, BallYposition = 220; // x,y start position for the ball
int iPlayer1Score = 0; // Score of player1
int iPlayer2Score = 0; // Score of player2

string sLastWinner = ""; // string that contain name of the winner of the last round
string sPlayer1 = "Player1"; // Name of the player1
string sPlayer2 = "Player2"; // Name of the player2

Uint32 SDL_GetTicks(void);


int main(int argc, char *argv[])
{
Init_SDL();
Init_Images();
Draw_Start();
Draw_BG();

int iQuit=0; // Variable used to see if user want to quit the game
// 1 to quit
while(iQuit == 0) // While the user doens't want to quit
{
SDL_Event event;
Uint8* keys;
keys = SDL_GetKeyState(NULL);
while ( SDL_PollEvent(&event) )
{
if ( event.type == SDL_QUIT )
{
iQuit = 1;
}

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

//Player 1 Bar Move
//If the player1 is pressing the key and isn't off limit
if ( keys[SDLK_LEFT] && (!Check_Limits_Left(Player1Xposition)) )
{
Player1Xposition -= 6; // Decrease X position of player1 Bar
}
//If the player1 is pressing the key and isn't off limit
if ( keys[SDLK_RIGHT]&& (!Check_Limits_Right(Player1Xposition)) )
{
Player1Xposition += 6; // Increase X position of player1 Bar
}

//Player 2 Bar Move
//If the player2 is pressing the key and isn't off limit
if ( keys[SDLK_a] && (!Check_Limits_Left(Player2Xposition)) )
{
Player2Xposition -= 6; //decrease X position of player2 bar
}
//If the player2 is pressing the key and isn't off limit
if ( keys[SDLK_s] && (!Check_Limits_Right(Player2Xposition)) )
{
Player2Xposition += 6; //Increase X position of player2 bar
}
Draw_scenes();
Move_Ball(BallXposition,BallYposition); // Call the function that will move the ball
}

SDL_FreeSurface(screen);
SDL_FreeSurface(Background);
SDL_FreeSurface(BarPlayer1);
SDL_FreeSurface(BarPlayer2);
SDL_FreeSurface(Ball);
SDL_FreeSurface(Start);

return 0;
}

void Init_SDL()
{
if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0 )
{
cout << "Can't init SDL" << endl << SDL_GetError();
}

screen = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE|SDL_DOUBLEBUF);

if ( screen == NULL )
{
cout << "Can't set resolution to 640x480x32" << endl << SDL_GetError();
}

}

void Init_Images()
{
Background = SDL_LoadBMP("BG.bmp");
BarPlayer1 = SDL_LoadBMP("Palette1.bmp");
BarPlayer2 = SDL_LoadBMP("Palette2.bmp");
Ball = SDL_LoadBMP("Balle.bmp");
Start = SDL_LoadBMP("StartMenu.bmp");

}
// Not used yet
void Draw_Start()
{
DrawIMG(Start, 0,0);
}
//Draw the background at origin (0,0)
void Draw_BG()
{
DrawIMG(Background, BgXposition, BgYposition);
}

void DrawIMG(SDL_Surface *img, int x, int y)
{
SDL_Rect dest;
dest.x = x;
dest.y = y;
SDL_BlitSurface(img, NULL, screen, &dest);
}

void Draw_scenes()
{
Draw_BG();
DrawIMG(Background,BgXposition,BgYposition);
DrawIMG(BarPlayer1, Player1Xposition ,Player1Yposition);
DrawIMG(BarPlayer2, Player2Xposition,Player2Yposition);
DrawIMG(Ball, BallXposition, BallYposition);
SDL_Flip(screen);
}
//Input : X, the X position of the object to check limits
//Use : Check if the bar is at the limit of the left screen
//Output : bOk, True if the bar is at the screen limit, else false
bool Check_Limits_Left(int x)
{
bool bOk = false;

if ( x <= 0 ) // If touching the left screen
{
bOk = true;
}

return bOk;
}
//Input : X, the X position of the object to check limits
//Use : Check if the bar is at the limit of the right screen
//Output : bOk, True if the bar is at the screen limit, else false
bool Check_Limits_Right(int x)
{
bool bOk = false;

if ( x >= 520 ) // If touching the right screen
{
bOk = true;
}

return bOk;
}
//Input : The X and Y position of the ball
//Use : Move the ball around the screen
//Output : None
void Move_Ball(int x, int y)
{
float Start_Time = 0;

if((SDL_GetTicks() - Start_Time) > (10000))
{
while ( !Check_Win(BallXposition, BallYposition) )
{
BallXposition +=2;
BallYposition +=2;
}
Start_Time = SDL_GetTicks();
}
}
//Input : the X and Y position of the ball
//Use : Check if someone has win, when the ball is at top or bottum limit of the screen
//Output : bOk, true is there is a winner, else false
bool Check_Win(int x, int y)
{
bool bOk = false;

if ( y <= 0 ) // If the ball is at the top of the screen
{
bOk = true;
iPlayer1Score++;
BallXposition = 260;
BallYposition = 220;
Draw_scenes();
}
else
{
if ( y >= 640) // If it's at the bottum of the screen
{
bOk = true;
iPlayer2Score++;
BallXposition = 260;
BallYposition = 220;
Draw_scenes();
}
}
return bOk;
}



The ball still can't move and i don't understand why :(

Share this post


Link to post
Share on other sites
1) You don't need a prototype for SDL_FreeSurface.

2) Alright, I'm gonna retrofit part of main and moveball for you


int main()
{
float Start_Time = 0;
...
if((SDL_GetTicks() - Start_Time) > (10000))
{
Move_Ball();
}
}

void Move_Ball()
{
if (!Check_Win()) // You had a while here, big no-no because if the code had worked before,the ball
// would just keep moving until there was a win check and nothing else could be done
{
BallXPos += 2;
BallYPos += 2;
}
}


Since you are using globals and programming procedurally (not object oriented) you do not need to use parameters for your functions if the variables that are being passed are already global.

Share this post


Link to post
Share on other sites
1) Thank i didn't know

2) Thank this is working now, i understand your logic and it's pretty good, the game also did stop to load after 6-7 second.

3) Yes i know, but i usualy don't use globals since my teachers doens't allow us ;)

Question, when you load an image and set it's position, what point of the image is set to the X,Y top left? Midlle?

and also, thank a lot dude, you did help me a lot, i think i won't have much problem next time ( i hope ;) )

Share this post


Link to post
Share on other sites
The (x,y) position of an image is starting at the top left (0,0) corner of that image.

And no problem for the help, I had a lot of trouble starting (still do from time to time) and I know how it feels to be stuck with not much help.

Share this post


Link to post
Share on other sites

This topic is 4514 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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