Pygame 速度很重要

Pygame speed matter

我不小心遇到了这种我无法解释的奇怪速度行为。如果主循环中的 print clock.tick() 行未绑定,则红色方块在屏幕宽度上移动得更流畅。谁能解释为什么会这样?

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()  

clock.tick 正在更新游戏时钟,应该每帧调用一次。在您的代码中,您不只是打印经过的毫秒数,而是在只需要一次时多次更新游戏时钟(将函数传递给 print,仍然会调用该函数)。

您也没有使用 clock.tick 函数的可选 framerate 参数,该参数可让您锁定帧速率或屏幕变化的速度。如果未锁定,对象可能会以可变速度移动 - 正如您所说的那样更流畅。

如果您想打印经过的毫秒数,只需打印您的 time_passed 变量即可。

作为参考,这里是关于 Clock.tickpygame documentation 信息,用于我的回答。

关于您在评论中的后续问题:

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.

print 语句将像主循环中的任何其他代码一样占用 CPU 时间。在时钟更新之间经过的 time 越多,time_passed 就会越大。

该值越大,方块移动得越快。假设自上次更新以来需要 10 毫秒,所以 timed_passed = 10 / 1000.0 = 0.01 秒。我们称你的 Box.updatemoved_distance = 300 * 0.01 = 3。很好,它向右移动了 3 个单位。但是,它可能会移动得更快或更慢,因为您没有锁定帧速率,所以速度 改变。

现在,时钟更新之间经过的时间越少,time_passed就会越小。你注释掉 print 语句,盒子就闲置了;为什么?假设自上次更新以来需要 1 毫秒,因为您没有处理 print 语句或任何其他代码。 time_passed = 1 / 1000.0 = 0.001 秒。我们更新你的红色方块和 moved_distance = 300 * 0.001 = 0.3.

盒子应该向右移动多少个单位? 0. 为什么?因为 rect.left 是一个整数。 0.3 将变为 0,即盒子空闲。