Ios 如何防止解码后SKAction序列重新启动?

Ios 如何防止解码后SKAction序列重新启动?,ios,sprite-kit,skaction,uikit-state-preservation,Ios,Sprite Kit,Skaction,Uikit State Preservation,我的应用程序是一款SpriteKit游戏,具有应用程序状态保存和恢复功能。当应用程序状态被保留时,我当前的SKScene中的大多数节点都被编码 当对运行SKAction的节点进行编码和解码时,该操作将从头开始。这似乎是标准的SpriteKit行为 对我来说,这种行为在SKAction-sequence中最为明显。解码时,序列将重新启动,无论其组件操作已完成多少。例如,假设运行序列的代码如下所示: [自运行动作:[SKAction序列:@[[SKAction fadeOutWithDuration

我的应用程序是一款SpriteKit游戏,具有应用程序状态保存和恢复功能。当应用程序状态被保留时,我当前的
SKScene
中的大多数节点都被编码

当对运行
SKAction
的节点进行编码和解码时,该操作将从头开始。这似乎是标准的
SpriteKit
行为

对我来说,这种行为在
SKAction-sequence
中最为明显。解码时,序列将重新启动,无论其组件操作已完成多少。例如,假设运行序列的代码如下所示:

[自运行动作:[SKAction序列:@[[SKAction fadeOutWithDuration:1.0],
[SKAction fadeInWithDuration:1.0],
[SKAction waitForDuration:10.0],
[SKAction removeFromParent]]];
如果应用程序状态在10秒等待期间保留,然后恢复,则
SKAction
序列将从头开始,并出现第二次可见的淡出和淡入


SKAction序列
应该显示与其他动作一致的解码行为,这是有道理的。不过,创建一个异常会很有用,这样就不会再次运行任何已完成的操作。如何防止解码后序列重新启动?

我能想到的实现您希望实现的目标的唯一方法是以下内容

  • 启动操作时,将时间存储在变量中。请记住,您将希望使用update函数中传递的“currentTime”值
  • 当需要编码时,计算从创建操作到编码的时间间隔
  • 从这里开始,您有两个选择:节省剩余时间,以及在重新创建动作时,将其用于计算,或者根据剩余时间创建新动作并对其进行编码

    我不认为SKActions真的打算以这种方式使用,但至少这可能是一种变通方法。我认为开发人员更常见的做法是存储游戏的“状态”以便持久化,而不是试图存储实际的精灵和动作。UIKit的东西也一样。您不会存储用于持久化的UIView,而是会有一些其他对象,其中包含根据用户进度重新创建的信息。希望其中一些至少有点帮助。祝你好运

    编辑

    要提供更多关于“理论上”我会如何做的信息,你是对的,这是一个麻烦

  • SKSpriteNode亚类
  • 创建一个新方法来在该精灵上运行操作(比如-(void)startAction:withKey:duration:),它最终将调用RunAction with key
  • 调用startAction时,您将其存储到某种可变数组中,并使用一个字典存储该操作、其键、持续时间和startTime(默认为0)。您甚至不必实际存储该操作,只需存储键、持续时间和开始时间
  • 在这个SKSpriteNode子类上添加一个update:method。您调用其更新的每个更新循环,并检查1是否有任何操作没有开始时间,2是否这些操作仍在运行。如果没有开始时间,则添加当前时间作为开始时间,如果未运行,则将其从数组中删除
  • 当您去编码/保存该精灵时,您使用该数组中的信息来确定这些精灵动作的状态

  • 在本例中,最重要的一点是每个SKSpritode都保持并跟踪自己的SKAction。很抱歉,我没有时间用Objective-C编写代码。我也绝不声称或试图暗示这比您的答案更好或更差,而是要说明如果我决心按照您的问题要求保存SKActions的状态,我将如何处理此问题。=)

    可以将
    SKAction
    序列分解为多个子序列,这样,一旦某个子序列完成,它将不再运行,因此在解码时不会重新启动

    代码 制作一个轻量级、可编码的对象,该对象可以管理序列,将其分解为子序列并记住(在编码时)已经运行的内容。我已经编写了一个实现。这是我的建议

    下面是一个示例(使用与下面相同的顺序):

    HLSequence*xyzSequence=[[HLSequence alloc]initWithNode:自身操作:@[
    [SKAction waitForDuration:10.0],
    [SKAction performSelector:@selector(doY)onTarget:self],
    [SKAction waitForDuration:1.0],
    [SKAction performSelector:@selector(doZ)onTarget:self]];
    [自运行操作:xyzSequence.action];
    
    概念 第一个想法:将序列分割成几个独立的子序列。当每个子序列完成时,它将不再运行,因此如果应用程序被保留,它将不会被编码。例如,像这样的原始序列:

    [self-runAction:[SKAction-sequence:@[[SKAction-performSelector:@selector(doX)onTarget:self],
    [SKAction waitForDuration:10.0],
    [SKAction performSelector:@selector(doY)onTarget:self],
    [SKAction waitForDuration:1.0],
    [SKAction performSelector:@selector(doZ)onTarget:self]];
    
    可以这样拆分:

    [self-runAction:[SKAction-sequence:@[[SKAction-performSelector:@selector(doX)onTarget:self]];
    [自运行操作:[SKAction序列:@[[SKAction waitForDuration:10.0],
    [SKAction performSelector:@selector(doY)onTarget:self]];
    [自运行操作:[SKAction序列:@[[SKAction等待]