我正在制作一个游戏,其中有一个玩家和多个敌人(至少,现在这很重要)。我有和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中的个别敌人?
答案 0 :(得分:1)
SpriteKit提供了多种方式来访问场景中的节点(例如nodeAtPoint
,childNodeWithName
,objectForKeyedSubscript
和enumerateChildNodesWithName
),因此无需使用属性/ ivars用于跟踪大多数情况下的节点。
具体来说,您可以通过查看didBeginContact
和categoryBitMask
的{{1}}属性来确定敌人是否参与了联系人事件(bodyA
)。然后,您可以使用正文的bodyB
属性访问精灵节点,并使用精灵节点将敌人的名称更改为@“staticEnemy”并取消设置正文node
中的“地面”位,以便它不再触发与地面的接触事件。