H.Sunner
H.Sunner

Reputation: 39

Swift fatal error: Array index out of range

I'm creating a game as a small project and i'm trying to make it so after ever 5 points the walls will generate more but when playing the game, it crashes at reaching around 24 points with the the error "fatal error: Array index out of range"

GameScene.swift

 if pointsLabel.number % kNumberOfPointsPerLevel == 0 {
                    currentLevel++
                    wallGenerator.stopGenerating()
                    wallGenerator.startGeneratingWallsEvery(kLevelGenerationTimes[currentLevel])
                }

Constants.swift

let kNumberOfPointsPerLevel = 5
let kLevelGenerationTimes: [NSTimeInterval] = [1.0, 0.8, 0.6, 0.4, 0.3]

Upvotes: 1

Views: 210

Answers (3)

David Skrundz
David Skrundz

Reputation: 13347

You're calling kLevelGenerationTimes[currentLevel] where currentLevel gets incremented every time pointsLabel.number % kNumberOfPointsPerLevel == 0.

kLevelGenerationTimes only has 5 elements ([1.0, 0.8, 0.6, 0.4, 0.3]) and with the rate at which you increase the level

Points: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Level : 0 0 0 0 0 1 1 1 1 1  2  2  2  2  2  3  3  3  3  3  4  4  4  4  4  5

At 25 points, currentLevel becomes 5 which is an invalid index for your array.

Upvotes: 3

Antonio
Antonio

Reputation: 72820

It looks like the error is here:

wallGenerator.startGeneratingWallsEvery(kLevelGenerationTimes[currentLevel])

when currentLevel is equal to or greater than the number of elements in kLevelGenerationTimes.

I don't know what the correct solution is, depending on your game logic - I would propose 2 versions, the first restarting from the first element of that array once the end is reached:

wallGenerator.startGeneratingWallsEvery(kLevelGenerationTimes[currentLevel % kLevelGenerationTimes.count])

whereas the second is to always use the last element of the array (I take that as an increasing complexity as the player progresses):

let index = currentLevel < kLevelGenerationTimes.count ? currentLevel : kLevelGenerationTimes.count - 1
wallGenerator.startGeneratingWallsEvery(kLevelGenerationTimes[index])

Upvotes: 1

Luca Angeletti
Luca Angeletti

Reputation: 59536

It happens because you have an array with 5 cells with index from 0 to 4.

If you try to access the array with a index outside this range the app will crash.

Example:

let kLevelGenerationTimes: [NSTimeInterval] = [1.0, 0.8, 0.6, 0.4, 0.3]

kLevelGenerationTimes[0] // ok
kLevelGenerationTimes[1] // ok
kLevelGenerationTimes[2] // ok
kLevelGenerationTimes[3] // ok
kLevelGenerationTimes[4] // ok
kLevelGenerationTimes[5] // crash!!!

Upvotes: 2

Related Questions