如何跟踪相同SKSpriteNode的各个实例

时间:2014-12-30 14:13:17

标签: ios objective-c sprite-kit

我正在制作一个游戏,其中有一个玩家和多个敌人(至少,现在这很重要)。我有和NSTimer调用一种方法来调用每隔x个时间产生一个敌人的敌人类。该方法在Enemy类中调用spawn方法,该类返回在GameScene中生成的SKSpriteNode。

现在,只要敌人从天上掉下来(这就是它的作用:它在顶部生成然后倒下),它的名字是@“fallingEnemy”,每当它撞到地面时,这个名字就会更新为@“ staticEnemy“(我使用接触位掩码进行此操作)我想要发生的事情如下:每当敌人尚未击中地面并在击中地面之前击中玩家时,我希望它能够杀死玩家并且当敌人已经到了地面并且玩家接触了它,我希望玩家死亡。

我通过检查(使用If语句),如果玩家联系敌人,敌人的名字是@“fallingEnemy”。问题在于:在我的GameScene中,我有一个属性调用aNewEnemy(SKSpriteNode),它被设置为等于每次NSTimer调用时Enemy类返回的SKSpriteNode。然后,当敌人击中地面时,名称会变为@“staticEnemy”一段时间,直到新的敌人产生,因为这个名称将被设置回@“fallingEnemy”。我完全理解为什么会发生这种情况,因为它非常明显,但我不是没有其他方法可以做到这一点。有人有什么建议吗?可能有一种更容易实现的方法,我不熟悉。

谢谢!

编辑:

我在这里发布了代码:

-(void)createSceneContents {
    self.spawningSpeed = 2.5;
self.enemySpawnTimer = [NSTimer scheduledTimerWithTimeInterval:self.spawningSpeed
                                                        target:self
                                                      selector:@selector(spawnObject)
                                                      userInfo:nil
                                                       repeats:YES];
}

createSceneContents方法中有更多内容,但现在这些并不重要。

-(void)spawnObject {
if (self.isPaused == NO){


        self.enemyData = [[Enemy alloc]init];

    self.aNewEnemy = [self.enemyData createEnemyWithSize:self.playerSize andWidth:self.frame.size.width andHeight:self.frame.size.height + self.player.position.y];
        self.aNewEnemy.physicsBody.allowsRotation = NO;
        self.aNewEnemy.physicsBody.categoryBitMask = self.enemyCategory;
        self.aNewEnemy.physicsBody.contactTestBitMask = self.enemyCategory | self.playerCategory | self.edgeCategory | self.bottomCategory;
        [self.world addChild:self.aNewEnemy];

    self.playerScore += 10;
    NSString *score = [NSString stringWithFormat:@"%i", self.playerScore];
    self.actualScore.text = score;

 }
}

在Enemy.m中:

-(SKSpriteNode *)createEnemyWithSize:(float)size andWidth:(float)width andHeight:(float)height {
    self.enemy = [SKSpriteNode spriteNodeWithImageNamed:@"block.png"];
    self.enemy.size = CGSizeMake(size - 5, size - 5);

    self.enemy.name = @"fallingEnemy";
    self.enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(size - 1, size - 1)];
    self.enemy.physicsBody.restitution = 0;
    int randomSection = arc4random_uniform(7);
    switch (randomSection) {
    case 0:

        self.enemy.position = CGPointMake(2.5 + self.enemy.size.width/2, height-5);

        break;
    case 1:


        self.enemy.position = CGPointMake(width/7 + self.enemy.size.width/2, height-5);

        break;
    case 2:

        self.enemy.position = CGPointMake((width/7*2)  + self.enemy.size.width/2, height-5);

        break;
    case 3:

        self.enemy.position = CGPointMake((width/7*3)  + self.enemy.size.width/2, height-5);

        break;
    case 4:

        self.enemy.position = CGPointMake((width/7*4)  + self.enemy.size.width/2, height-5);

        break;
    case 5:

        self.enemy.position = CGPointMake((width/7*5)  + self.enemy.size.width/2, height-5);

        break;
    case 6:

        self.enemy.position = CGPointMake((width/7*6)  + self.enemy.size.width/2, height-5);


        break;
    default:

        break;
 }
 return self.enemy;
}

当敌人接触地面或另一个敌人时,会在didBeginContact中调用它:

-(void)changeState {

   self.enemy.physicsBody.dynamic = NO;
   self.isFalling = NO;
   self.enemy.name = @"staticEnemy";

}

现在我如何跟踪GameScene中的个别敌人?

1 个答案:

答案 0 :(得分:1)

SpriteKit提供了多种方式来访问场景中的节点(例如nodeAtPointchildNodeWithNameobjectForKeyedSubscriptenumerateChildNodesWithName),因此无需使用属性/ ivars用于跟踪大多数情况下的节点。

具体来说,您可以通过查看didBeginContactcategoryBitMask的{​​{1}}属性来确定敌人是否参与了联系人事件(bodyA)。然后,您可以使用正文的bodyB属性访问精灵节点,并使用精灵节点将敌人的名称更改为@“staticEnemy”并取消设置正文node中的“地面”位,以便它不再触发与地面的接触事件。