This is all great info. Thank you.
-----Original Message-----
From: [email protected] [mailto:[email protected]] On
Behalf Of Sam Bull
Sent: Friday, February 17, 2012 3:17 PM
To: [email protected]
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