Jump to content
  • Advertisement
Sign in to follow this  
metal_kid43

SDL reflection

This topic is 4834 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

another guy and myself have been working on an SDL pong clone and are having a problem with when the ball collides with the wall.
if (SDL_PollEvent(&event))
		{
			if (event.type == SDL_QUIT)
			{
				gameRunning = false;
			}
			if (event.type == SDL_KEYDOWN)
			{
				keysHeld[event.key.keysym.sym] = true;
			}
			if (event.type == SDL_KEYUP)
			{
				keysHeld[event.key.keysym.sym] = false;
			}	
		}
		if (keysHeld[SDLK_ESCAPE])
		{
			gameRunning = false;
		}
        if (keysHeld[SDLK_UP])
        {
            paddle1_destination.y -= 2;
        }
        if (keysHeld[SDLK_DOWN])
        {
            paddle1_destination.y += 2;
            if (paddle1_destination.y + paddle1_destination.h > WINDOW_HEIGHT)
            {
                paddle1_destination.y = 480 - paddle1_destination.h;
            }
        }
        if (keysHeld[SDLK_KP2])
        {
            paddle2_destination.y += 2;
            if (paddle2_destination.y + paddle2_destination.h > WINDOW_HEIGHT)
            {
                paddle2_destination.y = 480 - paddle2_destination.h;
            }
        }
        if (keysHeld[SDLK_KP8])
        {
            paddle2_destination.y -= 2;
        }
        SDLKey keyPressed = event.key.keysym.sym;

        if (keyPressed == SDLK_KP5)
        {
        ball_destination.x =ball_destination.x + 1; 
        
        ball_destination.y =ball_destination.y + 1;
        }
        if (ball_destination.y + ball_destination.h >  WINDOW_HEIGHT)
        {
            ball_destination.y =ball_destination.y -5;
            ball_destination.x =ball_destination.x -5;
        }




