A somewhat simple fix to get the ball to stop bouncing would be like this
(put after velocity is set to newvelocity):
if abs(velocity) < 0.01:
  gravity = 0
  velocity = 0

This is just a quick fix though (and alters gravity, which is bad), you
probably want to use Patrick's or James'.

On Nov 28, 2007 1:57 PM, James Paige <[EMAIL PROTECTED]> wrote:

> On Wed, Nov 28, 2007 at 08:26:19PM +0000, Matt Smith 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:
>
> I have two suggestions, see below:
>
> > #! /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:
>
> Here you probably want "if ypos >= 384 ..." rather than checking the
> precise pixel position, since your ball could be falling fast enough to
> skip over pixel 384. I notice you have a check for that later, but why
> not put it here?
>
> >         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)
>
> Your velocity is a floating point number, and floating point math has
> limited precision. Because your ball sprite is being displayed only at
> integer pixel coordinates, you ought not to let your xpos and ypos have
> decmals. I suggest you change the above line to this:
>
>  ypos = ypos + int(((velocity + newvelocity) / 2) * time_passed * 160)
>
> This throws away the decmal on the ypos, but preserves it for your
> velocity. This fix alone, even without the ypos == 384 thing I mentioned
> above, is enough to solve your bouncing problem.
>
> >     # 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
>
> You are welcome :)
>
> ---
> James Paige
>



-- 
This, from Jach.

How many programmers does it take to change a light bulb?
None. It's a hardware problem.

How many Microsoft programmers does it take to change a light bulb?
None. Microsoft just declared darkness as the newest innovation in
cutting-edge technology.

Reply via email to