如何正确地将计算与渲染分离

时间:2012-10-27 11:56:42

标签: python oop class decoupling astronomy

我正在研究一个天文学项目,制作其中一个重力模拟器程序。我有一个Uni类,它代表一个充满天体的宇宙(Body类的实例)。

Uni类能够自行更新,添加新实体,并通过id删除实体。它完全基于数学,应该单独工作。

围绕它,我计划构建使用PyGame实时显示模拟的程序和MatPlotLib来分析结果。但是,我对如何保持计算(Uni)和渲染(Renderer)解耦感到困惑!

我设想这样:

主程序:

  1. 导入PyGame,对其进行初始化,然后创建screen
  2. 实例化一个Universe,用实体填充它等(实际上是由FileManager完成的,它为一个uni读取JSON规范。)
  3. 创建Renderer
  4. 输入while run:循环:

    1. uni.update(dt)
    2. #Listen to PyGame events, respond
    3. r.render(screen, uni, ui) #The UI class has a list of UI elements.
  5. 但是,渲染器需要保留一个需要绘制的PyGame曲面和图像的持久列表,并且存在问题。 UniBody实例都不必知道PyGame,所以他们不能自己保留它们。

    另一方面,渲染器仅用于render方法,它不能仅仅根据需要创建和销毁PyGame曲面(我猜这将是性能很重)。


    一种可能的解决方案是让渲染器具有PyGame对象的字典,所有这些都由body ID识别。然后,它将迭代它,删除任何遗失的物体,并在每帧添加任何新物体。

    这是正确的方法吗?

1 个答案:

答案 0 :(得分:1)

为什么不将Body自己添加到pygame对象的字典而不是ID?毕竟,Python变量只是一个标签,因此渲染器不需要知道变量代表什么。它可能会让你不得不查找ID。

相关选项是向您的Universe添加一个或多个viewport个对象。因为无论查看机制的实现方式如何,您通常都不希望显示整个Universe,因此视口将是Universe的适当属性。使用该视口将采用几种方法(除了创建和调整大小)。首先是在视口中获取所有Body的方法(可能只返回您在视口对象中保留的列表)。第二个获取包含两个列表的元组的方法;已出现在视口中的Body之一,以及自上次更新后退出视口的Body列表。视口还应该有一个由Universe的update方法调用的更新方法。