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

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

Attachment: signature.asc
Description: This is a digitally signed message part