python - 如何正确地将计算与渲染解耦

标签 python oop class decoupling astronomy

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

这个Uni类能够更新自身、添加新主体以及通过其id删除主体。它完全基于数学,并且应该单独工作。

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

我的设想是这样的:

主程序:

  1. 导入 PyGame,对其进行初始化,并创建一个屏幕
  2. 实例化一个 Universe,用主体填充它等(实际上由 FileManager 完成,它读取 uni 的 JSON 规范)。
  3. 创建一个渲染器
  4. 进入while run:循环:

    1. uni.update(dt)
    2. #监听PyGame事件,响应
    3. r.render(screen, uni, ui) #UI 类具有 UI 元素列表。

但是,渲染器需要保留需要绘制的 PyGame 表面和图像的持久列表,这就是问题所在。 UniBody 实例都不需要知道 PyGame,因此它们自己无法保留这些实例。

另一方面,渲染器仅用于其 render 方法,该方法不能仅根据需要创建和销毁 PyGame 表面(我猜这会影响性能)。


一种可能的解决方案是让渲染器拥有 PyGame 对象的字典,所有对象均由主体 id 标识。然后,它将对其进行迭代,删除任何消失的主体,并在每帧添加任何新的主体。

这是正确的方法吗?

最佳答案

为什么不将 Body 本身添加到 pygame 对象的字典中而不是 ID 中,而不是主体 ID 呢?毕竟,Python 变量只是一个标签,因此渲染器不需要知道变量代表什么。而且它可能会省去您查找 ID 的麻烦。

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

关于python - 如何正确地将计算与渲染解耦,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13099963/

相关文章:

python - BeautifulSoup:只有在同一 URL 中单击 "Accept"后才能访问 HTML

python - 如何使覆盖范围包括未测试的文件?

python - BeautifulSoup find_all() 是否保留标签顺序?

oop - Java “hello world” 程序中是否涉及对象?

css - A.类 :LINK only works for 1st element in Firefox

python - 从我的 sql 检索数据并使用 python 将其发送到 Web 服务

java - 为什么我的 getter 应该返回对象数组时却返回 [LSubmarine;@27c170f0

c++ - 在接口(interface)设计中应该总是返回一个指向类的指针吗?

c++ - 在 C++ 类中初始化静态数据成员(类)

c++ - C++中变量定义中的'class'关键字