the collision detection works fine, but when the ball goes outside of WINDOW_HEIGHT it bounces back 5 in the opposite direction and then goes back to ball_destination.x = ball_destination.x + 1; ball_destination.y = ball_destination.y + 1; and hits the wall right away and bounces back 5 and so on... how do we make it so the ball just keeps going back 5 and doesnt go back ball_destination.x =ball_destination.x + 1; ball_destination.y = ball_destination.y + 1; ? also, how do we make the ball bounce back at different angles? thanks for the help! laterz (PS, i think it has something to do with the fact that the program thinks that the numeric key 5 is always pressed, that's why it keeps going back but im not sure) [Edited by - metal_kid43 on August 20, 2005 10:57:28 AM]

Share this post


Link to post
Share on other sites
Advertisement
how about inserting an int containing the angle degree and then use cos/sin to get the next position (then i would think floats would be better for position though)

Share this post


Link to post
Share on other sites
You need to introduce a variable containing the velocity of the ball, and then just invert it when the ball collides with anything. For example:


int ballXVel = 2;
int ballYVel = 2;

...


if (//do your collision checks here)
//if ball hit a paddle {ballXVel = -ballXVel;}



Then, when you're moving the ball, use something like:


ballXPos += ballXVel;
ballYPos += ballYVel;



This type of deflection will simply reverse the X or Y velocity of the ball, but it seems to be what you're looking for.

All you're doing right now is checking if the ball hits anything and, if it does, moving the ball backwards by 5 units. The velocity is still the same, though, so the ball will keep moving in the same direction and hitting off the wall over and over again, moving backwards 5 units every time.

Share this post


Link to post
Share on other sites
here is the deal. on an arcade game on a modern operating system, you have to make it time based instead of frame based. You are going to need to use some OMG PHYSZAKS.

Don't be scared, it isn't all that hard. Basicly, every slice of time alloted to your program is not going to be the same every frame. Your game is going to either run too fast, or run to slow. You need to base your game off of something that can be kept track of, no matter how long your time slice is.

This is where I throw some physics your way.

right now, your position routine is this:
position = position + constant;

If you knew that each time slice delay was exactly say.... 20ms that would be fine, but lets say the time slice is reduced to 10ms, or upped to 50ms. Your game is going to be jerky and unplayable. But, we can fix this. We can make it stronger, better.

The key? a new formula, better than the last:
position = position + (time * velocity)

this way, your velocity is constant, say your ball moves 5 pixels in a second, and the time represents how many seconds. Of course, this doesn't account for acceleration or anything, but this is only pong.

When you hit a wall, or a paddle, all you need to do is flip the velocity around for that direction.
xvel = -xvel

there ya go. that should give you a good start.

Share this post


Link to post
Share on other sites
Hey,
I am the other person helping him. I have been trying to figure out the collision detection all day and well, I have finnaly said I would read tutorials on it(I didn't want to do that, as I wanted to figure it out by my self)and that didn't even work. I mean, I could probaly do it, but I am not the one who wrote the source for it right now, so the source would be changed and I want to talk to the person who posted this, to tell him why I want to do that.


Anyway, I was wondering if you could maybe give me a sample code, so I could look at that and learn from that and figure something out, so we can get this into the game. Once we get this done, we can do everything else by our self. I can do the menu, the points and everything else by my self but I am waiting for him and I don't want to do the points until I get collisioin detection done cause I would never know if the points were working.


Anyway,
Thanks! Hopefully I can see a little sample code.

Chad.

Share this post


Link to post
Share on other sites
well, i took the suggestion about adding a velocity variable and this is what i did:


SDL_Rect ball_source;
ball_source.x = 0;
ball_source.y = 0;
ball_source.w = 25;
ball_source.h = 25;

SDL_Rect ball_position;
ball_position.x = WINDOW_WIDTH/2;
ball_position.y = WINDOW_HEIGHT/2;
ball_position.w = 25;
ball_position.h = 25;

.........
int ballXVel = 1;
int ballYVel = 1;
ball_position.x += ballXVel;
ball_position.y += ballYVel;



if (ball_position.y + ball_position.h > WINDOW_HEIGHT)
{
ballXVel = -ballXVel;
ballYVel = -ballYVel;

}



and now the ball just goes right on through the screen. . . im getting kinda frustrated here, and could really use some advice on what to do next.
thanks

Share this post


Link to post
Share on other sites
Quote:
Original post by metal_kid43
well, i took the suggestion about adding a velocity variable and this is what i did:
(code removed)
and now the ball just goes right on through the screen. . . im getting kinda frustrated here, and could really use some advice on what to do next.
thanks


I have a question- why dont you just combine both of your rects together into one rect? I dont think that you need two:


SDL_Rect ball_location;
ball_location.h = 25;
ball_location.w = 25;
ball_location.x = WINDOW_WIDTH / 2;
ball_location.y = WINDOW_HEIGHT / 2;
int xVelocity = 1;
int yVelocity = 1;

//and then later:

while(1){

ball_location.x += xVelocity;
// again for y

if(ball_location.x + ball_location.w > WINDOW_WIDTH){
xVelocity *= -1;
}
if(ball_location.x < 0){
xVelocity *= -1;
}

// again for y

}




Any questions?

Share this post


Link to post
Share on other sites
ok, i tried that too, and it still dont work. . . ill just post my entire source, sorry im not getting this guys........

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

using namespace std;

const int WINDOW_WIDTH = 720;
const int WINDOW_HEIGHT = 480;
const char* WINDOW_TITLE = "Pong";

int main(int argc, char *argv[])
{
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER );
SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH, WINDOW_HEIGHT, 0,
SDL_HWSURFACE | SDL_DOUBLEBUF );
SDL_WM_SetCaption(WINDOW_TITLE, 0);
SDL_Surface* paddle1 = SDL_LoadBMP("paddle1.bmp");
SDL_Surface* paddle2 = SDL_LoadBMP("paddle2.bmp");
SDL_Surface* ball = SDL_LoadBMP("ball.bmp");
SDL_SetColorKey(ball, SDL_SRCCOLORKEY, SDL_MapRGB(ball->format,
255, 0, 0));

SDL_Rect paddle1_source;
paddle1_source.x = 0;
paddle1_source.y = 0;
paddle1_source.w = 20;
paddle1_source.h = 100;

SDL_Rect paddle1_destination;
paddle1_destination.x = 75;
paddle1_destination.y = 240;
paddle1_destination.w = 20;
paddle1_destination.h = 100;

SDL_Rect paddle2_source;
paddle2_source.x = 0;
paddle2_source.y = 0;
paddle2_source.w = 20;
paddle2_source.h = 100;

SDL_Rect paddle2_destination;
paddle2_destination.x = 645;
paddle2_destination.y = 240;
paddle2_destination.w = 20;
paddle2_destination.h = 100;

SDL_Rect ball_source;
ball_source.x = 0;
ball_source.y = 0;
ball_source.w = 25;
ball_source.h = 25;

SDL_Rect ball_position;
ball_position.x = WINDOW_WIDTH/2;
ball_position.y = WINDOW_HEIGHT/2;
ball_position.w = 25;
ball_position.h = 25;

SDL_Event event;

bool gameRunning = true;
bool keysHeld[323] ={false};
while (gameRunning)
{

if (SDL_PollEvent(&event))
{
if (event.type == SDL_QUIT)
{
gameRunning = false;
}
if (event.type == SDL_KEYDOWN)
{
keysHeld[event.key.keysym.sym] = true;
}
if (event.type == SDL_KEYUP)
{
keysHeld[event.key.keysym.sym] = false;
}
}
if (keysHeld[SDLK_ESCAPE])
{
gameRunning = false;
}
if (keysHeld[SDLK_UP])
{
paddle1_destination.y -= 2;
}
if (keysHeld[SDLK_DOWN])
{
paddle1_destination.y += 2;
if (paddle1_destination.y + paddle1_destination.h > WINDOW_HEIGHT)
{
paddle1_destination.y = 480 - paddle1_destination.h;
}
}
if (keysHeld[SDLK_KP2])
{
paddle2_destination.y += 2;
if (paddle2_destination.y + paddle2_destination.h > WINDOW_HEIGHT)
{
paddle2_destination.y = 480 - paddle2_destination.h;
}
}
if (keysHeld[SDLK_KP8])
{
paddle2_destination.y -= 2;
}

int ballXVel = 1;
int ballYVel = 1;
ball_position.x += ballXVel;
ball_position.y += ballYVel;



if (ball_position.x + ball_position.w > WINDOW_WIDTH)
{
ballXVel *= -1;
}
if (ball_position.x < 0)
{
ballXVel *= -1;
}
if (ball_position.y + ball_position.h > WINDOW_HEIGHT)
{
ballYVel *= -1;
}
if (ball_position.y <0 )
{
ballYVel *= -1;
}



SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_BlitSurface(paddle1, &paddle1_source, screen, &paddle1_destination);
SDL_BlitSurface(paddle2, &paddle2_source, screen, &paddle2_destination);
SDL_BlitSurface(ball, &ball_source, screen, &ball_position);
SDL_Flip(screen);
}
SDL_FreeSurface(paddle1);
SDL_FreeSurface(paddle2);
SDL_Quit();
return 0;
}



i know it's not the best organization, but im worrying about it WORKING right now, and will re-organize later, thanks again

Share this post


Link to post
Share on other sites
The problem is with the following line:

int ballXVel = 1;
int ballYVel = 1;

because it has a limited scope and because you initialize it to one, every single time you set it to -1 it becomes 1 right away.

Just take this out of your main while() loop and put it where you initialize all your other variables.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!