Public Group

# Need help with my Pong game

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

## Recommended Posts

Hi everyone, I'm working with C++ and SDL to make my pong game. I have a first version of a pong game that works alright. Its just two paddles and a ball that moves back and forth. I tried to make a second version that's more modular. I was working with a SDL graphics, Input, Sprite, and Timer classes to set up a better pong game. I'm running into problems and would like someone with more experience to take a look and give me some advice. I think its kind of long to put the source here, so if you would like to help send me a pm with your e-mail address and I can send it to you. My main concern (for now, there's lots more I need to do) is that the user controlled paddle is not moving very smoothly. Also, I know I haven't put in the computer movement yet, but I wanted to take care of the user controlled paddle first. Thanks!

##### Share on other sites
post the paddle control code.

##### Share on other sites
Ok, I think I'll post the main and the HandleKeyboardInput, because I think the problem is somewhere in the order I put things.

void HandleKeyboardInput();// Global Variablesbool g_quit = false;SDL_Graphics* g_graphics = NULL;SDL_Input* g_input = NULL;Timer* g_timer = NULL;Sprite* g_paddle1 = NULL;Sprite* g_paddle2 = NULL;Sprite* g_ball = NULL;int main( int argc, char* args[] ){    g_graphics = new SDL_Graphics(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,                 WINDOW_TITLE, BACKGROUND_RED, BACKGROUND_GREEN, BACKGROUND_BLUE);        g_input = new SDL_Input();        g_paddle1 = new Sprite(g_graphics,0,0,20,100,255,255,255,"paddle.bmp",10.0,710,375);    g_paddle2 = new Sprite(g_graphics,0,0,20,100,255,255,255,"paddle.bmp",10.0,20,375);    g_ball = new Sprite(g_graphics,0,0,20,20,255,255,255,"ball.bmp",10.0,375,375,1.0,1.0);    g_timer = new Timer();        // While the user hasn't quit    while(g_quit == false)    {        g_timer->start();                g_input->readInput();                if (g_input->windowClosed())        {              g_quit = true;        }                // Get user input and move human paddle        HandleKeyboardInput();                // Check for any collision with paddles and bounce the ball accordingly        if(g_ball->checkCollision(g_paddle1) | g_ball->checkCollision(g_paddle2))        {              g_ball->changeVelocity(-(g_ball->get_Vx()),g_ball->get_Vy());        }                // Check for any collision with vertical walls and bounce the ball accordingly        if(g_ball->get_ypos() <= 0 | g_ball->get_ypos() >= SCREEN_HEIGHT)        {              g_ball->changeVelocity(-1,1);        }                g_ball->update(g_timer->get_ticks());        g_paddle1->update(g_timer->get_ticks());        g_paddle2->update(g_timer->get_ticks());                g_graphics->beginScene();                g_ball->draw();        g_paddle1->draw();        g_paddle2->draw();                g_graphics->endScene();                g_timer->stop();    }        delete g_timer;    delete g_ball;    delete g_paddle1;    delete g_paddle2;    delete g_input;    delete g_graphics;        return 0;    }void HandleKeyboardInput(){   bool* keysHeld = g_input->getInput();   if (keysHeld[SDLK_ESCAPE])   {      g_quit = true;   }   if (keysHeld[SDLK_UP])   {      g_paddle1->moveUp();   }   else if (keysHeld[SDLK_DOWN])   {      g_paddle1->moveDown();   }   else   {      // If neither arrow key is being held, the doom guy isn't moving.      g_paddle1->stopMoving();   }}

##### Share on other sites
One of the problems is that you're using the bitwise OR operator | rather than the conditional OR operator ||.

For example, the line
should look like this:

##### Share on other sites
Hard to tell from what I see here, but is the timer object handling the loop speed? Usually I'll put in Sleep(35) in my game loop to conrol that. If the keyboard input seems choppy, perhaps it has something to do with the timer? Then again, I'm not too familiar with the library you're using, but you might check out what's going on in the beginScene() and draw() functions.

##### Share on other sites
We can help, but not from the above code. I like how you did OOP, but in that way we won't know what the functions do. Know what I mean? Like:
// This may be good, yet since you aren't showing us it might be bad.input->read();

Post this code:

g_input->getInput();

And also, the timer code may be good to post. Just in case:
1) I suggest reading input from SDL_GetKeyState(NULL);. Like this:
// at the beginningUint8 *pKeys;pKeys = SDL_GetKeyState(NULL);// readingif (pKeys[SDLK_ESCAPE])    break; // just and example!// and at the end of your loopSDL_PumpEvents();

