#### Archived

This topic is now archived and is closed to further replies.

# Updated Pong

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

## Recommended Posts

I have been working on Pong game. A couple of you have seen the first version, and I encourage everyone to look at this new version. During my coding spree I have fixed a few collision detection quirks, made a few minor graphical improvements (including changing the square ball into an actual circle), and even added a MENU SYSTEM! I am happiest with the menu system. Right now, it allows you to resume game, start a new game, change the ball and paddle speed and paddle length, and exit the game. Other improvements were made to the code layout where I seperated the Draw and Update functions into smaller, seperate functions (not a big deal right now, but it will be helpful when I release the code). You can grab Pong right here: Pong Thanks for looking. Feedback and criticism are wanted and appreciated.

##### Share on other sites
It''s much better than the old version, but I''ve found a couple of bugs:
The paddle suddenly jumps to the bottom of the screen occasionaly
The ball once seemed to ''stick'' to the cpu''s paddle (looked like it was quickly bouncing back and forth)

Also, some graphics would be great, such as a wood texture on the paddles, a background image etc.

##### Share on other sites
Hmm, I thought I had fixed the paddle jump in this version. I am not really sure what causes it, but I think it may be due to a jump in the time (for instance, the reading from GetTickCount() spikes when the down arrow is pressed). Otherwise, I have no idea what could cause that jump, because I only change the paddle position during VK_UP or VK_DOWN. I did add a little "spike" protection, and I didn't see it happen to me. I'll fool around with it tomorrow and hopefully be able to post an updated version.

As for the sticking ball, I also am not sure what causes it. I'll search for the problem tomorrow, and if I don't make any progress, I'll post my paddle collision code here and hopefully someone will be able to diagnose my problem. I think the ball might be getting stuck between the paddle and the ball, but it really shouldn't because I reverse the direction and place the ball a few pixels away from the paddle.

As for graphical improvements, I'll fool around with some ideas after I iron out the two problems you mentioned. Personally, I think Pong works best as a black and white game, but I guess a little variety couldn't hurt. Perhaps I'll even overhaul my menu system and add a seperate options section (where color could be selected, computer difficulty level, speed, etc). I might even throw in some texture options if I find some suitable ones and they look good enough.

Thanks for the feedback, Sibbo. I'll probably be back in this thread tomorrow asking for help, but I guess having bugs is the only way you learn. By the way, how did you fare against the computer? It still only tracks the y-axis movement of the ball, which is probably the most accurate AI you can implement short of using trigonometry. In future version I hope to make the computer a little less difficult (I was thinking of limiting the computer's "vision"; on a lower difficulty, it would only react when the ball is on its half of the screen; on a higher level, it would react wherever the ball is, like it does now... what do you think of that?).

To everyone else: More feedback is welcome!

EDIT: Whoops, I hit the Post button before I even finished writing the message. Guess I got excited.

[edited by - Erunama on June 27, 2002 11:28:29 PM]

##### Share on other sites
quite possible thats the reason for the spikes. basically you should be using WM_KEYUP and WM_KEYDOWN which will set a varible to let the paddle to know which way to move. it should move along with the other game logic and not be seperated like you seem to have it.

when you recieve a WM_KEYDOWN, you check whether its VK_LEFT or VK_RIGHT. then set a varible paddleDirection to the correct value. maybe 1 for left 2 for right and 0 more no movement. when the player releases the key, you will recieve a WM_KEYUP. you check to make sure its either VK_LEFT or VK_RIGHT. if it is you set playerDirection to 0.

now in yoru movement code (ie where you handle moving the ball and cpu paddle), you do a simple switch statement:

{
case 0: // dont move
break;
case 1: // move left
break;
case 2: // move right
break;
}

dont forget to check and make sure the paddle dont go off the edge of the screen. this should fix any jumping you are having. i only suggest this since no one has complained about the ball jumping, so its very likly the cause.

aslo remove the paddle code you have from WM_CHAR if thats where you are checking stuff now. it will mess things up if you choose to use the approach i suggested.

