Barkley
Barkley

Reputation: 6713

How to prevent spawning overlap in swift sprite kit?

If I'm trying to spawn in enemies in 2 defined areas of the screen (top and bottom with a middle section where they can't spawn in), how do I prevent them from spawning on top of or too near each other .

My sprites are relatively quite small to the screen, and the only suggestion I've found on here is to create an array of possible positions and every time you use one of those positions take it off the list, but first of all I don't know how that would even look, second of all I've got SO many possible positions because I'm working with 5px high sprites, and I want for them to be able to respawn once that area is clear.

My method of choosing top or bottom is just picking a random number 1 or 2, and depending I've got 2 functions that make them either on top or on bottom.

I just need for no 2 objects to spawn in a ball's diameter from each other. Any ideas how to incorporate that into my spawning?

edit:

  //Create your array and populate it with potential starting points
   var posArray = Array<CGPoint>()
   posArray.append((CGPoint(x: 1.0, y: 1.0))
   posArray.append((CGPoint(x: 1.0, y: 2.0))
   posArray.append((CGPoint(x: 1.0, y: 3.0))

   //Generate an enemy by rolling the dice and 
   //remove its start position from our queue
   let randPos = Int(arc4random()) % posArray.count
   posArray[randPos]
   posArray.removeAtIndex(randPos)

   ...

   //Play game and wait for enemy to die
   //Then repopulate the array with that enemy's start position
   posArray.append(enemyDude.startPosition)

This is the recommendation I found, but this gives errors "expected separator" that I don't really know how to fix.

And so really, I'd have to make a HUGE array of possible positions going across the X and Y covering all areas, or is there some better way to do this?

Upvotes: 3

Views: 1289

Answers (1)

sangony
sangony

Reputation: 11696

Not spawning a node on top of another is simply enough by using intersectsNode(_ node: SKNode) -> Bool.

As for not spawning too close, that's another story. The only way you can do that is too have all your current nodes in an array, enumerate the array and check each node's position to that of the spawning node. Dependent on your parameters, you either spawn or not spawn.


I am not versed in Swift so you will have to translate the code yourself.

-(void)testMethod {

    // an array with all your current nodes
    NSMutableArray *myArray = [NSMutableArray new];

    // the potential new spawn node with the proposed spawn position
    SKSpriteNode *mySpawnNode = [SKSpriteNode new];

    BOOL tooClose = NO;

    // enumerate your node array
    for(SKSpriteNode *object in myArray) {

        // get the absoulte x and y position distance differences of the spawn node
        // and the current node in the array
        // using absolute so you can check both positive and negative values later
        // in the IF statement
        float xPos = fabs(object.position.x - mySpawnNode.position.x);
        float yPos = fabs(object.position.y - mySpawnNode.position.y);

        // check if the spawn position is less than 10 for the x or y in relation
        // to the current node in the array
        if((xPos < 10) || (yPos < 10))
        tooClose = YES;
    }

    if(tooClose == NO) {
        // spawn node
    }
}

Note that the array should be a property and not declared in the scope I have it in the example.

Upvotes: 2

Related Questions