Reputation: 885
Aim:
I have particles falling from the top of the screen and I would like them to increase their speed, as the score reaches a certain value.
Previous failed attempt:
I first made those falling particles affected by gravity and tried to increase the value of gravity as the score hit a certain value. However it didn't seem to work so I assume that gravity cannot be changed during the game.
Current situation:
After some research, I thought of using two global NSTimers, slowTimer
and fastTimer
. slowTimer
is called in didMoveToView
. In touchesBegan
, everytime there is a tap, I call a function, changeSpeed which is this :
func changeSpeed()
{
if score >= 2
{
slowTimer.invalidate()
makeWallsDividerT = 300
fastTimer = NSTimer.scheduledTimerWithTimeInterval(1.4, target: self, selector: Selector("makeWalls"), userInfo: nil, repeats: true)
}
}
makeWallsDividerT
is a variable in the function makeWalls
which is called by the fastTimer
.
Problem with current situation :
When it is game over and everything is reset, I do fastTimer.invalidate()
and still there seem to be problems as it is not resetting to slowTimer. Also it seems that both timers are on as after reset, the game is much faster than fastTimer.
Any pointers please? Or any other ways of achieving what I am trying to do? Thanks!!
Upvotes: 3
Views: 135
Reputation: 13675
Because the spawning action is simple eg. wait + add walls, you could just modify the speed of the spawning action, like this:
import SpriteKit
class GameScene: SKScene {
var score = 0 { didSet{changeSpawningSpeed() } }
override func didMoveToView(view: SKView) {
/* Setup your scene here */
let wait = SKAction.waitForDuration(2.0)
let block = SKAction.runBlock({ [unowned self] in self.spawnWalls()})
let sequence = SKAction.sequence([wait, block])
runAction(SKAction.repeatActionForever(sequence), withKey: "spawning")
}
func spawnWalls(){print("Walls spawned")}
func changeSpawningSpeed(){
if score == 2 {
if let action = actionForKey("spawning"){action.speed += 1.0}
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?)
{
score += 1
}
}
Upvotes: 2
Reputation: 16837
To rework your code so that you are no longer using NSTimers, you want to do the following:
override func didMoveToView(view:SKView)
{
let spawnWall = SKAction.runBlock({[unowned self] in self.makeWalls();});
let sequence = SKAction.sequence([SKAction.waitForDuration(3),spawnWall])
let repeatForever = SKAction.repeatActionForever(sequence);
self.runAction(repeatForver, withKey:"makeWalls");
}
func changeSpeed()
{
if score >= 2
{
self.removeActionForKey("makeWalls");
makeWallsDividerT = 300;
let spawnWall = SKAction.runBlock({[unowned self] in self.makeWalls();});
let sequence = SKAction.sequence([SKAction.waitForDuration(1.4),spawnWall])
let repeatForever = SKAction.repeatForever(sequence);
self.runAction(repeatForver, withKey:"makeWalls");
}
}
This will prevent multiple actions being fired. (In your case, you had multiple timers being fired, and you only stopped the last timer made.)
Upvotes: 2
Reputation: 1665
Also an alternative to the NSTimer
is to use SKAction
s.
SKAction *wait = [SKAction waitForDuration:1.0f];
Upvotes: 2
Reputation: 8130
The problem is you shouldn't be using NSTimers
in SpriteKit
at all.
Use SKAction
:
runAction(
SKAction.sequence([
SKAction.waitForDuration(1.4),
SKAction.runBlock({
self.makeWalls()
})
])
)
Upvotes: 2