##### Share on other sites
I''m not sure you understand what I am doing. I am using WM_KEYDOWN and checking for VK_UP and VK_DOWN (not left and right... pong is vertical, not horizontal). I am not using WM_CHAR (in case you were wondering how keyboard input is configured, I am using NeHeGL).

And keyboard input moves along with the rest of the game logic. Basically, my Update function checks for a few certain keys (like ESC, F for framerate toggle, P for pause, F1, +, and -). Then, if the game is currently looping, I go into an UpdateGame function (which handles ball movement, scoring, collision detection, and paddle movement). Yes, it is in a seperate function, but that was necessary. Otherwise, when the menu is up, the ball would still be bouncing around. And it is called with the other game logic. If the game is not looping, an UpdateMenu function is called (handles up and down selection of menu options and checks for hitting Enter).

If you want to see some code, here is the code to handle the UP and DOWN keys:

      // User paddle movement    if (g_keys->keyDown [VK_UP] == TRUE)    {        if(paddleA > (20 + (pLength/2)))        {            if((time/10) < 50)            {                paddleA -= pSpeed*(time/10);            }            if((paddleA - (pLength/2)) < 20)                paddleA = 20 + (pLength/2);        }    }    if (g_keys->keyDown [VK_DOWN] == TRUE)    {        if((paddleA + (pLength/2)) < HEIGHT)        {            if((time/10) < 50)            {                paddleA += pSpeed*(time/10);            }            if((paddleA + (pLength/2)) > HEIGHT)                paddleA = HEIGHT - (pLength/2);        }    }

paddleA is the current y-axis position of the paddle (x-axis stays the same). pLength is the length of the paddle. HEIGHT is a macro to the window HEIGHT (g_window->init.height). pSpeed is a speed constant for the paddles (allows them to be sped up in game). Time is an int passed into the UpdateGame function. It comes from the main loop from GetTickCount, which is subtracted from the previous frames count and passed as DWORD milliseconds into the Update function. I switch it to an int because I wasn''t sure if there were any problems with multipying integers by a DWORD.

I hope that clears up some of the concerns you had, Person.

##### Share on other sites
You could try using GetAsyncKeyState for keyboard input (trouble is on slower computers you''ll lose keypresses). At the very least, it''ll show you whether the spike is caused by WM_KEYDOWN.

The cpu is impossible to beat at low speed setting, but I can beat it when speed is 6 or above. Maybe you could give the cpu paddle a max speed, and if the ball is too high or too low, increase its speed, but not letting it exceed its max speed. Not sure if it''ll work well but it''s an idea.

Another idea to make the game better is add music/sfx which should be easy enough with a library like bass or fmod.

Also, I think the paddle quirk could be caused by the delta time. If you are checking for collision, and inverting the direction, try also moving the ball so that it only touches the paddle, but is not half inside it.

Eg.
{
BallSpeedX = 1;
}

That''ll prevent it switching direction again next frame and bouncing back and forth.

Hope you can understand my jibberish

##### Share on other sites
Thanks for the suggestions. I am looking into GetAsyncKeyState right now. I hope it is simply a drop in function call (and I hope it is not a DirectX function).

I''ll try fooling around with some Computer AI today. The hardest part will probably be adding an options menu. I have actually been thinking about adding CD music play to the game. It seems extremely easy to implement through FMOD and FSOUND_CD_PLAY, but I might hold off because that would add yet another .dll to the package. Is there anyway to get the program to find a DLL in a subfolder?

And I already invert the direction and move the ball outside of the paddle. Since my entire ball-paddle collision code is in a seperate function, I''ll just drop it in here for you to look at:

  void CheckBallPaddle(void){    if(ballX <= 13)    {        if(((ballY + 2) >= (paddleA - (pLength/2))) && ((ballY + 2) <= (paddleA + (pLength/2))))        {            ballX = 13;            dirX = -dirX;            if(((ballY + 2) >= (paddleA - (pLength/2))) && (ballY + 2 < paddleA))                dirY = -1;            else if(ballY == paddleA) { }            else { dirY = 1; }        }    }    if(ballX >= 627)    {        if(((ballY + 2) >= (paddleB - (pLength/2))) && ((ballY + 2) <= (paddleB + (pLength/2))))        {            ballX = 627;            dirX = -dirX;            if(((ballY + 2) >= (paddleB - (pLength/2))) && ((ballY + 2) < paddleB))                dirY = -1;            else if(ballY == paddleB) { }            else { dirY = 1; }        }    }}

