シーケンスは、特定のサブシーケンスが終了すると実行されなくなり、デコード時に再開されないように、いくつかのSKAction
サブシーケンスに分解できます。
コード
シーケンスを管理できる軽量でエンコード可能なオブジェクトを作成し、シーケンスをサブシーケンスに分割し、(エンコード時に) 既に実行されたものを記憶します。GitHub のライブラリに実装を記述しました。gist内のコードの現在の状態を次に示します。
そして、ここに例があります(以下と同じシーケンスを使用):
HLSequence *xyzSequence = [[HLSequence alloc] initWithNode:self actions:@[
[SKAction waitForDuration:10.0],
[SKAction performSelector:@selector(doY) onTarget:self],
[SKAction waitForDuration:1.0],
[SKAction performSelector:@selector(doZ) onTarget:self] ]];
[self runAction: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] ]]];
[self runAction:[SKAction sequence:@[ [SKAction waitForDuration:10.0],
[SKAction performSelector:@selector(doY) onTarget:self] ]]];
[self runAction:[SKAction sequence:@[ [SKAction waitForDuration:11.0],
[SKAction performSelector:@selector(doZ) onTarget:self] ]]];
ノードがいつエンコードされても、メソッドdoX
、doY
、およびdoZ
は 1 回だけ実行されます。
ただし、アニメーションによっては、待機時間が奇妙に見える場合があります。たとえば、アプリケーションが の後に保存され、の前の 1 秒の遅延中に実行されたdoX
とします。その後、復元時にアプリケーションは実行されませんが、実行されるまで 11 秒待機します。doY
doZ
doX
doY
doZ
おそらく奇妙な遅延を回避するには、シーケンスを依存サブシーケンスのチェーンに分割し、それぞれが次のサブシーケンスをトリガーします。たとえば、分割は次のようになります。
- (void)doX
{
// do X...
[self runAction:[SKAction sequence:@[ [SKAction waitForDuration:10.0],
[SKAction performSelector:@selector(doY) onTarget:self] ]]];
}
- (void)doY
{
// do Y...
[self runAction:[SKAction sequence:@[ [SKAction waitForDuration:1.0],
[SKAction performSelector:@selector(doZ) onTarget:self] ]]];
}
- (void)doZ
{
// do Z...
}
- (void)runAnimationSequence
{
[self runAction:[SKAction performSelector:@selector(doX) onTarget:self]];
}
この実装では、シーケンスが後で保存され、doX
実行された場合doY
、復元時に、前の遅延doZ
はわずか 1 秒になります。確かに、それは 1 秒 (エンコード前に半分経過していたとしても) ですが、結果はかなり理解できます。エンコード時にシーケンス内で進行中だったアクションはすべて再開されますが、完了すると完了します。
もちろん、このようなメソッドをたくさん作るのは厄介です。代わりに、シーケンス マネージャー オブジェクトを作成します。このオブジェクトは、トリガーされると、シーケンスをサブシーケンスに分割し、ステートフルな方法で実行します。