2014-12-30 78 views
0

我正在製作一個遊戲,其中有一個玩家和多個敵人(至少現在這很重要)。我有和NSTimer調用一種方法來召喚敵人類,每隔x時間產生一個敵人。該方法在Enemy類中調用spawn方法,該方法返回在GameScene中產生的SKSpriteNode。我如何跟蹤同一個SKSpriteNode的個體實例

現在,每當敵人是從天上掉下來(這是它的作用:它產生於頂部,然後落下),它的名字叫@「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中的敵人?

+0

這聽起來像基本的面向對象問題。你瞭解類實例和類工廠(類類型)之間的區別嗎? –

+0

是的,我也明白我做錯了什麼,我只是不知道如何正確地做到這一點 – SemAllush

+0

發佈您的代碼,並且不要使用nstimer:http:// stackoverflow。com/a/23978854/201863 – LearnCocos2D

回答

1

SpriteKit提供多種方式來訪問場景(例如,nodeAtPointchildNodeWithNameobjectForKeyedSubscriptenumerateChildNodesWithName)節點,所以沒有必要使用性能/高德跟蹤節點的大多數情況。

具體而言,您可以通過檢查bodyAbodyBcategoryBitMask屬性來確定是否有敵人蔘與了接觸事件(在didBeginContact中)。然後你可以使用主體的node屬性來訪問精靈節點,並使用精靈節點將敵人的名字改爲@「staticEnemy」,並取消設置主體的contactTestBitMask中的「地」位,以便它不再觸發與地面。

+0

但是,如何影響1個敵人而不影響場景中的其他敵人 – SemAllush

+0

您想如何影響敵人?你可以讓你的遊戲事件驅動,它對各種事件的反應。例如,當計時器觸發時,您將一個敵人添加到場景中(只需將其添加到場景中,不需要使用self.enemy跟蹤它)。進行聯繫後,您可以確定涉及哪個敵人,並將其更改爲靜態。 – 0x141E

+0

是的,這是有益的,我會試試這個謝謝 – SemAllush

相關問題