A couple things about the code:
- I only check for collisions if the ball is near the edges of the screen (under 13 or above 627 pixels). That way, I can avoid going into more complex IF statements the majority of the time.
- If the ball is near the edges, then I check to see if the ball''s y-axis value is within the paddle''s reach. If it is, then a collision is "detected."
- The ball''s x value is moved 6 pixels outside of the paddle''s center.
- If the ball hits the top half of the paddle, the ball is deflected upward; if it hits the middle, the y direction stays the same; if it hits the bottom, the ball is deflected downward.
- The (ballY + 2) is to give a little more room to make successful contact. Since the ballY value is located at the center of the ball, and the ball has a radius of 5, a person make score even if there appears to be successful contact.

Thanks for the input!

##### Share on other sites
Ok, I threw GetAsyncKeyState in there and the paddle still jumps to the bottom. I am really perplexed by this problem, since 'a person' brought up a good point: it really can't be a jump in time, since the ball does not jump as well.

In case your curious, here is the updated key code:

        // User paddle movement    //if (g_keys->keyDown [VK_UP] == TRUE)    if (GetAsyncKeyState(VK_UP))    {        if(paddleA > (20 + (pLength/2)))        {            if((time/10) < 50)            {                paddleA -= pSpeed*(time/10);            }            if((paddleA - (pLength/2)) < 20)                paddleA = 20 + (pLength/2);        }    }    //if (g_keys->keyDown [VK_DOWN] == TRUE)    if (GetAsyncKeyState(VK_DOWN))    {        if((paddleA + (pLength/2)) < HEIGHT)        {            if((time/10) < 50)            {                paddleA += pSpeed*(time/10);            }            if((paddleA + (pLength/2)) > HEIGHT)                paddleA = HEIGHT - (pLength/2);        }    }

Should I even bother keeping this code now, since it didn't fix the problem? Is using keyDown a more efficient way of working?

EDIT: And, by the way, that if((time/10 < 50) is supposed to protect from time spikes.

[edited by - Erunama on June 28, 2002 10:53:19 AM]

##### Share on other sites
Hmm, I did some more testing, and it seems the paddle jump only occurs when the paddle speed is 6 or above, though I can''t think of any reason why that should happen.

If the GetAsynKeyState doesn''t help, I''d suggest going back to WM_KEYDOWN, due to potentially losing keypresses.

Also, about the dll''s, I''m not sure about searching sub-dirs but it is possible to include it as a resource, write it to disk during run-time, and delete it when your app closes. If you have BASS, it has an example on how to do this (if not, go to www.un4seen.com)

##### Share on other sites
I was on a coding spree today, so if you get a chance, here is an updated version:
Pong

Unfortunately, I wasn''t able to hash out the jumping problem, because I still have no idea what is causing it. Hopefully, some other people will stop by this thread and make some suggestions.

New features:
- CD playback! I am really proud of myself for this one. For my computer, the default drive setting (passing ''0'' into the FSOUND functions) looks to my CD burner, not my main CD/DVD drive. So I made a little while loop to search for a CD drive with a CD inserted. Make sure the CD is an audio CD, because I don''t think FMOD has any protection against ''playing'' data CDs.
- I wanted to have color options in this version, and the structure for it is in there (there are even options), but I was having a little trouble with a switch statement to change the color arrays. I also added code to display a colored box next to ''Background'' and ''Paddle Color'' to show the current color, but it isn''t coming up.

Hopefully I don''t have to add any more menus, because they are a pain in the butt to add. It is fairly easy to add additional options, but a whole new menu requires a bunch of additional if statements and a couple of switches.

Hope you enjoy the new version. All changes were aesthetic, because I still can figure out the physics problems I am having. If we (me and you, Sibbo) can''t figure it out, I''ll probably post something in the ''Game Programming'' forum.

Enjoy!

• 38
• 12
• 10
• 10
• 9
• ### Forum Statistics

• Total Topics
631365
• Total Posts
2999583
×