我正在设计一个使用 Java 2D 和牛顿物理学的简单游戏。目前我的主要“游戏循环”看起来像:
do {
for (GameEntity entity : entities) {
entity.update(gameContext);
}
for (Drawable drawable : drawables) {
drawable.draw(graphics2d);
}
} while (gameRunning);
当一个实体被指示更新自身时,它会根据施加在它身上的当前力来调整它的速度和位置。但是,我需要实体表现出其他行为;例如如果“坏人”被玩家射中,则该实体应被摧毁并从游戏世界中移除。
我的问题:以面向对象的方式实现这一目标的最佳方法是什么?到目前为止,我看到的所有示例都将游戏循环合并到一个名为 Game
之类的 God 类中,该类执行以下步骤:检测碰撞,检查 -if-bad-guy-killed,检查-if-player-killed, repaint 等并封装所有游戏状态(剩余生命等)。换句话说,它非常程序化并且所有逻辑都在 Game 类中。谁能推荐一个更好的方法?
以下是我目前想到的选项:
- 将
GameContext
传递给每个实体,如果需要,实体可以从中移除自身或更新游戏状态(例如,如果玩家被杀死,则变为“未运行”)。 - 将每个
GameEntity
注册为中央Game
类的监听器,并采用面向事件的方法;例如碰撞会导致CollisionEvent
被触发到碰撞中的两个参与者。
最佳答案
我曾与两个商业游戏引擎密切合作,它们遵循类似的模式:
对象代表游戏实体的组件或方面(如物理、可渲染等),而不是整个实体。对于每种类型的组件,都有一个巨大的组件列表,每个具有该组件的实体实例都有一个。
“游戏实体”类型本身只是一个唯一 ID。每个庞大的组件列表都有一个映射来查找与实体 ID 对应的组件(如果存在)。
如果一个组件需要更新,它会被服务或系统对象调用。每个服务都直接从游戏循环中更新。或者,您可以从调度程序对象调用服务,该对象根据依赖关系图确定更新顺序。
以下是这种方法的优点:
您可以自由组合功能 无需为每个人编写新类(class) 组合或使用复杂的继承 树。
几乎没有这样的功能 你可以假设所有游戏 您可以放入游戏中的实体 实体基类(灯有什么作用 与赛车或 天空盒?)
ID 到组件的查找可能看起来像 昂贵,但服务正在做 大部分密集的工作由 遍历所有组件 特定类型的。在这些情况下, 存储所有数据效果更好 你需要一个整洁的列表。
关于java - OO方式的游戏设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2231527/