Quick Question in SDL

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

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 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 on other sites
OR maybe how do i add a small timer that would move the ball each 0.5 second of pause?

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 on other sites
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.

Share on other sites
Quote:
 Original post by Ekim_Gram1) 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 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 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 on other sites
Would you be able to post more of your code? I feel that it may be something else.

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 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 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 on other sites
You just have to get rid of the DrawIMG function with more parameters.

Also, you call SDL_FreeSurface right before main() ends.

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 Backgroundint Player1Xposition = 260, Player1Yposition = 460; // X,Y Start position for the player1 barint Player2Xposition = 260, Player2Yposition = 20; // X,Y start position for the player2 barint BallXposition = 260, BallYposition = 220; // x,y start position for the ballint iPlayer1Score = 0; // Score of player1int iPlayer2Score = 0; // Score of player2string sLastWinner = ""; // string that contain name of the winner of the last roundstring sPlayer1 = "Player1"; // Name of the player1string sPlayer2 = "Player2"; // Name of the player2Uint32 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 yetvoid 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 falsebool 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 falsebool 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 : Nonevoid 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 falsebool 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 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 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 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 on other sites
EDIT : found my own stupid error ^^