你如何阻止粒子效应? (SKEmitterNode)

时间:2014-04-06 18:15:13

标签: sprite-kit particles skemitternode

我目前在碰撞语句中有这个代码,如果与对象发生碰撞,那么这个粒子会发生但是我该如何阻止呢?因为它永远持续下去,而我只希望每次接触发生几次

SKEmitterNode *emitter =  [NSKeyedUnarchiver unarchiveObjectWithFile:[[NSBundle mainBundle]     pathForResource:@"ff" ofType:@"sks"]];
emitter.zPosition = 0;
emitter.particlePositionRange = CGVectorMake(0, self.size.height);
emitter.position = CGPointMake(self.size.width, self.size.height/2);
[self addChild:emitter];

6 个答案:

答案 0 :(得分:18)

使用粒子编辑器时,可以设置要创建的最大粒子数。这是“粒子纹理”下面的字段。官方说明是:

“发射器在发射器的生命周期内创建的最大粒子数。达到此数量后,发射器不再创建粒子。输入0以移除粒子限制。”

另见:Particle Emitter Editor Guide

当然,您应该在创建最大粒子数后从其父节点中删除发射器节点。这可以通过创建一个等待几秒钟的动作序列并从其父[SKAction removeFromParent]中删除发射器节点来完成。

答案 1 :(得分:10)

使用setParticleBirthRate:0停止发射粒子。这是关闭发射器的最现实的方法。

如果您希望它立即消失,请使用removeFromParent。

如果使用setParticleBirthRate,请记住原始值,以便稍后将其重新打开。例如。

@implementation GameScene
{    
    SKEmitterNode *rocketfire;
    float rocketfire_birthrate;
}

// ...
-(void)init {
    // ... 
    rocketfire_birthrate = rocketfire.particleBirthRate;
}

// turn on the emitter (thrust rocket) when the screen is touched
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [rocketfire setParticleBirthRate:rocketfire_birthrate];

}

// turn off the emitter on touches ended    
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    [rocketfire setParticleBirthRate:0];
}

答案 2 :(得分:2)

SWIFT 4:

我认为我有一个更好的方法来关闭它:

1)将出生率设为0:

pEmitter.particleBirthRate = 0

2)在生命周期内运行延迟动作:

let waitAction = SKAction.wait(forDuration: pEmitter.particleLifetime)
pEmitter.run(waitAction, completion: {
    pEmitter.removeFromParent()
})

注意:如果你有一系列的partilcelifetime,可能不会100%准确。

答案 3 :(得分:1)

这类似于Tap提供的答案here,但我没有使用选择器。我不确定在以前的版本中是否需要它,但是在ios 10中我没有看到我的节点数增加而且确实有效。即。添加一个发射器,弹出指定数量的粒子,然后移除发射器。在这种情况下,我修改了它以添加单个粒子。

-(void) gainPoints:(int)x  y:(int)y {


NSString *pPlus1Path = [[NSBundle mainBundle] pathForResource:@"PlusEmitter" ofType:@"sks"];
SKEmitterNode *pEmitter = [NSKeyedUnarchiver unarchiveObjectWithFile:pPlus1Path];


// Place the emitter at the specified position
pEmitter.position = CGPointMake(x,y);
pEmitter.name = @"plus1";
pEmitter.particleLifetime = 1;
pEmitter.particleBirthRate = 1;
pEmitter.numParticlesToEmit = 1;
// Send the particles to the scene.
pEmitter.targetNode = self.scene;

[self addChild:pEmitter];

SKAction *pRemoveNode = [SKAction removeFromParent];
SKAction *pWaitForSecsN = [SKAction waitForDuration:1];
SKAction *pSequence = [SKAction sequence:@[pWaitForSecsN,pRemoveNode]];
[pEmitter runAction:pSequence];

}

答案 4 :(得分:0)

对于那些想要在动画的特定部分冻结粒子发射器的人,可以将发射器暂停:

Fatal Exception: android.content.res.Resources$NotFoundException: Resource ID #0x7f08023b
       at android.content.res.ResourcesImpl.getValue + 254(ResourcesImpl.java:254)
       at android.content.res.Resources.getValue + 1364(Resources.java:1364)
       at androidx.appcompat.widget.ResourceManagerInternal.createDrawableIfNeeded + 176(ResourceManagerInternal.java:176)
       at androidx.appcompat.widget.ResourceManagerInternal.getDrawable + 141(ResourceManagerInternal.java:141)
       at androidx.appcompat.widget.ResourceManagerInternal.getDrawable + 132(ResourceManagerInternal.java:132)
       at androidx.appcompat.content.res.AppCompatResources.getDrawable + 104(AppCompatResources.java:104)
       at androidx.appcompat.view.menu.MenuItemImpl.getIcon + 505(MenuItemImpl.java:505)
       at androidx.appcompat.view.menu.ActionMenuItemView.initialize + 126(ActionMenuItemView.java:126)
       at androidx.appcompat.widget.ActionMenuPresenter.bindItemView + 207(ActionMenuPresenter.java:207)
       at androidx.appcompat.view.menu.BaseMenuPresenter.getItemView + 188(BaseMenuPresenter.java:188)
       at androidx.appcompat.widget.ActionMenuPresenter.getItemView + 193(ActionMenuPresenter.java:193)
       at androidx.appcompat.widget.ActionMenuPresenter.flagActionItems + 473(ActionMenuPresenter.java:473)
       at androidx.appcompat.view.menu.MenuBuilder.flagActionItems + 1182(MenuBuilder.java:1182)
       at androidx.appcompat.view.menu.BaseMenuPresenter.updateMenuView + 96(BaseMenuPresenter.java:96)
       at androidx.appcompat.widget.ActionMenuPresenter.updateMenuView + 226(ActionMenuPresenter.java:226)
       at androidx.appcompat.view.menu.MenuBuilder.dispatchPresenterUpdate + 298(MenuBuilder.java:298)
       at androidx.appcompat.view.menu.MenuBuilder.onItemsChanged + 1069(MenuBuilder.java:1069)
       at androidx.appcompat.view.menu.MenuBuilder.startDispatchingItemsChanged + 1096(MenuBuilder.java:1096)
       at androidx.appcompat.app.ToolbarActionBar.populateOptionsMenu + 461(ToolbarActionBar.java:461)
       at androidx.appcompat.app.ToolbarActionBar$1.run + 56(ToolbarActionBar.java:56)
       at android.os.Handler.handleCallback + 790(Handler.java:790)
       at android.os.Handler.dispatchMessage + 99(Handler.java:99)
       at android.os.Looper.loop + 192(Looper.java:192)
       at android.app.ActivityThread.main + 6769(ActivityThread.java:6769)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run + 438(RuntimeInit.java:438)
       at com.android.internal.os.ZygoteInit.main + 826(ZygoteInit.java:826)

答案 5 :(得分:-1)

暂停时你需要:

emitter.hidden = true

重新启动时需要:

emitter.hidden = false
emitter.resetSimulation()