【问题标题】:How to deal with time in python while using pygame使用pygame时如何在python中处理时间
【发布时间】:2019-10-09 08:04:36
【问题描述】:

我正在做一个模拟,它代表一条带有移动产品的生产线。

我对纸上某个 (x,y) 的产品到达时间的计算与我的模拟计算不匹配。

我的 pygame while 循环的迭代时间为 0.01 秒,不确定性非常小。

所以我的像素移动为 0.5,长度为例如 645 像素。 所以我认为每一步都是 0.5 像素,总共需要 1290 步。迭代时间为 0.01 秒,这应该有 12.9 秒的持续时间。

但是,对于 645 像素的长度,我的模拟需要 16 秒。

有人能解释一下区别吗?

我用一个 RECT 做了一段代码,所以迭代时间比较快但是还是有区别的

示例:

import pygame, sys, time, random
init_time = time.time()
from pygame.locals import *



pygame.init()

w_x = 1550
w_y = 800

DISPLAYSURF = pygame.display.set_mode((w_x,w_y))
pygame.display.set_caption('COPAL')

## COLORS USED (SIZE CORRESPONDS TO COLOR)
# background
BLACK = (0,0,0)

# boxes
GREEN = (0,100,0)
PINK = (255,0,255)
BLUE = (0,0,128)

xx = 0
yy = 400

but_on = True
sum_duration = 0
total_iteration = 0

total = []



box = [[xx,yy]]

## Filling background
DISPLAYSURF.fill(BLACK)
start = time.time()

start2 = time.time()


while True:


    init_end = time.time()


    if but_on == True:
        print(init_end-init_time)
        but_on = False    


    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()



    DISPLAYSURF.fill(BLACK)

    pygame.draw.rect(DISPLAYSURF,BLUE,(xx,yy,30,30))


    pygame.draw.line(DISPLAYSURF,PINK,(645,0),(645,800))

    xx += 0.5

    if xx == 645:

        timex = time.time()
        print(timex - start2)

        print(time_iteration_avg)


    stop = time.time()

    duration = stop - init_end

    total.append(duration)

    sum_duration += duration

    time_iteration_avg = sum_duration / len ( total )




   pygame.display.update()

示例编辑

import pygame, sys, time, random
init_time = time.time()
from pygame.locals import *



pygame.init()

# window aize
w_x = 1550
w_y = 800

# time for each step
ite = 0.00387

DISPLAYSURF = pygame.display.set_mode((w_x,w_y))
pygame.display.set_caption('COPAL')


# background
BLACK = (0,0,0)

# boxes
GREEN = (0,100,0)
PINK = (255,0,255)
BLUE = (0,0,128)

# start position
xx = 0
yy = 400

but_on = True
sum_duration = 0
total_iteration = 0

total = []

oo= 0

step = 0.5

duration = ite

box = [[xx,yy]]

## Filling background
DISPLAYSURF.fill(BLACK)
start = time.time()

start2 = time.time()


while True:


    init_end = time.time()


    if but_on == True:
        init_t = (init_end - init_time)

        print(init_t)
        but_on = False    


    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()



    DISPLAYSURF.fill(BLACK)

    pygame.draw.rect(DISPLAYSURF,BLUE,(xx,yy,30,30))


    pygame.draw.line(DISPLAYSURF,PINK,(645,0),(645,800))

    xx += step

    if round(xx) == 645:

        timex = time.time()
        print("elapsed time ")
        print(timex - start2)

        print(time_iteration_avg)




    if duration == ite:

        step = 0.5



    if duration < ite:
        dif_ite = ite - duration
        time.sleep(dif_ite)

        print("Smaller")

        step = 0.5

    if duration > ite:
        dif_pix = duration - ite

        pix_ex = 5 / duration

        step = 645 / pix_ex

        print("Bigger")

    total.append(duration)

    sum_duration += duration

    time_iteration_avg = sum_duration / len ( total )


    print(step)


    stop = time.time()
    duration = stop - init_end


    pygame.display.update()

【问题讨论】:

  • 会不会是某些循环迭代花费的时间稍长,从而导致运行时间出乎意料地长? stackoverflow.com/questions/24039804/… 尝试使用基于增量的循环来设置每帧/循环迭代的时间
  • 你的循环是如何构建的?在您的循环中,您是使用 pygame 的 clock.tick 还是 time.sleep,还是使用其他东西,或者没有任何特定于睡眠的东西,只是您认为您的代码需要 0.01 秒才能完成一次迭代?
  • 我的 while 循环设置为 1 毫秒(使用:time.wait(1)。但是,当我使用 time.clock 函数检查这一点时,我可以看到每次迭代后都经过 0.01 秒而且这个值波动很小。
  • 我不确定“time.wait”到底是什么,但如果这会让你的程序在每次迭代中等待 1 毫秒(1 毫秒 + 代码需要执行的时间) )。
  • 我删除了 time.wait 所以唯一剩下的是 while True:在这种情况下我仍然有 1.3 秒的差异

