【问题标题】:Removing Node From Parent (Sprite Kit) Objective C从父级(Sprite Kit)目标 C 中移除节点
【发布时间】:2016-04-07 21:45:00
【问题描述】:

我正在创建一个节点从右向左移动的横向滚动游戏。问题是当它离开屏幕时它不会自行移除。我可以让它工作的唯一方法是不多次调用我的 bat 节点方法。但我需要多个蝙蝠出现在屏幕上。问题似乎是当我使用 SKAction waitforDuration 或 performSelector afterDelay 多次调用我的 bat 方法时。

蝙蝠法

-(void) addBats

{ int random = arc4random_uniform(self.size.height/2);

bats = [SKSpriteNode spriteNodeWithImageNamed:@"Bat1.png"];
bats.physicsBody = [SKPhysicsBody bodyWithTexture:bats.texture size:bats.frame.size];
bats.position = CGPointMake(self.size.width * 9, random);
bats.zPosition = 4;
[bats setScale:0.3];
bats.physicsBody.categoryBitMask = enemyCategoryL4;
bats.physicsBody.dynamic = NO;
bats.physicsBody.contactTestBitMask = playerCategoryLevel4;
bats.physicsBody.usesPreciseCollisionDetection = YES;

[L4foregroundNode addChild:bats];

SKAction *up = [SKAction moveByX:-1 y: -40 duration:1];
SKAction *down = [SKAction moveByX:-1 y:40 duration:1];
SKAction *action1 = [SKAction repeatActionForever:[SKAction sequence:@[up, down]]];

SKAction *action2 = [SKAction moveByX:-self.size.width * 10  y:0 duration:40.0];
SKAction *group = [SKAction group:@[action1, action2]];

[bats runAction:group];

}

-(void) update:(NSTimeInterval) currentTime {

if(bats.position.x < -50)
{
    [bats removeFromParent]; 
    [self addBats];
}

}

上述方法仅在我每次调用蝙蝠一次时才有效。有没有一种方法可以让我多次调用并在每次离开屏幕时移除球棒?

【问题讨论】:

  • bats 是否定义为场景的 iVar(SKSpriteNode 类型)(只是检查以获得完整图片)?
  • 是的,它是 SKSpriteNode 的 iVar。你认为这可能是问题吗?
  • 好的,所以你这里的代码很乱:) 你想要的是创建动作序列,或者按照建议使用完成处理程序。当动作完成时,也就是蝙蝠离开屏幕时,您将它们从其父级中移除......
  • 另外,如果老节点不在屏幕上(你看不到它),你怎么知道它实际上没有从场景中移除?
  • 哦,我明白了...如果您使用[SKAction waitForDuration]; 在一定延迟后调用addBats,那么您将失去用户5556671 指出的引用。 (这仍然意味着节点实际上并没有像你说的那样离开屏幕;)因为你可以看到它们)。

标签: objective-c sprite-kit


【解决方案1】:

这是一个关于如何创建精灵的示例,将其移动直到最终离开屏幕,然后立即将其移除:

#import "GameScene.h"


@interface GameScene()

@property (nonatomic, strong)SKSpriteNode *sprite;

@end

@implementation GameScene

-(void)didMoveToView:(SKView *)view{

    self.sprite = [SKSpriteNode spriteNodeWithColor:[SKColor purpleColor] size:CGSizeMake(50.0f,50.0f)];

    //Place a sprite on right edge of the screen (I assume that your view and a scene have same size)
    self.sprite.position = CGPointMake(self.frame.size.width, self.frame.size.height / 2.0f);

    SKAction *moveSprite = [SKAction moveTo:CGPointMake(-self.sprite.size.width, self.frame.size.height / 2.0f) duration:5.0f];

    SKAction *removeSprite = [SKAction removeFromParent];

    SKAction *sequence = [SKAction sequence:@[moveSprite, removeSprite]];

    [self addChild:self.sprite];

    [self.sprite runAction:sequence withKey:@"moving"];
}


-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

    if (self.sprite.parent) {
        NSLog(@"Sprite has a parent");
    }else{
        NSLog(@"Sprite doesn't have a parent");
    }
}

@end

尝试使用或不使用[SKAction removeFromParent] 的这段代码(查看两​​种情况下精灵离开屏幕后打印的内容)。

【讨论】:

    【解决方案2】:

    对于您在 addBats 中创建的每个 bat,您可以使用 runAction:completion: 来运行滚动操作,然后在完成块中从父节点中删除节点。问题可能是当您添加多个节点时,您会丢失对要删除的节点的引用。

    这段代码应该做你想做的事(未经测试):

    SKAction *up = [SKAction moveByX:-1 y:-40 duration:1]; 
    SKAction *down = [SKAction moveByX:-1 y:40 duration:1];
    SKAction *action1 = [SKAction repeatActionForever:[SKAction sequence:@[up, down]]];
    [bats runAction:action1];
    
    SKAction *scroll = [SKAction moveByX:-self.size.width * 10 y:0 duration:40.0];
    [bats runAction:scroll completion:^{
       [bats removeFromParent];
    }];
    

    【讨论】:

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