oop - Scala 游戏编程 - 介于 OOP 和 FP 之间

标签 oop scala functional-programming

我正在尝试用 Scala 和Processing 编写一个教程游戏,打算尽可能多地使用 FP。然而,我得出的结论是,不可变状态的游戏对象在此类应用程序中是无利可图的。如果一个对象很大,那么在大量此类对象不断更新的情况下可能会导致相当大的内存消耗(因此,每个周期都会复制自身),例如使用 copy() 函数。解决这个问题的默认方法是什么?我唯一想到的就是将对象切成小块对象,以便只有那些需要更新的对象才会被更新,同时保持“大”对象不变。

最佳答案

游戏引擎本质上是一个(离散)事件模拟。通常,这些是通过可变数据结构实现的,例如用于事件的堆、用于对象空间查询的四叉树/八叉树以及大量哈希表。

对于这些数据结构中的每一个,可变变体都更快。此外,不可变的数据结构会产生必须收集的垃圾,因此 GC 的压力更大,并且您的应用程序最终会变慢。在考虑实时性的情况下,GC 暂停可能是有害的(例如,它可能会影响游戏的帧速率),在处理能力较低的平台(例如 Android)上尤其如此。

至于 copy() 方法 - 它不必复制整个对象来创建更新的版本。如果您的对象以树状方式分层组织(例如,作为案例类的层次结构),则更改对象的一个​​属性只需要重写该树中的一个路径 - 您不需要重写所有内容。尽管如此,它仍然比仅仅拥有可变版本并就地更新成本更高。

示例:

case class World(map: Array[Item], players: Vector[Player])

case class Player(health: Int, speed: Int, weapon: Weapon, shield: Shield)

case class Weapon(strength: Int, ammo: Int)

要为武器添加更多弹药,您不必复制整个世界:

def setAmmo(playerNum: Int, newAmmo: Int, world: World): World = {
  val p = players(playerNum)
  world.copy(players = players.updated(playerNum, p.copy(weapon = p.weapon.copy(ammo = newAmmo))))
}

在此示例中, map 、其他玩家以及修改后的玩家盾牌保持不变在内存中并且不会被急切地复制。

我建议采用可变数据结构来表示状态 - 除非您有一个并发游戏引擎,其中(例如)一个模拟游戏状态的编写器,以及一系列渲染输出、处理声音的读取器,网络等,在这个用例中,不可变数据结构的好处几乎没有。

关于oop - Scala 游戏编程 - 介于 OOP 和 FP 之间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8714515/

相关文章:

oop - 这个 OOP 惯例是真的吗?

swift - 为什么 'self.self'在swift中编译运行?

java - 使用高级编程语言的简化 MIPS CPU

mongodb - salat是否支持scala中Either类型的反/序列化?

Scala 在 if 条件下赋值

functional-programming - 不是由 coq 中的自反性建立的 eta 等价项的相等性

android - 如何使用 Kotlin 函数式 (SAM) 接口(interface)编写可组合函数

scala - 在 scalaz 中组合状态的标准方法

java - 是否存在推断协方差

scala - Scaja.js 浏览器支持