When I click and hold on the window of the demo, the simulation "pauses". This accounts for the ball bouncing high into the sky. Since the game has paused for a while, the framerate has gone waaaay down, resulting in a very large time_passed amount. When put into the rest of the system, this very large time_passed makes the new velocity very large, resulting in it shooting high above. A better method of handling physics, is to run a certain number of physics steps depending on how much time has passed, so that variable time doesn't cause issues such as this. So it would be like:
def physics_step(blah): """Physics to be run for 1/30th of a second""" update_velocity() collision_detection() As to the bouncy problem, you see this happen in even established physics engines such as ODE. What you have to do is have some sort of threshold in which to stop the physics and "freeze" the moving objects, when they collide with something at some small amount of speed. The inaccuracies have to do with floating point math, which is never going to be exactly 0, in addition to your allowance of the ball falling through the floor before calculating the velocity. Here's my quick and dirty modification: # The physics # Reverse velocity taking into account bounciness if we hit the ground newvelocity = velocity + (gravity * time_passed) # Use the average velocity over the period of the frame to change position ypos = ypos + (((velocity + newvelocity) / 2) * time_passed * 160) if ypos >= 384: ypos = 384 newvelocity = -newvelocity * bounce if velocity < 1: #Alter this value for the "freeze" to happen at different speeds ypos = 384 newvelocity = 0 # Prevent the ball from sinking into the ground velocity = newvelocity On Nov 28, 2007 12:26 PM, Matt Smith <[EMAIL PROTECTED]> wrote: > Hi, > > I am beginning to learn Pygame and I have written a short program to > simulate a bouncing ball. The motion of the ball is pretty realistic > until it has almost come to rest. The ball continues to vibrate long > after you would have expected it to come to a complete rest (or be > moving less than 1 pile each time as it will never stop moving 100%). > Also, the ball can start to bounce higher again if I click somewhere > else on the desktop. I can't work out why this happens so can anyone > shed some light on it and suggest how I can prevent it.Here's my code: > > #! /usr/bin/python > > import sys, pygame > pygame.init() > > xpos = 92 > ypos = 0 > gravity = 9.8 > velocity = 0 > # How much of the velocity of the ball is retained on a bounce > bounce = 0.8 > > screen = pygame.display.set_mode((200, 400), 0, 32) > # The ball is a 16px sprite > ball = pygame.image.load('ball.png') > clock = pygame.time.Clock() > > # The main loop > while True: > > # Test for exit > for event in pygame.event.get(): > if event.type == pygame.QUIT: > exit() > > # The physics > # Reverse velocity taking into account bounciness if we hit the ground > if ypos == 384 and velocity > 0: > velocity = -velocity * bounce > time_passed = clock.tick(60) / 1000.0 > newvelocity = velocity + (gravity * time_passed) > # Use the average velocity over the period of the frame to change > position > ypos = ypos + (((velocity + newvelocity) / 2) * time_passed * 160) > # Prevent the ball from sinking into the ground > if ypos >= 384: > ypos = 384 > velocity = newvelocity > > # Update the screen > screen.fill((0, 0, 0)) > screen.blit(ball, (xpos, ypos)) > pygame.display.update() > > Thanks for looking. > > Matt > > > > >