我正在使用SpriteKit在Xcode中制作游戏,我在处理粒子时遇到了问题。
初始化SKEmitterNode的方法:
-(SKEmitterNode *)newExplosionEmitter {
NSString *explosionPath = [[NSBundle mainBundle] pathForResource:@"explosionH" ofType:@"sks"];
SKEmitterNode *explosion = [NSKeyedUnarchiver unarchiveObjectWithFile:explosionPath];
return explosion;
}
我的这个方法是CPU1的AI,在更新方法中调用。
-(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吗?
提前致谢!
答案 0 :(得分:3)
将这些方法添加到您的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]。
答案 1 :(得分:0)
只是为了帮助别人寻找相同的答案我试过这个 上面的那个也不适合我 - 但让我走上正轨。
-(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]]];
}