这可能看起来不是一个明智的问题,但我想要澄清我的困惑。在Apple的2D游戏框架Sprite工具包中,通常建议在Plist中存储与节点相关的数据,然后在代码中需要时进行检索。我没有得到的是在使用.sks场景编辑器时,你有机会在属性检查器中设置和存储与节点相关的数据。或者我误解了它?通过使用.sks场景编辑器通过属性检查器,两种方法或设置与节点相关的数据有什么不同,它们不会存储在任何地方,只能动态访问。如果有人能说明这两种方法之间的明显区别,我将不胜感激。我试图寻找它但无法得到任何帮助。
答案 0 :(得分:3)
我最近开始在我的游戏的各个方面使用场景编辑器。不仅仅是场景,还有创建复杂的SKSPriteNode对象,模块化弹出窗口等等。它主要是很棒,比尝试在代码中布局对象要快得多。
因此,如果我能够更好地保留sks文件中的所有数据。
是的,您是正确的,您可以在场景编辑器中设置和存储与节点相关的数据。它位于用户数据下的属性检查器中。
您还可以将该信息存储在Plist文件中。但是,这两种方法之间的一个很大区别是,如果将数据存储在Plist文件中,则必须对数据进行排序并查找相关数据并将其绑定到节点。使用用户数据时,数据已经绑定到节点并与之一起使用,因此您不必在以后找到它关联它。
来自Apple。
您可以使用此属性将自己的数据存储在节点中。例如, 您可以存储有关每个节点的游戏特定数据,以便在您的内部使用 游戏逻辑。这可以是创建自己的节点的有用替代方法 用于保存游戏数据的子类。 SpriteKit对它没有任何作用 存储在节点中的数据。但是,数据在节点时存档 存档。
以下是访问sks文件中存储的用户数据的容易程度的示例
if let userData = redVillian.userData {
if let hitPoints = userData.object(forKey: "hitPoints") as? Int {
redVillain.hitPoints = hitPoints
}
if let name = userData.object(forKey: "name") as? String {
redVillian.name = name
}
}
您还可以在代码中设置用户数据
redVillian.userData = ["hitPoints": 5, "name" : "Herbert"]
或在代码
中修改它redVillian.userData?.setValue("Eleanor", forKey: "name")
答案 1 :(得分:1)
我认为你应该在这件事情上做得很简单。 PLists非常适合存储更一般的数据。如游戏设置等。如果您需要存储与节点直接相关的数据,请使用节点的用户数据。
重要的是要理解,在你拥有的游戏中,让我们说,产生敌人,你可以/应该将关于不同敌人类型的信息存储在一个plist中。 当敌人产生时,它们将具有不同的属性,这些属性将使它们成为唯一的,即使它们中的一组属于同一类型。它可以是颜色,健康点,水平等。如果您需要序列化并保存以供以后使用的数据,它应该包含在用户数据中。
根据我刚才所说的,我不知道,在性能方面,如果用户数据在变化很大的数据(例如健康点)方面非常有效。我觉得在这种情况下,使用自定义类并添加属性来存储数据可能会使事情变得更快,但在这种情况下,如果需要序列化数据,则必须实现NSCoding协议。
修改强>
根据您的评论,这里有一些澄清:
如果您只在xCode的场景编辑器中处理场景,那么您可能看不到用户数据和使用plist之间的真正区别。如果您从未通过代码创建精灵,那么它并不明显。
为什么要下载?
如果您通过代码创建角色,那么使用plist存储"模型信息"可能会很有趣。正如您所提到的,Apple关于SpriteKit最佳实践的视频演示正在谈论在plist中存储诸如锚点,位置,比例等信息。例如,如果您正在制作太空船游戏,您可能希望拥有不同的太空飞船模型。它们可能具有非常不同的形状,因此您可能不希望它们围绕同一点旋转以使其看起来很好。它们还具有不同的纹理和不同的统计数据(最大健康点,最大盾牌等)。在plist中,你可以存储这样的东西:
如果您正在使用graphist,那么在不参与xCode的情况下编辑plist很容易。因此,当他的图形准备就绪时,他可以自己填写有关纹理和锚点的信息(例如),并让游戏设计师添加其他统计数据等。
然后,如果您在代码中创建了一艘船,只需从plist中检索信息,即可创建具有所有正确设置的新船。
随着时间的推移,graphist可以更新plist中的图形和相关信息,您甚至不需要重新编译来测试新内容。您甚至可以在获得图形材料之前使用通用图片(或在没有图片的情况下使用纯色)来开发功能。
为什么要使用UserData?
您的宇宙飞船已经创建,您正在为生命而战。在某些时候,有些人会受伤,你需要跟踪它。您可以使用变量轻松完成,但是,您希望使用NSCoder来保存游戏状态,您必须手动完成。 如果存储有关精灵的特定信息,则UserData是关键。它只是特定于THAT节点的东西。当您使用NSCoder保存游戏状态时,它也将与其他所有内容一起保存。 这是一个ponctual数据。在游戏过程中,健康状况会有很大差异,但是当你加载最后一次保存时,你希望你正在战斗的老板受到伤害,就像你保存时一样。所以它很有意思,但很执着。它只与该节点有关。因此将它存储在节点本身中是有意义的。
性能
与您可能担心的任何表现一样。如果你有数百个精灵都受到伤害并且不间断地治愈,那么如果你一直更新userData,它可能会成为瓶颈。如果你达到这一点,你可以考虑从SKSpriteNode继承子类,添加一个变量来跟踪健康状况等,而不是直接处理NSCoder的东西,只需在需要时将变量的内容提交给userData保存它。