【问题标题】:Xcode 5.0.2 - Attempted to add a SKNode which already has a parent: <SKEmitterNode>Xcode 5.0.2 - 尝试添加一个已经有父节点的 SKNode:<SKEmitterNode>
【发布时间】:2014-03-15 11:30:25
【问题描述】:

我正在尝试在 touchesBegan 方法中添加粒子效果,因此当用户触摸绘制的精灵(SKSpriteNode)时,它会绘制粒子效果。但是,我收到错误尝试添加已经有父节点的 SKNode:SKEmitterNode。添加一些上下文...游戏是宝石/糖果迷恋风格,其中根据相邻颜色删除块(deleteNode)。在触摸事件中,我递归地迭代,检查相邻块并将它们添加到数组中以便稍后删除。在删除每个块(deleteNode)之前,我希望粒子事件发生。它们都继承自 SKNode(对吗?),所以我不明白冲突...

@interface
{
   NSString *blockParticlePath;
   SKEmitterNode *blockParticle;
}

在初始化方法中...

blockParticlePath = [[NSBundle mainBundle] pathForResource:@"blockParticle" ofType:@"sks";
blockParticle = [NSKeyedUnarchiver unarchiveObjectWithFile:blockParticlePath];

开始接触...

blockParticle.position = deleteNode.position;
blockParticle.particleColor = deleteNode.color;
[self addChild:blockParticle];

为了确保我没有发疯,我查看了其他论坛并看到了将粒子效果添加到场景中的相同逻辑。提前致谢。如果您需要更多信息,请告诉我。

【问题讨论】:

  • 如果你只是将你的粒子添加到自身(即 SKScene)你应该没问题,检查粒子没有父级。尝试创建一个新项目,创建粒子,然后将其添加到 SKScene,如果可行,您可能会遇到一些您缺少的东西。
  • @fuzzygoat:我确实执行了那个测试。在 SpriteKit 默认项目中,我添加了 6 行代码,减去了 deleteNode 变量。而是使用 CGMakePoint 作为位置,使用 SKColor 作为颜色,它工作正常。我的下一步是在原始项目中分配类似的值。编译器是否会仅仅因为我正在分配与 sprite 节点相关的值而将 emmitter 节点与 sprite 节点混淆?在进一步测试后,我会再次发表评论。谢谢。
  • 好的,所以我尝试将位置设置为新的 CGPoint:blockParticle.position = CGMakePoint(deleteNode.position.x, deleteNode.position.y);无论如何,我可能应该拥有。但是,仍然是同样的错误。然后我从触摸事件中删除了所有粒子逻辑,并从初始化方法中将粒子添加到场景中,它可以工作。它对我的积木来说不是动态的,但它是在场景中绘制的......
  • 糟了!我创建了一个类 BlockNode 来处理块的行为。那是冲突的来源,而不是 SKNode 类。我在我的 BlockNode 类中添加了一个 AddParticle 方法,然后动态放置粒子。现在转到粒子的 zPosition,因为 CGPointMake 只接受 x 和 y 值。 @fuzzygoat 感谢您激发了正确的思路。顺便说一句,如果没有答案,有没有办法“感谢”评论?

标签: objective-c xcode5 sprite-kit sknode skemitternode


【解决方案1】:

@whfissler,您的解释有助于确定此解决方案。

仅当我有许多 SKSpriteNodes 处于活动状态(气球游戏)时才会发生此错误。在每个气球上单击它都会弹出并添加一个 SKEmitterNode(爆炸)。似乎当爆炸产生的粒子相互接触时,我收到了和你一样的错误。我将代码更改为:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    SKEmitterNode *explosion = [SKEmitterNode orb_emitterNamed:@"ballonEksplosion"];
    CGPoint positionInScene = [touch locationInNode:self];
    explosion.position = positionInScene;
    SKSpriteNode *touchedSprite;
    for ( int i = 0; i < [[self nodesAtPoint:positionInScene] count]; i++)
    {
        touchedSprite = (SKSpriteNode *)[[self nodesAtPoint:positionInScene] objectAtIndex:i];
        if ([touchedSprite.name isEqualToString:@"BALLON"])
        {


            [(MBDBallon *)touchedSprite popAndRemoveWithSoundEffect];
            [self addChild:explosion];
        }
    }
}

到:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];
    CGPoint positionInScene = [touch locationInNode:self];
    SKSpriteNode *touchedSprite;
    for ( int i = 0; i < [[self nodesAtPoint:positionInScene] count]; i++)
    {
        touchedSprite = (SKSpriteNode *)[[self nodesAtPoint:positionInScene] objectAtIndex:i];
        if ([touchedSprite.name isEqualToString:@"BALLON"])
        {
            SKEmitterNode *explosion = [SKEmitterNode orb_emitterNamed:@"ballonEksplosion"];
            explosion.position = positionInScene;
            [(MBDBallon *)touchedSprite popAndRemoveWithSoundEffect];
            [self addChild:explosion];
        }
    }
}

它奏效了。对我来说,似乎我的爆炸 SKEmitterNode 在 SKScene 上一直保持很长时间,因此为 currentPosition 添加另一个 SKEmitterNode 会导致以下问题:

self nodesAtPoint:positionInScene

nodesAtPoint 堆栈。

我没有完全理解,也许这有助于你进一步理解。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多