我正在制作一个游戏,其中有一个玩家和多个敌人(至少,目前这很重要)。我有 NSTimer 调用一个方法,该方法调用每 x 时间产生一个敌人的 Enemy 类。该方法调用 Enemy 类中的 spawn 方法,该方法返回一个在 GameScene 中生成的 SKSpriteNode。
现在,每当 Enemy 从天而降(这就是它的作用:它在顶部生成然后掉落),它的名字是@"fallingEnemy",每当它撞到地面时,这个名字就会更新为@"staticEnemy”(我使用接触位掩码来做到这一点)我想要发生的事情如下:每当敌人还没有撞到地面并在它撞到地面之前击中玩家时,我希望它杀死玩家并且当敌人已经落地,玩家触碰它,我想让玩家死掉。
我通过检查(使用 If 语句)每当玩家接触敌人时敌人的名称是否为 @"fallingEnemy"来执行此操作。问题在于:在我的 GameScene 中,我有一个属性调用 aNewEnemy (SKSpriteNode),它被设置为等于 Enemy 类每次被 NSTimer 调用时返回的 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 中的单个敌人?
最佳答案
SpriteKit 提供了多种方式来访问场景中的节点(例如,nodeAtPoint
、childNodeWithName
、objectForKeyedSubscript
和enumerateChildNodesWithName
),因此在大多数情况下无需使用属性/变量来跟踪节点。
具体来说,您可以通过检查 bodyA
的 categoryBitMask
属性来确定敌人是否参与了接触事件(在 didBeginContact
中)和正文B
。然后,您可以使用 body 的 node
属性访问 Sprite 节点,并使用 Sprite 节点将敌人的名称更改为@"staticEnemy"并取消设置 body 的 contactTestBitMask 中的“ground”位
因此它不再触发与地面的接触事件。
关于ios - 如何跟踪同一 SKSpriteNode 的各个实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27706993/