Reputation: 375
So, I have this timer that is setup to run a specific function (which are both shown below) on a time interval variable called 'frequency' when I try and change the timeinterval variable frequency to a lower number based on the score number it doesn't seem to change the rate at which it fires it just seems to fire at the same time even if the frequency is changed to a lower number
override func didMove(to view: SKView) {
Timer.scheduledTimer(timeInterval: frequency, target: self, selector: #selector(GameScene.spawnFallingOjects), userInfo: nil, repeats: true)
}
func spawnFallingOjects() {
if (GameState.current == .playing || GameState.current == .blackstone) {
guard usingThirdEye == false else { return }
let scoreLabel = childNode(withName: "scoreLabel") as! Score
let lane = [-100, -50 , 0, 50, 100]
let duration = 3.0
switch scoreLabel.number {
case 0...50:
frequency = 6.0
print("frequency has changed: \(frequency)")
case 51...100:
frequency = 4.5
print("frequency has changed: \(frequency)")
case 101...200000:
frequency = 1.1
print("frequency has changed: \(frequency)")
default:
return
}
let randomX = lane[Int(arc4random_uniform(UInt32(lane.count)))]
let object:Object = Object()
object.createFallingObject()
object.position = CGPoint(x: CGFloat(randomX), y: self.size.height)
object.zPosition = 20000
addChild(object)
let action = SKAction.moveTo(y: -450, duration: duration)
object.run(SKAction.repeatForever(action))
}
}
How do I make the timer fire faster when the frequency number changes to a lower number? should I recreate the timer at the end of the function?
Upvotes: 0
Views: 1595
Reputation: 16837
You should actually avoid using Timer, Sprite kit has its own time functionality, and Timer does not work well with it and is a real pain to manage.
Instead, use SKAction's to wait and fire:
let spawnNode = SKNode()
override func didMove(to view: SKView) {
let wait = SKAction.wait(forDuration:frequency)
let spawn = SKAction.run(spawnFallingObjects)
spawnNode.run(SKAction.repeatForever(SKAction.sequence([wait,spawn])))
addChild(spawnNode)
}
Then to make it faster, just do:
switch scoreLabel.number {
case 0...50:
spawnNode.speed = 1
print("speed has changed: \(spawnNode.speed)")
case 51...100:
spawnNode.speed = 1.5
print("speed has changed: \(spawnNode.speed)")
case 101...200000:
spawnNode.speed = 2
print("speed has changed: \(spawnNode.speed)")
default:
return
}
Upvotes: 2
Reputation: 47896
The timeInterval
property of Timer
is a readonly property. (And your code is not trying to write a new frequency
into the property...)
should I recreate the timer at the end of the function?
Nearly yes. Just you have no need to do it at the end.
With changing your method header like this:
func spawnFallingOjects(_ timer: Timer) {
You can access the fired Timer
through the parameter timer
, so you may need to write something like this just after switch scoreLabel.number {...}
:
if frequency != timer.timeInterval {
//Invalidate old Timer...
timer.invalidate()
//And then allocate new one
Timer.scheduledTimer(timeInterval: frequency, target: self, selector: #selector(GameScene.spawnFallingOjects), userInfo: nil, repeats: true)
}
You can modify the fireDate
property of an existing Timer
(in case which still isValid
), but recreating a Timer
instance is not a heavy operation (comparing to creating an SKSpriteNode
instance), so recreating a new Timer
seems to be a little bit easier.
Upvotes: 0