如何在SpriteKit中删除或获取某个节点的位置?

时间:2014-01-16 20:49:40

标签: objective-c macos sprite-kit

我有一个适用于Mac的精灵工具包游戏,我有多个精灵节点在屏幕上移动。我该怎么做才能removeFromParent某个节点? 例如,我有一个循环,每秒定期添加一个新节点:

-(void)spawnNew {
xPos = 100;
yPos = 1000;
CGPoint location = CGPointMake(xPos, yPos);
orb = [SKSpriteNode spriteNodeWithImageNamed:@"orb"];
orb.position = location;
orb.scale = 0.3;
orb.name = @"orbSprite";
CGFloat dirX = 0;
CGFloat dirY = -30;
CGVector vector1 = CGVectorMake(dirX, dirY);
SKAction *action = [SKAction moveBy:vector1 duration:0.1];
[orb runAction:[SKAction repeatAction:action count:100000]];
[self addChild:orb];

}

我如何才能获得这个位置或删除某些球体,而不是整个组?例如,如果精灵的位置等于x=100, y=200,那么我会从父项中删除它。目前,如果我尝试这样做并检查一个球体的位置,它只是检查要添加的最新球体的位置,而不是我想要的所有球体。

谢谢,任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:2)

这可能不是最有效的答案,但它确实显示了如何做到这一点。请记住,通常使用Sprite Kit,您最终会得到很多节点,因此将它们分组到父SKNode下是个好主意,它还可以指定树中的一个点,这样您就可以轻松获得它下面的孩子。 NSLog语句仅用于测试/调试,我离开了,因为如果您尝试代码,它们可能会有所帮助。

- (void)addOrbs {
    SKNode *orbRoot = [SKNode node];
    [orbRoot setName:@"ORB_ROOT"];
    [self addChild:orbRoot];

    for(int counter = 0; counter<5; counter++) {
        SKSpriteNode *newOrb = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(20, 20)];
        [newOrb setPosition:CGPointMake(100, 100 + (100*counter))];
        NSLog(@"ORB POS: %@", NSStringFromCGPoint([newOrb position]));
        [newOrb setName:@"orbSprite"];
        [orbRoot addChild:newOrb];
    }
}

- (void)removeOrbAtPoint:(CGPoint)point {
    SKNode *orbRoot = [self childNodeWithName:@"//ORB_ROOT"];
    NSArray *allOrbs = [orbRoot children];
    NSLog(@"ORBS: %@", allOrbs);
    for(SKNode *eachOrb in allOrbs) {
        if([eachOrb position].x == 100 && [eachOrb position].y == 200) {
            NSLog(@"REMOVING: %@ WITH POSITION: %@", [eachOrb name], NSStringFromCGPoint([eachOrb position]));
            [eachOrb removeFromParent];
        }
    }
}

使用快速块枚举删除的备用版本:

- (void)removeOrbAtPoint_v2:(CGPoint)point {
    SKNode *orbRoot = [self childNodeWithName:@"//ORB_ROOT"];
    NSArray *allOrbs = [orbRoot children];
    NSLog(@"ORBS: %@", allOrbs);
    [orbRoot enumerateChildNodesWithName:@"orbSprite" usingBlock:^(SKNode *node, BOOL *stop) {
        if([node position].x == 100 && [node position].y == 200) {
            NSLog(@"REMOVING: %@ WITH POSITION: %@", [node name], NSStringFromCGPoint([node position]));
            [node removeFromParent];
        }
    }];
}

答案 1 :(得分:1)

另一种方法 - 您可以将removeFromParent添加到操作序列中。这将在到达定义的点时自动删除它,而不需要额外的代码。

会将您的moveBy:操作更改为moveTo:吗?

SKAction *moveToFinish  = [SKAction moveTo:finishPoint duration:5.0];
SKAction *removeMe = [SKAction removeFromParent];
SKAction *actionSeq = [SKAction sequence:@[moveToFinish,removeMe]];
[sprite runAction:actionSeq];

我的finishPoint是由随机声明生成的,以赋予它一些变化。

答案 2 :(得分:0)

循环遍历要添加球体的节点或场景中的所有节点。

for(SKNode * child in self.children) {
 ...
}

看看它们是否在此框内。

for(SKNode * child in self.children) {
   if(CGRectIntersectsRect(child.calculateAccumulatedFrame, CGRectMake(10, 50, 100, 200))) {
      ...        
   }
}

删除子项(CGRectMake将x,y,width,height作为参数)

for(SKNode * child in self.children) {
   if(CGRectIntersectsRect(child.calculateAccumulatedFrame, CGRectMake(10, 50, 100, 200))) {
      [child removeFromParent];       
   }
}