[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] Why does my ball vibrate?



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 <matt@xxxxxxxxxxxxxxxxxxxxxxxxxxxx> 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
>
>
>
>
>