I'm working on a Snake Game using swift and the library SpriteKit
.
I reached the point where I have to create the tail of the snake.
The code I made works with 2 arrays: snakeX
and snakeY
. Both of them are global empty arrays of type CGFloat
. At every execution, I add to these arrays the X player position and the Y player position. If the score doesn't change, I delete the last element of both arrays. In this way, If the score is 0, I'll always have only one element for each array. But then, if the score changes, I don't delete the last element. Therefore, is the score increases by 1, I'll have 2 elements for each array... etc. etc.
The elements stored in snakeX
and snakeY
arrays represents the previous player position. In this way, I'll display the snake tail in this position and the tail will follow the head.
But here's the problem. The snake's head moves 56 pixels every 0.1 seconds. BUT, at each run, it moves 8 pixels. Because of this, the "previous player position coordinates" stored in the snakeX
and snakeY
arrays are always 8 pixels less than the current player position. Basically... the tail will be covered for 1/7 by the snake's head.
To avoid this problem I thought I could just tell the program to wait for 0.1s before adding the previous player position coordinates to the snakeX
and snakeY
arrays, but the rest of the code keep running and when it will try to access to the element in position 0 of the array snakeX
(or snakeY
) it won't find anything because it will appear an element only after 0.1s.
I also tried to call the function makeTail()
only after 7 execution (8 pixel * 7 execution = 56 pixel ). This worked, but 60fps aren't enough and the tail keeps blitzing.
Here's the code I used to create the tail:
func makeTail(){
snakeX.insert(player.position.x, at: 0)
snakeY.insert(player.position.y, at: 0)
if firstTime == false{ //this variable starts equal true. This avoids the error "out of index". Without this variable, with score = 0 the program would't find any item in the arrays
if prevscore == score { //if the score doesn't change, remove
snakeX.removeLast() //the last element of both arrays
snakeY.removeLast()
}
else { //if the score changes, don't delete anything and just
prevscore += 1 // add 1 to the previous score variable
}
}
for i in 0...score{ //call the function "spawnTail" once if the
spawnTail(index:i) // score is equal to 0, twice if the score is equale to 1... etc. etc.
}
firstTime = false
}
func spawnTail(index:Int){
let tail = SKSpriteNode(imageNamed: "tail")
let endPoint = CGPoint(x: player.position.x, y: player.position.y)
tail.zPosition = 1
tail.setScale(2)
tail.position.x = snakeX[index]
tail.position.y = snakeY[index]
self.addChild(tail)
//let waitToMove = SKAction.wait(forDuration: 0.1)
let moveTail = SKAction.move(to: endPoint, duration:0.1/8)
let deleteTail = SKAction.removeFromParent()
let tailSequence = SKAction.sequence([moveTail, deleteTail])
tail.run(tailSequence)
}