标签: python-3.x pygame


【解决方案1】:

Jammy Dodger 已经指出了主要问题,但我会尝试进一步解释。
当您编写游戏(或任何物理模拟)时,您不能依赖于您的代码片段将始终花费相同的时间来执行这一事实。有可能:
1- 您尝试挂起您的应用程序(通过睡眠),但操作系统可能无法在您指定的确切时间恢复程序的执行。我会说这是主要原因。
2- 您尝试在屏幕/GPU/RAMbuffer 上绘制一些东西,设备的工作速度可能因您的每个请求而异。
3- 可能还有几十个我现在想不出来的原因。

正确的做法是测量帧之间经过的时间量,并相应地调整您的物理模拟(例如:代码中框的速度)。阅读 xx += ... 部分附近的 cmets。 (有些人可能会因为使用time.sleep而不是pygame的clock.tick而批评代码,但我只是想让它易于理解):

import pygame, sys, time, random
init_time = time.time()
from pygame.locals import *


#  frame per second you want
FPS = 100

#  speed at each frame
SPEED = 0.5

#  use a pygame clock object to control FPS
#clock = pygame.time.Clock()





pygame.init()

w_x = 1550
w_y = 800

DISPLAYSURF = pygame.display.set_mode((w_x,w_y))
pygame.display.set_caption('COPAL')

## COLORS USED (SIZE CORRESPONDS TO COLOR)
# background
BLACK = (0,0,0)

# boxes
GREEN = (0,100,0)
PINK = (255,0,255)
BLUE = (0,0,128)

xx = 0
yy = 400

but_on = True
sum_duration = 0
total_iteration = 0

total = []



box = [[xx,yy]]

## Filling background
DISPLAYSURF.fill(BLACK)
start = time.time()

start2 = time.time()


#  initial value
time_spend_py = 1 / FPS

elapsed_step = 0
while True:
    init_end = time.time()
    loop_start_time = time.time()

    if but_on == True:
        print(init_end-init_time)
        but_on = False    

    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()

    DISPLAYSURF.fill(BLACK)

    pygame.draw.rect(DISPLAYSURF,BLUE,(xx,yy,30,30))


    pygame.draw.line(DISPLAYSURF,PINK,(645,0),(645,800))


    #  amount of change depends on elapsed time since last frame!
    #  Example:
    #  FPS: 100, time_spend=0.012 s
    #  your loop took more time at last iteration
    #  because of that we need to adjust speed
    #  xx += SPEED * (0.012 / (1/100))
    #  xx += SPEED * (0.012 / 0.010)
    #  xx += SPEED * 1.2
    #  so object moves faster
    xx += SPEED * (time_spend_py / (1 / FPS))    

    if xx >= 645:

        timex = time.time()
        print(timex - start2)

        print(time_iteration_avg)
        print("Elapsed step:{}".format(elapsed_step))
        exit(0)


    pygame.display.update()

    stop = time.time()
    duration = stop - init_end
    total.append(duration)
    sum_duration += duration
    time_iteration_avg = sum_duration / len ( total )

    #time_spend = clock.tick(FPS)
    time.sleep(0.01)
    elapsed_step += 1
    loop_end_time = time.time()
    time_spend_py = loop_end_time - loop_start_time

【讨论】:

  • @ninja 如果这个答案对您的问题有帮助,请务必标记此答案,以便其他人知道该问题已解决并给予发布者声誉积分。
  • 你好。我按照你的建议做了。但是,我仍然有0.9秒的延迟,我找不到问题。我计算出以 0.5 为步长的 645 像素是 1290 步。因此,如果盒子必须在 5 秒内移动,则每次迭代必须是 0.00387 秒。
  • @ninja 因为您似乎仍然不了解问题的主要根源(至少这是我从阅读您的代码中得到的)。您期望 time.sleep 命令停止执行您指定的确切数量的程序,但它不会。您的“time.sleep(dif_ite)”不会持续不同的秒数。不要试图让循环的每次迭代都花费相同的时间,您必须接受可能发生差异的事实并相应地调整对象速度。此外,您还没有考虑 pygame.display.update() 所花费的时间。
  • @ninja 请看这个例子:pastebin.com/uCwGWTCr,特别是两个重要部分:1- CONSTANTS 部分,2- 在每次迭代中确定步长值
  • 感谢您的评论,但示例已不存在。
猜你喜欢
  • 1970-01-01
  • 2022-12-22
  • 1970-01-01
  • 2014-07-16
  • 1970-01-01
  • 2012-10-11
  • 1970-01-01
  • 2012-08-18
相关资源
最近更新 更多