如何在精灵工具包游戏中仅在场景中显示一次标签
Posted
技术标签:
【中文标题】如何在精灵工具包游戏中仅在场景中显示一次标签【英文标题】:How do I show labels in a scene only once in a sprite kit game 【发布时间】:2019-01-14 14:07:03 【问题描述】:我确信它一定很容易实现,但尽管以不同的方式实现它,但我未能在我的游戏中实现它。我的游戏由不同的场景组成,场景 1 是我希望我的用户只访问两次的场景,一次是他第一次打开游戏并点击播放进入下一个场景(场景 2),这基本上是一张地图并显示要做的不同活动的数量。只有当用户完成了场景 2 上地图显示的所有活动时,才会第二次访问场景 1。点击场景 2 时的每个活动都会导致不同的场景,即场景 3、4、5、6,但会将用户带回场景 2,当他完成一项特定活动或未能完成时。
现在我面临的问题是我的场景 2,它显示了一张地图,在用户第一次访问该场景时,它还向用户展示了一些欢迎标签来描述只需要显示一次的游戏。当用户在不同场景上完成/失败活动后返回场景 2(地图场景)时,不应再次向他呈现标签,因为它们只是为了让他第一次意识到游戏。我曾尝试使用布尔变量来解决这个问题,但我失败了,因为我认为用于跟踪“如果访客已经访问过场景”的布尔变量不应该保存在节点 userdata 属性中,因为每次用户回到场景 2. 存储在 userdata 中针对特定标签的布尔变量只是重置为默认值,并不表示用户以前去过场景。
这很棘手,但我相信解决方案会很简单,但由于某种原因我无法理解。
【问题讨论】:
让我们确保我理解正确。您在场景 1 上打开应用程序,进入场景 2,显示标签,启动场景 3,失败,重定向到显示标签的场景 2?你希望当他被重定向到场景 2 时不显示标签? 正确。即使用户成功完成场景 3/4/5 上的活动,我想添加一件事,他仍将被引导回场景 2,在那里他不应再次看到标签。我能想到的一种方法是不在场景 2 的 viewDidLoad 方法中创建标签,而是在不同的文件中创建标签,或者可能使用 NSUserDefaults 来存储布尔标志的值,但这似乎过于复杂。必须有某种方法可以使用与标签绑定的 userdata 属性。 【参考方案1】:理想的方法是将场景与数据模型分开。
第二种方法是使用全局设置来替换存储在场景节点中的状态。
每次场景重新出现时,默认情况下所有节点都在重新加载。所以节点中存储的信息只与场景有关,与游戏数据模型有关。
您正在走向令人兴奋的游戏编程设计。玩得开心。
【讨论】:
问题是 Apple 展示了使用 Sprite Kit 框架开发游戏的方式,您应该偏离他们通常的模型-视图-控制器方法。但是他们已经解释了通过使用 plists 和 userdata 属性将数据与逻辑分开。我同意当重新加载场景时,所有节点都会重新加载,这就是我存储在 userdata 中的布尔变量自然重置的方式。但我相信有一种方法可以阻止存储在 userdata 属性中的数据被重置,那么拥有 userdata 属性有什么好处。 用户数据用于场景相关对象,如动画或节点渲染。如果可能的话,游戏逻辑应该独立于场景甚至精灵套件。尤其是大型游戏。您可以选择不同的设计,仅供参考。【参考方案2】:您可以通过为场景命名并在viewDidLoad
上检查来解决此问题。
用户在场景 3 中获胜/失败后,您创建场景 2。为该场景命名,例如 scene.name = "scene_failed"
,然后将其呈现给用户。
let transition = SKTransition.flipVertical(withDuration: 1.0)
let next_scene = Scene_Two()
next_scene?.name = "scene_failed"
self.view?.presentScene(next_scene!, transition: transition)
这样,当场景2中的viewDidLoad
函数被调用时,就会触发if。
if scene?.name == "scene_failed"
// redirected from scene 2
hide_labels()
else
// the scene has no name. so for sure it came from scene 1
show_labels()
通过为您提供场景名称,您始终可以知道您从哪个场景过渡。
【讨论】:
以上是关于如何在精灵工具包游戏中仅在场景中显示一次标签的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift iOS 中仅在最后一个屏幕上获取导航栏?
将游戏中心添加到游戏后第一次接触时 Spritekit 游戏场景停止