以下のコードで効果を作成しました。テストとしてこれを起動するボタンを配線しました。最初に押すと、効果は意図したとおりに機能します。ただし、後続のすべてのリクエストでは、効果は表示されません。ブレークポイントを介して、効果が呼び出され、最初とその後の実行の両方で完了ハンドラーに組み込まれていることがわかりました。また、runAction の一部として「totalTime」変数を確認し、最初の実行とその後の実行の両方で同じ (2 秒) であることを確認しました。興味深いことに、最初の実行では、前の if ステートメントと完了ハンドラーのブレーク ポイントの間に数秒の遅延が見られます。ただし、後続のすべての実行では、先行する if と完了ハンドラーの間に実質的に遅延はありません。繰り返しますが、すべての実行で持続時間が 2 秒であることを確認しました。最後に、コメントアウトすると[self.view setPaused:YES]
完了ハンドラーでは、エフェクトが毎回実行されます。繰り返しますが、以下のコードによって、シーンが以前に一時停止されていないことがわかります。これは時折の効果であり、余分な CPU を使用したくないため、この方法でシーンを一時停止しています。したがって、これらの効果が生成されていない時間の大半はバッテリーを消費します。
- (void) smokeEffectAtPosition:(CGPoint)position withDuration:(NSTimeInterval)duration andView:(SKView *)view andPosVector:(CGVector)vector
{
SKEmitterNode *emitter = [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"SmokeEffect" ofType:@"sks"]];
emitter.position = position;
// Calculate the number of particles we need to generate based on the duration
emitter.particleBirthRate = 100;
emitter.numParticlesToEmit = duration * emitter.particleBirthRate;
emitter.particleLifetime = duration;
emitter.particlePositionRange = vector;
// Determine the total time needed to run this effect.
NSTimeInterval totalTime = duration + emitter.particleLifetime + emitter.particleLifetimeRange/2;
// Run action to remove the emitter from the scene
if ([self.view isPaused])
[self.view setPaused:NO];
[emitter runAction:[SKAction sequence:@[[SKAction waitForDuration:totalTime],
[SKAction removeFromParent]]]
completion:^{
if (![self.view isPaused])
[self.view setPaused:YES];
}];
[self addChild:emitter];
}