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

RE: [pygame] Substantial Lag



This is all great info. Thank you.

-----Original Message-----
From: owner-pygame-users@xxxxxxxx [mailto:owner-pygame-users@xxxxxxxx] On Behalf Of Sam Bull
Sent: Friday, February 17, 2012 3:17 PM
To: pygame-users@xxxxxxxx
Subject: RE: [pygame] Substantial Lag

On Mon, 2012-02-13 at 02:37 -0600, Ryan Strunk wrote:
> If clock can force my program to run at a desired speed, how do I 
> program it to do so? Do I use clock.tick at a certain framerate, for 
> instance?

[Sent from wrong address, so re-posting]

Clock.tick(fps) effectively sleeps your program to keep it running at a desired framerate. So, if you run clock.tick(10), it would try to maintain 10 fps, by sleeping your program for upto 100ms. If the last call to clock.tick() was 10ms earlier, meaning it's taken your code 10ms to run a frame, then it will sleep your program for 90ms, in order to regulate it at 10 fps.
	So, this is more flexible than simply using time.sleep(100). If your code took 10ms to run, then you run sleep(100) on top of that, it's 110ms per frame, and you're dropping to 9 fps. So clock.tick(fps) is preferred.
	If you don't pass a framerate, then it simply returns the time passed since the last tick, and does not sleep at all, and so will max out the CPU usage.

The reason tapping a key wasn't moving your character: when the game is sleeping for upto 200ms, as in your example, if a player presses the key down and releases before it finishes sleeping, then when the code runs get_pressed(), the key is no longer being held down, and your code doesn't move the character.
	Increasing the framerate will likely improve the responsiveness, but if you want to be certain you catch this, then you should use the pygame events. Here's a change to your code:

from pygame.locals import *

clock = pygame.time.Clock()
o = Output()
guy = Player()
screen = pygame.display.set_mode((640, 400)) move_left = move_right = False
while(True):
    if move_left:
        guy.move(-1)
    if move_right:
        guy.move(1)
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_LEFT:
                move_left = True
                guy.move(-1)
            elif event.key == K_RIGHT:
                move_right = True
                guy.move(1)
        elif event.type == KEYUP:
            if event.key == K_LEFT:
                move_left = False
            elif event.key == K_RIGHT:
                move_right = False
    clock.tick(30)

Something like that would ensure you always catch the key press. If the user taps the key quickly in-between frames, we would get both a KEYDOWN and a KEYUP event. This is why we call guy.move() when we catch the KEYDOWN event, it will move the character even if the move_[left/right] variable is set back to False in the same frame.
	If you set this to something like 2 fps, you can test that it does work. It should always move the character after the user taps the key, though at 2 fps, there would obviously be a delay before you see the character respond.

--
Sam Bull <sambull.org>
PGP: 9626CE2B