Резюме
Я делаю физическое моделирование в реальном времени, для которого требуется низкий delta_t.Я подключил эту симуляцию к окну аркадной игры с питоном для отображения информации в реальном времени.
Я создал отдельный поток для физики, потому что в потоке физики есть несколько дорогостоящих умножений матриц.Затем, когда обновление выполнено, я устанавливаю результирующие состояния класса игрового окна, которое игровое окно может отображать всякий раз, когда оно рисует новый кадр.
Следовательно, мой мыслительный процесс заключается в том, что класс игрового окна должен заботиться только о рисовании на экране, в то время как физический поток заботится обо всех вычислениях.
Однако естьузкое место в общении между окном игры и потоком, и я не знаю, что у меня есть понимание.
Минимальное представление того, что я хочу сделать:
import threading
import time
import math
import arcade
class DisplayWindow(arcade.Window):
def __init__(self):
super().__init__(width=400, height=400)
self.state = 0
self.FPS = 0
def set_state(self, state):
self.state = state
def on_update(self, delta_time: float):
self.FPS = 1. / delta_time
def on_draw(self):
arcade.start_render()
arcade.draw_text(f'FPS: {self.FPS:0.2f}', 20, 20, arcade.color.WHITE)
arcade.draw_rectangle_filled(center_x=self.state * self.width,
center_y=self.height/2,
color=arcade.color.WHITE,
tilt_angle=0,
width=10,
height=10)
# Thread to simulate physics.
def simulation(display):
t_0 = time.time()
while True:
# Expensive calculation that needs high frequency:
t = time.time() - t_0
x = math.sin(t) / 2 + 0.5 # sinusoid for demonstration
# Send it to the display window
display.set_state(state=x)
# time.sleep(0.1) # runs smoother with this
def main():
display_window = DisplayWindow()
physics_thread = threading.Thread(target=simulation, args=(display_window,), daemon=True)
physics_thread.start()
arcade.run()
return 0
if __name__ == '__main__':
main()
Ожидаемый результат: Плавное моделирование с высокой частотой кадров.Аркадное окно должно запускать on_draw только со скоростью 30 или 60 кадров в секунду.Нужно только нарисовать несколько вещей.
Фактический результат: Физический цикл работает очень быстро и вызывает падение FPS.
Когда ядобавьте time.sleep (0.1) к физическому потоку, все становится намного более плавным, я думаю, по какой-то причине set_state( _ )
замедляет цикл рисования.