删除子 SKSpriteNode

Posted

技术标签:

【中文标题】删除子 SKSpriteNode【英文标题】:Delete child SKSpriteNode 【发布时间】:2015-06-15 20:27:53 【问题描述】:

基本上,我正在努力做到这一点,以便当用户击中油箱时,旧油箱会消失,而新油箱会在随机位置产生。现在它正在检测碰撞,但我无法摆脱孩子。它只会增加一个新的油箱,而不会去掉旧的。

我可以做些什么来移除旧的孩子并生成一个新的孩子? removefromparent 和 removeallchildren 不起作用(nslog 显示“移动”,在检测到碰撞后我肯定会得到该语句)

- (void) fuelGenerate 
    //make a fuel tank

    for (int j=1; j<2; j++) 
        SKSpriteNode *fuel = [SKSpriteNode spriteNodeWithImageNamed:@"fuel.png"];

        fuel.position = CGPointMake(arc4random_uniform(self.frame.size.width), arc4random_uniform(self.frame.size.height));
        [fuel setScale:0.6];
        fuel.zPosition = 1;
        fuel.shadowCastBitMask = 1;

        fuel.name = @"fuelNode";
        fuel.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:fuel.frame.size];

        fuel.physicsBody.dynamic = FALSE;

        fuel.physicsBody.affectedByGravity = false;
        fuel.physicsBody.usesPreciseCollisionDetection = YES;
        fuel.physicsBody.categoryBitMask = fuelCategory;

        fuel.physicsBody.collisionBitMask = fuelCategory | fireCategory;
        fuel.physicsBody.contactTestBitMask = fireCategory;


        if (FuelGen == 1) 

            [self addChild:fuel];

         else if (FuelGen == 0) 

            NSLog(@"Move");

            [fuel removeFromParent];
            [self addChild:fuel];
            FuelGen == 1
        

    

【问题讨论】:

您的代码存在一些逻辑问题,但在深入讨论之前,FuelGen 是什么? 只是一个系统来确定是否应该生成燃料箱等。它工作正常。我只是在删除旧孩子时遇到问题。 【参考方案1】:

以下是一些观察:

你的代码在一个只运行一次的循环中。你为什么要这么做?

如果您正在创建一个对象,在您的情况下是一个 SKSpriteNode,并且想要稍后删除它,您将需要保留对它的某种引用。有几种方法可以实现,包括创建属性或将对象添加到数组中。

您当前位置的 IF 语句没有任何意义。您的代码正在创建 SKSpriteNode,但您的 IF 语句仅在 FuelGen == 1 时广告该节点。如果不是,它会尝试删除该节点,该节点本身应该会引发错误,因为您尚未添加它。

最后,当您使用 IF - ELSE IF 语句时,您应该在末尾添加一个 ELSE 来捕获任何其他未触发任何先前 IF 语句的内容。


要创建 SKSpriteNode 属性,请在您的 import(s) 和 @implementation 之间添加此代码。

@property (nonatomic, strong) SKSpriteNode *mySprite;

现在你有了一个属性。

要使用 NSMutableArray,您可以将数组设为属性,然后执行以下操作:

SKSpriteNode *myNode = [SKSpriteNode spriteWith....
myNode.name = @"SomeUniqueName";
[self addChild:myNode];
[myArray addObject:myNode];

现在您已经创建了一个 sprite 并将其添加到您的数组中并具有对它的引用。

【讨论】:

所有这些变量都已在其他方法中得到处理。 我该怎么做“有几种方法,包括创建属性或将对象添加到数组中。” 非常感谢 :) @sangony【参考方案2】:

您似乎没有提到“旧”油箱。你所有的日常工作就是创建一个新的燃料精灵并将其添加到小时候的“自我”中。

您需要获取对燃料精灵的引用并删除那个。在您的代码中,[fuel removeFromParent] 指的是您刚刚在上面的代码中创建的新燃料精灵,而不是您要移除的旧燃料箱。

您执行此操作的方式取决于您的实际实施;例如,如果您只有一个油箱,则可以保留对它的引用。如果您有很多,那么将需要一个更复杂的系统,例如将它们存储在一个数组中,或者设置您的消息传递以将燃料节点传递给您的代码。但无论哪种方式,除非您在代码中引用旧的燃料节点,否则您将永远无法删除它。

【讨论】:

如何只保留一个油箱的引用?我宁愿只移动我拥有的那个? 最简单的做法是只拥有一个指向您的一个油箱的实例变量。在设置场景时创建一次,然后保留对它的引用。然后,当您收到表明它已被击中的事件时,只需将坦克的位置设置为您希望它在新位置的位置。在下一个更新周期,它将被绘制在新的位置。 (如果您不了解如何执行上述操作,您可以考虑在玩游戏之前先进行一些在线学习 - 掌握更多技巧会带来很大的好处。) 不过,您最终可能需要更复杂的解决方案。例如,您可能希望旧油箱爆炸或在新油箱“介绍”进入场景时有一些其他“开场”动画。或者你可能想要一个拥有多个坦克的关卡。一个更好的解决方案是以这样一种方式编写你的代码,它不会假设只有一个油箱,但如果这是你的第一个项目,你可以接受只有一个油箱可以“传送”单帧,您只需保留对单缸的参考就可以了。 我只是把它作为一个练习来玩弄精灵节点(同时玩得开心哈哈)。 “有一个指向您的一个油箱的实例变量。在设置场景时创建一次并保留对它的引用”我该怎么做?谢谢你的帮助:) 请参阅下面@sangony 的回复了解如何操作。

以上是关于删除子 SKSpriteNode的主要内容,如果未能解决你的问题,请参考以下文章

SKSpriteNode 从屏幕上消失后如何删除或销毁它

Xcode 如何自动从其父节点中删除 skspritenode

如何在Swift中正确地从父节点中删除SKSpriteNode的子类(要从数组中移除,屏幕上的空格......)?

从数组 spritekit swift 中删除节点

iOS SKSpriteNode - 离开屏幕

SpriteKit iOS 7 Sknode 没有被删除