#python #pygame #pygame-clock
#python #pygame #pygame-clock
Вопрос:
В моем основном цикле у меня есть:
clock.tick_busy_loop(60)
pygame.display.set_caption("fps: " str(clock.get_fps()))
Однако на дисплее отображается, что игра читается со скоростью 62,5 кадров в секунду.
Затем я попытался ввести clock.tick_busy_loop(57.5)
, что дало мне значение 58.82 … fps. Когда я устанавливаю clock.tick_busy_loop(59)
, я снова получаю 62,5 кадров в секунду. Похоже, что существует порог между 58.8fps и 62.5fps, который я не могу преодолеть здесь. Как мне заставить мою игру работать со скоростью 60 кадров в секунду? Я в основном ищу такой тип управления, потому что я выполняю события, зависящие от музыкального времени.
Комментарии:
1. используйте время вместо кадров в секунду для управления событиями. Даже если вы получаете 60 кадров в секунду на своем компьютере, я могу получить только 30 кадров в секунду на моем — и ваша программа будет бесполезна для меня.
2. разве Clock не является подклассом pygame.time? Или вы предлагаете не использовать часы и вычислять системное время?
3. используйте pygame.time.get_ticks() и
if pygame.time.get_ticks() >= previous_execution delay: execute_event()
для управления событиями. Он будет работать на быстром компьютере со скоростью 60 кадров в секунду и на медленном компьютере со скоростью 30 кадров в секунду.4. Я бы посоветовал вам использовать системное время с временем импорта и time.time() и задерживать по мере необходимости с помощью time.sleep() . Библиотека pygame построена с использованием SDL, разрешение таймера которого низкое и в основном находится в миллисекундном диапазоне. Причина, по которой вы колеблетесь между 62,5 и 58,82, заключается в том, что вы ожидаете 16 или 17 мс соответственно между кадрами (подсказка: разделите 1000 на каждое из этих мс раз).
Ответ №1:
Итак, я создал простую демонстрационную версию, основанную на моем комментарии выше, которая использует модуль системного времени вместо модуля pygame.time. Вы можете игнорировать материал OpenGL, поскольку я просто хотел отобразить что-то простое на экране. Самая важная часть — это код синхронизации в конце каждого кадра, который я прокомментировал в коде.
import pygame
import sys
import time
from OpenGL.GL import *
from OpenGL.GLU import *
title = "FPS Timer Demo"
target_fps = 60
(width, height) = (300, 200)
flags = pygame.DOUBLEBUF|pygame.OPENGL
screen = pygame.display.set_mode((width, height), flags)
rotation = 0
square_size = 50
prev_time = time.time()
while True:
#Handle the events
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
#Do computations and render stuff on screen
rotation = 1
glClear(GL_COLOR_BUFFER_BIT)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, 0, height, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslate(width/2.0, height/2.0, 0)
glRotate(rotation, 0, 0, 1)
glTranslate(-square_size/2.0, -square_size/2.0, 0)
glBegin(GL_QUADS)
glVertex(0, 0, 0)
glVertex(50, 0, 0)
glVertex(50, 50, 0)
glVertex(0, 50, 0)
glEnd()
pygame.display.flip()
#Timing code at the END!
curr_time = time.time()#so now we have time after processing
diff = curr_time - prev_time#frame took this much time to process and render
delay = max(1.0/target_fps - diff, 0)#if we finished early, wait the remaining time to desired fps, else wait 0 ms!
time.sleep(delay)
fps = 1.0/(delay diff)#fps is based on total time ("processing" diff time "wasted" delay time)
prev_time = curr_time
pygame.display.set_caption("{0}: {1:.2f}".format(title, fps))
Комментарии:
1. Это отлично работает, хотя по причинам, которые ускользают от меня, мне приходится уменьшать частоту кадров вдвое, чтобы она была синхронной с моим звуком. Кажется, работает!
2. @NullSalad Рад, что это работает для вас! Это кажется странной проблемой. Отправьте вопрос об этом с вашим образцом, и я посмотрю на него.