Astrum
Astrum

Reputation: 375

Taking an array option out for one cycle

Ok so I have this code where spawn locations are put into an array and then one of the locations is picked at random with this code:

let randx = spawnLocations[Int(arc4random_uniform(UInt32(spawnLocations.count)))]
            obstacle.position = CGPoint(x: randx, y: 0)

Object Spawning code:

var spawnLocations:[CGFloat] = [] 

func getObjectSpawnLocation() {

//Create 5 possible spawn locations
let numberOfNodes = 5

    // Spacing between nodes will change if: 1) number of nodes is changed, 2) screen width is changed, 3) node's size is changed.
    for i in 0...numberOfNodes - 1 {

        // spacing used to space out the nodes according to frame (which changes with screen width)
        var xPosition = (frame.maxX /*- thePlayer.size.width*/) / CGFloat((numberOfNodes - 1)) * CGFloat(i)

        //add a half of a player's width because node's anchor point is (0.5, 0.5) by default
        xPosition += thePlayer.size.width/2

        //I have no idea what this does but it works.
        xPosition -= frame.maxX/1.6
        spawnLocations.append( xPosition )

    }
  ()
}

But I have a problem because sometimes the game spawns the objects like in the picture below and it does not let my player advance any further without them dying and so my question is:

Is there anyway I can stop it from doing this?

maybe take one of the spawning locations out of the array temporally?

I should also note that each of the objects (Skulls) are spawned one after the other not all at once and the skulls can spawn at any of the 5 horizontal locations.

enter image description here

Upvotes: 0

Views: 59

Answers (1)

Double M
Double M

Reputation: 1503

The player can only be trapped between the skulls and the screen's edge. You should keep track whether or not you are currently "wedging" the player in or not, for example:

//Keep instance variables to track your current state
BOOL lineFromEdge; //YES if you're currently drawing a "line" of skulls from an edge
BOOL leftEdge; //YES if the line originates from the left edge, NO if from the right
int previousIndex;

Then you determine the value as follows:

- (int) randomIndex {

    int randIndex = Int(arc4random_uniform(UInt32(spawnLocations.count)));

    // This expression tells you if your current index is at an edge
    if (randIndex == 0 || randIndex == (spawnLocations.count - 1)) {
        lineFromEdge = YES;
        leftEdge = randIndex == 0;
    }

    //Check if you left a gap
    BOOL didLeaveGap = abs(randIndex - previousIndex) > 1
    if (didLeaveGap) lineFromEdge = NO;

    if ((lineFromEdge && leftEdge && randomIndex == spawnLocations.count) ||
        (lineFromEdge && !leftEdge && randomIndex == 0)) {

        //You have drawn a line from one edge to the other without leaving a gap;
        //Calculate another index and perform the same checks again
        return [self randomIndex];

    }

    //Your index is valid
    previousIndex = randIndex;
    return randIndex;
}

Note: Your algorithm must return 0 or spawnLocations.count as very first index for this to work. Else your skulls may start at the center and still wedge the player in without you realizing it.

Upvotes: 0

Related Questions