简体   繁体   中英

Call method on certain distance between nodes in Spritekit

I'm trying to create a game where enemies follow player. I tried enumerating all enemy nodes and calculating distance to a player. I did all this in Update function. By doing so I have a huge FPS drop and almost 100% CPU usage. Is there any other way I can achieve the same behavior?

[self enumerateChildNodesWithName:@"enemy" usingBlock:^(SKNode * _Nonnull node, BOOL * _Nonnull stop) {
    if(SDistanceBetweenPoints(self.player.position, node.position)<120)
        {
            if((![[node.userData objectForKey:@"move"] boolValue])&&
              ((SDistanceBetweenPoints(self.player.position, node.position)>45)))
            {
                [self findPathFor:node To:self.player.position];
            }
            else if (round(SDistanceBetweenPoints(self.player.position, node.position) <= 32.01) &&
                    (![node hasActions]) &&
                    (![[self.player.userData objectForKey:@"move"] boolValue]))
            {
                [self thisNode:node attack:self.player];
            }

            [self update:node WithDeltaTime:deltaTime];
        }
}];

EDIT : When I'm enumerating enemies from self , maybe it's taking so much time, because I have lots and lots of nodes in self . Maybe it would be better to create like a separate self thingy for enemies?

EDIT2 : I tried adding all enemies to an array and used for loop instead of enumerating. And now I get steady 60 fps and ±40% CPU usage.

for (SKNode *node in self.enemiesArray) {
    [self update:node WithDeltaTime:deltaTime];
}

SKAction *enemiesFollow = [SKAction runBlock:^{

    for(SKNode *node in self.enemiesArray){
       [...]
    }

}];

SKAction *wait = [SKAction waitForDuration:0.5];

if(![self actionForKey:@"enemyFollow"]){
    [self runAction:[SKAction sequence:@[wait, enemiesFollow]] withKey:@"enemyFollow"];
}

Is it the right way of doing this?

I think a different approach would serve you much better.

Instead of calculating the distance between the player and every node every update, use the collisions frame work which should calculate much faster.

Add a circle node with a transparent color (UIColor with the alpha 0)to the player that has a radius of how far away you want something to happen when the enemies get that close. When an enemy collides with the circle run your code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM