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

Re: [pygame] Last Frame of Animation/Game Loop Problem



​Hi,


On Tue, Jan 16, 2018 at 10:37 AM, dejohnso <dejohnso@xxxxxxxxxxx> wrote:
I have having trouble with a basic game/animation loop.

It seems like the final frame doesn't show up until after the game loop is done and pygame.quit() is called. An example is below - if it is run, I see the "Out of loop" output, then a pause, then the final frame, then the final pause.

​Great self-contained example!

On Win 7 x86-64, Python 3.5.1, PyGame 1.9.2a0, I see 5 frames of animation, with the last frame being presented an instant before "Out of loop" is printed. This is the behavior I would expect, but it sounds like your last frame comes 1s after printing?
 
Am I doing something wrong?

​Everything here looks good to me. I would prefer the drawing code (including display update) all in one place (idiomatically, at the end of the frame). I also prefer `pygame.display.flip()`. Also, in this case, `time.sleep(...)` instead of `.tick(...)` (due to the low framerate, see below). But these are all suggestions; nothing as-is looks wrong.​
 
Is this specific to my setup/machine?

​Since I can't reproduce it myself, this seems likely. What is your setup/machine?

I have a few vague suspicions. If the input polling rate is very low, some windowing systems will conclude the process is hung, and possibly draw some kind of grayed-out overlay on the window, which can make it drop a frame or two. Also, `.tick(...)` does some internal timekeeping history measurements, meaning that the framerate provided is rather inaccurate, especially on startup. That's why I'd prefer `time.sleep(...)` (OTOH, slowing the framerate should work just fine, so . . .).
 
import pygame, sys

def main():
    pygame.init()
    screen = pygame.display.set_mode((600, 400))

    frame_count = 0

    # The clock helps us manage the frames per second of the animation
    clock = pygame.time.Clock()

    square = pygame.Rect((0,100),(50,50))
    done = False
    while not done:
        # Erase the screen
        screen.fill((50, 50, 50))
        # Process events
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                done = True
        # The main snake code
        square.move_ip((50,0))
        pygame.draw.rect(screen, (200,50,50), square)
        print(square)
        frame_count += 1
        if frame_count >= 5:
            done = True
        print(done)
        # set fps
        clock.tick(1)
        # Bring drawn changes to the front
        pygame.display.update()

    print("Out of loop")
    pygame.time.delay(2000)
# This also works to bring up the last frame.
#    pygame.event.clear()
#    pygame.event.wait()
    pygame.quit()
    print("After quit")
    pygame.time.delay(2000)
    sys.exit()

main()


​(Waves from SoC)

Ian​