C#数组-使用它们来存储游戏级别

本文关键字:存储 游戏 数组 | 更新日期: 2023-09-27 18:28:23

我正在制作一款基于2D瓷砖的游戏。我使用一个2D锯齿状数组来存储一个整数,然后渲染器根据这个整数绘制一个特定的图像。我的代码的这一部分正在运行,但我已经到了不确定下一步如何进行的地步。

当玩家继续玩游戏时,我需要能够存储关于2D阵列中每个单元的信息,例如光照水平、用户点击该单元的次数、该单元中图像的旋转值、该图像的阿尔法水平等

我能想到的唯一方法是像以前一样,为我使用的每一条信息创建一个2D阵列。例如:

AlphaLevel[][]
NumberOfTimesClicked[][]

然后,如果我需要(例如)检查用户单击单元格的次数5,5,我可以执行NumberOfTimesClicked[5][5],或者如果我需要设置旋转,我可以进行SetRotation[5][5]=90。

我不确定这有多高效,因为为每条信息都有一个数组似乎并没有那么高效。

这个想法是我有一个好的解决方案,还是有一个我没有想过的更好的方法?

任何建议都会很棒!感谢

C#数组-使用它们来存储游戏级别

制作一个包含信息的Tile对象,如AlphaLevelNumberOfTimesClicked,并制作这些信息的锯齿状数组。然后,您只需要一个锯齿状数组就可以保存所有信息,而且它的组织也更完善,因为您可以很容易地找到Tile的所有属性。

如果你对内存优化感兴趣,NPSF3000说结构会稍微好一点是正确的。在使用值和引用类型之前,请确保您熟悉它们的区别。

以较小的格式存储数据总是比根本不存储数据更大。除了尽可能压缩当前数据外,还要考虑如何将不需要的旧数据存储到磁盘上,或者丢弃以后可以按程序生成的数据。

最后一点:你确定你需要压缩它吗?当我过去在2D瓦片系统上工作时,我发现我实际上存储了一些额外的数据,这样我就可以提高速度,因为我实际上并没有使用那么多内存。运行一些数字以确保您实际使用了足够的内存进行优化。

我不确定这有多有效,有一个数组对于每一条信息,似乎都没有那么高效的记忆。

简短的回答:您可以使用Structs作为替代方案——它只需"将所有内容存储在一起"就可以消除额外的数组。


答案很长:

数组的表示形式如下所示:Header:Data其中报头是4字节的Int32。

目前,您的存储可能如下所示:

IIII:B:B:B  //Byte array (e.g. alpha level)
IIII:SS:SS:SS  //Short array (e.g. num times clicked)
IIII:B:B:B  //Byte array

其中I、B和S分别表示Int、byte和Short的一个字节。使用Struct,您可以将其存储在一起-就像这样:

IIII:BSSB:BSSB:BSSB

如果您使用类,它看起来非常不同,因为类存储在数组中,作为对数据位置的引用:

IIII:RRRR:RRRR:RRRR
BSSB  //These can be stored anywhere in memory
BSSB  //These can be stored anywhere in memory
BSSB  //These can be stored anywhere in memory

因此,虽然结构可以节省一些内存,但它并不多。使用类实际上会消耗内存!然而,它使用的内存不一定是连续的,这有助于存储大量的大数据组(例如,总计1GB+),特别是在32位机器上。。。然而,这是另一天的讨论。

当然,这纯粹是关于内存大小的效率,如果您的工作负载在逐字段的基础上进行计算,那么单个阵列将对缓存更友好,因此效率也更高。相反,如果您倾向于逐块进行计算,则情况正好相反。类对于原始存储来说效率很低,但如果它们符合您的编码模式,则可能会使开发变得更容易。此外,当许多对象需要引用相同的数据时,类是很好的——这甚至可以通过减少重复来节省内存!

希望这会有所帮助,因为你可以看到对基本原理的良好理解会有所帮助。然而,最重要的是要重视你的时间,以及性能是否成为自己的问题测试和基准

免责声明:写于清晨,可能有错误/遗漏等。

四种方法是:

  • 为每个贴图单元拥有的每个属性定义锯齿状数组
  • 将多个单元格属性组合成一个结构类型(为了获得最佳性能和语义,公开公共字段而不是属性),并定义这些属性的锯齿状数组
  • 定义一个包含多个单元格属性的不可变类类型类类型,定义这些属性的锯齿状数组,并使用默认实例初始化所有元素
  • 定义一个包含多个单元格属性的可变类类型,定义这些元素的锯齿状数组,初始化数组的每个元素以引用一个不同的对象实例,然后再也不写入数组(只需更改它包含引用的实例)

如果某些属性组可能会被紧密地访问,而其他属性组则不会,则可以通过使用第二种方法来实现最佳性能,即将经常一起访问的内容分组。如果属性值的某些组合会比其他组合更频繁地出现,那么将这些特定的属性组合成一个不可变的类可能是有意义的。不过,一般来说,对于内部数据类型,我更喜欢使用暴露字段结构类型的锯齿状数组。

对于这个应用程序,结构应该是不可变的咒语是完全错误的。可变结构的语义与类的语义不同;任何不了解这一点的人都可能会感到困惑。然而,这并不意味着应该避免使用结构。相反,这意味着任何想成为一名优秀程序员的人都应该了解结构是如何工作的。所有暴露的字段结构的行为都是相同的,学习所有这些结构的行为不应该比学习如何使用典型的Framework类花费更长的时间。