删除和读取节点后,SpriteKit SKAction不起作用

时间:2013-10-31 17:30:29

标签: ios objective-c sprite-kit

现在已经开始反对这一天,我真的不知道发生了什么。

我有一个非常简单的设置:一个SKNode(我们称之为基础),它包含另一个SKNode(子基础),以及几个SKShapeNode对象。有时,我将一个SKShapeNode对象(使用removeFromParent)从基节点移动到子基节点。然后我应用SKAction,将节点移动到某个任意位置。

除了SKAction在移除SKShapeNode并添加到子基础对象时不起作用。如果我将其从底座中取出并将其放回底座,SKActions将再次起作用。

我完全难过了。是否有一些属性在添加到另一个节点时在节点上设置,当我删除它时没有正确重置...?我无法想象这是应该发生的事情。

任何想法都会非常受欢迎。

更新

这是我可以用它生成的一些代码。此函数位于SKNode的子类中。该类添加了一堆SKShapeNodes,它还有另一个名为testNode的SKNode,所以,不用多说了:

-(void) removeThenAdd
{
    [someNode removeFromParent];

    [self.testNode addChild:someNode];

    SKAction* action = [SKAction moveTo:CGPointMake(200, 200) duration:1];

    SKNode* thatSameNodeJustAdded = [self.testNode.children objectAtIndex:0];

    [thatSameNodeJustAdded runAction:action];
}

另一次更新!

我刚刚发现,如果我在节点位于testNode内部时向节点添加SKAction,然后将其从testNode中删除并将其添加回原始父节点,则会激活该操作。比如,我在这里错过了什么?这必须是某种设计行为,我只是没有正确使用..

2 个答案:

答案 0 :(得分:0)

这似乎是SDK中的一个错误。我有这个问题,因为我想在他们自己的场景文件中制作高级精灵(带有孩子,发射器等的精灵),这样我就可以有选择地加载然后将它们添加到我的场景中。我想出了一个使用NSKeyedArchiver和NSKeyedUnarchiver的工作 - 将节点(或父节点)转换为数据,然后再返回,如果它是一个发射器,新对象就可以添加到场景中了,或者具有作为发射器的子节点,它们将被复制并正确地重新添加。这是我为swift做的扩展,就像一个魅力:

extension SKNode {
    // Pulling a node from one scene and putting it into another causes some problems with broken emitters :(
    // Fix here is to archive and then unarchive the node before returning
    class func nodeFromScene(nodeName : String, sceneFileName : String) -> SKNode? {
        if let scene = SKScene(fileNamed: sceneFileName), node = scene.childNodeWithName(nodeName) {
            let archive = NSKeyedArchiver.archivedDataWithRootObject(node)
            return NSKeyedUnarchiver.unarchiveObjectWithData(archive) as? SKNode
        }
        return nil
    }
}

答案 1 :(得分:0)

我还看到我的SpriteKit项目中出现了此问题。就我而言,我要从在“场景编辑器”中创建的SKScene文件中删除一个节点,然后将其添加到当前场景中。

在进行一些调试之后,它表明这些操作根本没有运行。经过进一步的研究,我发现了为什么……似乎,当您以这种方式向场景添加节点时,isPaused属性被设置为true。无论是故意还是错误,我都无法确定。

从文档中: https://developer.apple.com/documentation/spritekit/sknode/1483113-ispaused

已暂停

如果该值为true,则场景处理动作时将跳过该节点(及其所有后代)。

因此,为了“解决”此问题,请在节点上运行任何SKAction之前,先取消暂停该节点:

node.isPaused = false