2) Make sure your timer isn't too slow. Timers like these:
int start_point; // or delta or somethingwhile (1) // forever{    start_point = static_cast<int>(SDL_GetTicks()); // get the beginning    //...    // while the loop isn't long enough    // I'm not sure about the 1000 / FPS part, but I'm sure you can use a    // thousand.  Remember, SDL_GetTicks() returns in milliseconds    while (static_cast<int>(SDL_GetTicks()) - start_point < 1000 / FPS)        ;}

May cause slowdowns, depending on what you do.

Good luck.

C++

##### Share on other sites
Ok first of all

@nsto119 Thank you for pointing that out. I think you might have saved me 2 hours trying to figure out why that was wrong :)

@vinb The timer class is just like a stop watch. It just tells me the ticks from when I started to when I get_ticks. It has a pause function too. I was going to put a cap frame rate later on, but I was trying to make the game update based on the time that has passed.

Oh that might be it in Sprite::update I did this

void Sprite::update(float deltaTime){   // This needs to be changed so the value is rounded   m_x += (int)(m_Vx * deltaTime);   m_y += (int)(m_Vy * deltaTime);}

Is there a way I can round it into an int value?

@Anonymous Poster
Here's my SDL_Input::getInput and SDL_Input::readInput

void SDL_Input::readInput(){   if (SDL_PollEvent(&m_event))   {      if (m_event.type == SDL_QUIT)      {         m_windowClosed = true;      }      if (m_event.type == SDL_KEYDOWN)      {         m_keysHeld[m_event.key.keysym.sym] = true;      }      if (m_event.type == SDL_KEYUP)      {         m_keysHeld[m_event.key.keysym.sym] = false;      }   }}bool* SDL_Input::getInput(){   return m_keysHeld;}

Thanks for all the replies too!

##### Share on other sites
Quote:
 Original post by eektorOk first of all@nsto119 Thank you for pointing that out. I think you might have saved me 2 hours trying to figure out why that was wrong :)@vinb The timer class is just like a stop watch. It just tells me the ticks from when I started to when I get_ticks. It has a pause function too. I was going to put a cap frame rate later on, but I was trying to make the game update based on the time that has passed.Oh that might be it in Sprite::update I did this*** Source Snippet Removed ***Is there a way I can round it into an int value?@Anonymous PosterHere's my SDL_Input::getInput and SDL_Input::readInput*** Source Snippet Removed ***Thanks for all the replies too!

Gotcha...

Well, I think it might be from the bool. I tried that once and the input messed up. I don't know why, it just does. Try something like this:
// your classclass input{    public:        bool GetKey(int numKey);        // whatever you have};bool input::GetKey(int numKey){    return (SDL_GetKeyState(NULL)[numKey]);}

You can also use a variable, but theres no need for it. Something like this:
private:    Uint8 *m_pKeys;public:    void Update();// later onbool input::GetKey(int numKey){    return (m_pKeys[numKey]);}void input::Update(){    m_pKeys = SDL_GetKeyState(NULL);}

Good luck!

C++

##### Share on other sites
Just to make sure I understand you. If I do what you did the first time, each time I use getInput (or in your case getKey) I would have to use a for loop and run it 323 times to fill up the array?

So in my HandleKeyboardInput function, I would have to do

bool* keysHeld;

for (int i=0;i<323;i++)
{
keysHeld = g_input->getInput(i);
}

##### Share on other sites
Quote:
 Original post by eektorJust to make sure I understand you. If I do what you did the first time, each time I use getInput (or in your case getKey) I would have to use a for loop and run it 323 times to fill up the array?So in my HandleKeyboardInput function, I would have to dobool* keysHeld;for (int i=0;i<323;i++){ keysHeld = g_input->getInput(i);}

Oh, no no no.

It's much, much simpler. All you do is (for example):
input myIn; // or whateverif (myIn.GetKey(SDLK_ESCAPE)) // or whatever    ; // something

Oh, I forgot to add something. At the end of your main loop make sure you add:

//main loop end:
SDL_PumpEvents();

This makes sure everything is up-to-date.

When you declare and 'input' you can just use GetKey(SOME_KEY_THAT_YOU_WOULD_NORMALLY_WANT) and be over with it. No messing with anything.

-Good luck!-

C++

• ### What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• 14
• 11
• 29
• 15
• 41
• ### Forum Statistics

• Total Topics
634838
• Total Posts
3019568
×