概括
我正在做一个需要低 delta_t 的实时物理模拟。我已将此模拟连接到 python-arcade 游戏窗口以实时显示信息。
我为物理线程制作了一个单独的线程,因为物理线程中有一些昂贵的矩阵乘法。然后,当更新完成时,我设置游戏窗口类的结果状态,游戏窗口在绘制新框架时可以显示这些状态。
因此,我的想法是游戏窗口类只需要担心在屏幕上的绘制,而物理线程负责所有的计算。
但是,游戏窗口和线程之间的通信存在瓶颈,我不知道是否有深入的了解。
我想做的最小表示:
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()
预期结果:高帧率的平滑模拟。街机窗口只需以 30 或 60 fps 运行 on_draw。它只需要画一些东西。
实际结果:物理循环运行速度超快并调用 FPS 下降。
当我在物理线程中添加 time.sleep(0.1) 时,整个事情变得更加顺畅,我猜出于某种原因set_state( _ )
会减慢绘制循环。