0

我想知道管理大型 3d 数组的最佳方法是:

x = 1000 y = 1000 z = 100

=> 100000000 个对象

每个单元格都是一个包含一定数量数据的对象。

即使所有数据都折叠了,简单的方法也非常冗长(我首先尝试了一个对象数组数组)

class Test

    def initialize
        @name = "Test"
    end

end

qtt = 1000*1000*100
Array.new(qtt).each { |e| e = Test.new }

我在某处读到数据库对于这种情况可能是一件好事。

你怎么看待这件事 ?

我想做什么?

这个“矩阵”代表一个世界。每个元素都是一个 1mx1mx2m 的块,可能是不同的类型(水、泥、石头……)有些块也可能是空的。

但是用户应该能够在任何地方移除块并改变周围的一切(如果他们后面有水,它会流过孔,例如。

事实上,我想做的不是 Minecraft 成为 DwarfFortress 的一个非常小的克隆(http://www.bay12games.com/dwarves/)

其他有趣的事情

在我的模型中,地面处于 10 级。这意味着在大多数情况下,[0,10] 是空旷的天空。在这些层上只能存在丘陵和部分山脉。

地下基本上是未知的,没有被挖掘。所以我们不必为未使用的块添加实例。

我们应该从一开始就添加到模型中:宝石、黄金、水,它们可以存储而无需存储相邻的石头/情绪/土块。

在游戏开始时,80%的立方体不需要加载到内存中。

每次我们挖掘我们都会创建新的块:我们挖的空块和周围的块。

我们唯一应该索引的是:

  • 地下河
  • 地下湖
  • 熔岩河
4

1 回答 1

1

在内存中保存这么多对象从来都不是一件好事。以平面文件或以数据库为中心的方法会更有效且更易于维护。

我会做什么——面向对象的方法

将块的参数存储为简单数据并动态构造对象。

创建一个Block类来表示游戏中的块,并为其提供变量以保存该特定块的参数:

class Block
  # location of the Block
  attr_accessor :x, :y, :z

  # an individual id for the Block
  attr_accessor :id

  # to define the block type (rock, water etc.)
  attr_accessor :block_type

  # and add any other attributes of a Block...
end

然后,我将创建一些方法,使我能够将数据序列化/反序列化到文件或数据库。

正如您所说,它可以在板上工作,您还需要一个Board类来表示它,以保持游戏状态并对Block对象执行操作。使用x, y, z每个属性,Block您可以确定其在游戏中的位置。使用这些信息,您可以在Block类中编写一个方法来定位与当前块相邻的那些块。这将使您能够执行您所说的“级联”效果,其中一个块受另一个块的操作影响。

高效访问数据

这将完全取决于您选择如何序列化 Block 对象。我可能会选择二进制格式来减少不必要的数据读取并通过其id参数存储对象,然后使用MMIO 之类的东西以类似数组的方式快速对大型数据文件进行随机访问读/写。这将允许您快速有效地访问数据,而不会产生内存开销。您如何读取数据将与您上面的相邻块方法有关。

当然,您也可以选择 DB 存储路径,这将允许您隔离块并以更高级别的方式对特定块进行查找,但这可能会给您带来一些额外的开销。

这听起来像是一个有趣的项目,我希望这会有所帮助!:)

PS关于@Linuxious 上面关于选择不同语言的评论。是的,在某些情况下这可能是正确的,但熟练的程序员从不怪罪他的工具。程序的效率取决于程序员的效率……除非你是用 Java 编写的;)

于 2012-07-09T19:51:12.547 回答