Reputation:
I came accidentally to this strange speed behavior which i can't explain for me. If the print clock.tick()
line in the main loop is uncemmented the red square moves more fluently across the screen width. Can any one explain why is this happening?
import pygame
from pygame.locals import *
class Box(pygame.sprite.Sprite):
def __init__(self,color,init_pos):
super(Box, self).__init__()
self.image=pygame.Surface([50,50])
self.image.fill(color)
self.rect=self.image.get_rect()
self.rect.topleft=init_pos
self.speed=300
def update(self,time_passed):
moved_distance=self.speed*time_passed
self.rect.left+=moved_distance
pygame.init()
screen=pygame.display.set_mode([640,480])
box=Box((255,0,0),(0,0))
clock=pygame.time.Clock()
while True:
for e in pygame.event.get():
if e.type==QUIT:
pygame.quit()
screen.fill((0,0,0))
time_passed=clock.tick()/1000.0
box.update(time_passed)
print clock.tick() #this line uncommented moves the red sqaure faster, why?
screen.blit(box.image,box.rect)
pygame.display.flip()
Upvotes: 0
Views: 455
Reputation: 1582
clock.tick
is updating the game clock and should be called once per frame. In your code, you're not just printing the milliseconds passed, you're updating the game clock multiple times when it's only needed once (passing a function into print
, is still going to call that function).
You're also not using the optional framerate
parameter for the clock.tick
function which lets you lock the frame-rate or the speed at which the screen is changing. If this isn't locked, objects can appear to move at variable speeds - more fluently as you put it.
If you want to print the milliseconds passed, just print your time_passed
variable.
For reference, here's the pygame documentation information regarding Clock.tick
used for my answer.
As regards your follow-up question in the comments:
I changed the print line to print "Hi there!" and it still is having the same effect as printing clock.tick(). My aim was not to move or not move the red square, but to understand why putting a print has such an impact on the speed. It also speeds up the loop when one puts a print somewhere in the main loop, as soon as print is commented the movement is idle.
The print
statement will take up a CPUs time like any other piece of code in your main loop. The more time that passes between clock updates the larger the time_passed
will be.
The larger that value is, the faster the box will move. Let's say it takes 10 milliseconds since the last update so timed_passed
= 10 / 1000.0 = 0.01 seconds. We call your Box.update
and the moved_distance
= 300 * 0.01 = 3. Great, it moves 3 units to the right. But, it may move faster or slower because you are not locking frame-rates so the speed will change.
Now, the less time that passes between clock updates, the smaller the time_passed
will be. You comment out the print
statement and the box is idle; Why? Let's say it takes 1 milliseconds since last update because you are not processing a print
statement or any other code. time_passed
= 1 / 1000.0 = 0.001 seconds. We update your red square and the moved_distance
= 300 * 0.001 = 0.3.
How many units to the right should the box move? 0. Why? Because rect.left
is an integer. 0.3 will become 0 i.e the box is idle.
Upvotes: 4