【问题标题】:Objective-c, SpriteKit particles not removed after action finishedObjective-c,动作完成后没有移除SpriteKit粒子
【发布时间】:2014-07-30 13:32:17
【问题描述】:

我在 Xcode 中使用 SpriteKit 制作游戏,但在使用粒子时遇到了问题。

SKEmitterNode的初始化方法:

-(SKEmitterNode *)newExplosionEmitter {
NSString *explosionPath = [[NSBundle mainBundle] pathForResource:@"explosionH" ofType:@"sks"];
SKEmitterNode *explosion = [NSKeyedUnarchiver unarchiveObjectWithFile:explosionPath];
return explosion;

}

我的这个方法是CPU1的AI,在update方法中调用。

-(void)CPU1AI {
SKSpriteNode *CPU1 = (SKSpriteNode *)[self childNodeWithName:CPU1CategoryName];

int aiX = CPU1.position.x;
int aiY = CPU1.position.y;
int ballX = self.ball.position.x;
int ballY = self.ball.position.y;

if ((aiY-ballY)<250 && !CPU1isDead) {
    //CPU1 AI

}
if (CPU1isDead) {
    float posY = CPU1.position.y;
    float centerX = self.frame.size.width/2;
    CGPoint goToPos = CGPointMake(centerX, posY);

    SKAction *moveToPoint = [SKAction moveTo:goToPos duration:3];
    SKAction *removeNode = [SKAction removeFromParent];
    SKAction *CPUdead = [SKAction runBlock:^{CPU1isDead = NO;}];
    SKAction *sequence = [SKAction sequence:@[moveToPoint, removeNode, CPUdead]];
    explosion.position = CPU1.position;
    explosion.zPosition = 10;
    [CPU1 runAction:sequence];
    if (![explosion hasActions]) {
        explosion = [self newExplosionEmitter];
        [self addChild:explosion];
        [explosion runAction:[SKAction sequence:@[[SKAction fadeAlphaTo:0.5 duration:3.5],[SKAction removeFromParent]]]];
    }
}
[explosion removeAllChildren];
}

在 SK runActions 结束后,我放了“[explosion removeAllChildren]”只是为了确保我的粒子将被删除,但不管有没有它,一个仍然留在内存中(我猜)并且仍在缓冲。 是因为我在场景中将它声明为静态 SKEmitterNode 吗?

提前致谢!

【问题讨论】:

  • 你能显示 newExplosionEmitter 吗?因为在这种情况下,您似乎需要从父级中删除爆炸本身。不过不确定。
  • 请将其编辑到您的第一篇文章中:) 因为您没有从可能是问题的父级中删除发射器。而不是 [explosion removeAllChildren] 尝试 [explosion removeFromParent]
  • 在爆炸的 runAction 的序列中,最后一步是将其从父级中移除。这就是为什么我不明白为什么它不删除它。
  • 你是对的。监督了那个。对不起!我一回家就测试一下。但我想早点会有答案:)
  • 场景中还剩下什么?粒子还是发射器?

标签: ios objective-c sprite-kit particle-system skemitternode


【解决方案1】:

将这些方法添加到您的 SKScene 子类(来自 Apple 网站的代码,我稍作修改)...

- (SKEmitterNode*) newExplosionNode: (CFTimeInterval) explosionDuration
{
    SKEmitterNode *emitter =  [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle] pathForResource:@"explosionH" ofType:@"sks"]];

    // Explosions always place their particles into the scene.
    emitter.targetNode = self;

    // Stop spawning particles after enough have been spawned.
    emitter.numParticlesToEmit = explosionDuration * emitter.particleBirthRate;

    // Calculate a time value that allows all the spawned particles to die. After this, the emitter node can be removed.

    CFTimeInterval totalTime = explosionDuration + emitter.particleLifetime+emitter.particleLifetimeRange/2;
    [emitter runAction:[SKAction sequence:@[[SKAction fadeAlphaTo:0.5 duration:totalTime],
                                            [SKAction removeFromParent]]]];
    return emitter;
}

- (void)createExplosionAtPosition:(CGPoint)position
{
    SKEmitterNode *explosion = [self newExplosionNode:3.5];
    explosion.position = position;
    explosion.zPosition = 10;
    [self addChild:explosion];
}

从您的代码中删除以下内容...

explosion.position = CPU1.position;
explosion.zPosition = 10;
[CPU1 runAction:sequence];
if (![explosion hasActions]) {
    explosion = [self newExplosionEmitter];
    [self addChild:explosion];
    [explosion runAction:[SKAction sequence:@[[SKAction fadeAlphaTo:0.5 duration:3.5],[SKAction removeFromParent]]]];
}

用这个替换它

[self createExplosionAtPosition:CPU1.position];

我怀疑您想在 if 语句中设置 CPU1isDead = NO,因此代码不会多次执行。您还应该删除 [explosion removeAllChildren]。

【讨论】:

  • 不,它不是那样工作的 :( 无论如何。我回到了这段代码的第一个版本,它可以工作,唯一的问题是如果fadeAlpaTo:0.5 duration:3 SKAction 被执行在最后一刻,它会再持续 3 秒,但我已经设法克服了这个错误 :)
【解决方案2】:

只是为了帮助其他人寻找相同的答案,我尝试了这个 上面的那个也对我不起作用 - 但让我走上了正确的轨道。

-(void)addTimeBonusParticles
{
    SKAction *remove = [SKAction performSelector:@selector(StopParticlesFlame) onTarget:self];
    SKAction *wait = [SKAction waitForDuration: .5];
    SKAction* blockAction = [SKAction runBlock:^

                             {

                                 NSString *file = [[NSBundle mainBundle] pathForResource:@"TimeBonusMagic" ofType:@"sks"];
                                 stars = [NSKeyedUnarchiver unarchiveObjectWithFile:file];
                                 [self addChild:stars];
                                 stars.zPosition = 5;
                                 stars.position = CGPointMake(countDown.position.x, countDown.position.y);


                             }];

    [self runAction:[SKAction sequence:@[blockAction,wait,remove]]];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-28
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多