update function w/ multiple intervals (SWIFT)

983 views Asked by At

I'm a newbie to programming so please help. I'm trying to set up intervals to create various Sprite nodes throughout my game (using the update function). However, each Sprite node needs to spawn at different intervals. I have a bunch of "if" statements and it seems to be causing my frame rate to drop and cause the app to lag. Can someone please tell me how to fix this? If possible, please also explain to me why it does this so that I can better understand the coding process. Thank you!

var timeBetweenBirds: Int!
var timeBetweenBadBirds: Int!
var timeBetweenSubtractTimeBirds: Int!
var timeBetweenAddTimeBirds: Int!
var timeBetweenBonusBirds: Int!

var now : NSDate?
var nextTime : NSDate?
var badBirdNextTime: NSDate?
var subtractTimeBirdNextTime: NSDate?
var addTimeBirdNextTime: NSDate?
var bonusBirdNextTime: NSDate?

override func update(currentTime: CFTimeInterval) {

 timeBetweenBirds = Int(arc4random_uniform(3))
 timeBetweenBadBirds = Int(arc4random_uniform(3) + 2)
 timeBetweenSubtractTimeBirds = Int(arc4random_uniform(3) + 2)
 timeBetweenAddTimeBirds = Int(arc4random_uniform(1) + 5)
 timeBetweenBonusBirds = Int(arc4random_uniform(20) + 20)


now = NSDate()

  if now?.timeIntervalSince1970 > nextTime?.timeIntervalSince1970 {

        nextTime = now?.dateByAddingTimeInterval(NSTimeInterval(timeBetweenBirds))

        createBird()
    }

    if now?.timeIntervalSince1970 > badBirdNextTime?.timeIntervalSince1970 {

        badBirdNextTime = now?.dateByAddingTimeInterval(NSTimeInterval(timeBetweenBadBirds))

        createBadBird()

    }

    if now?.timeIntervalSince1970 > subtractTimeBirdNextTime?.timeIntervalSince1970 {

        subtractTimeBirdNextTime = now?.dateByAddingTimeInterval(NSTimeInterval(timeBetweenSubtractTimeBirds))

        createSubtractTimeBird()

    }

    if now?.timeIntervalSince1970 > addTimeBirdNextTime?.timeIntervalSince1970 {

        addTimeBirdNextTime = now?.dateByAddingTimeInterval(NSTimeInterval(timeBetweenAddTimeBirds))

        createAddTimeBird()

    }

    if now?.timeIntervalSince1970 > bonusBirdNextTime?.timeIntervalSince1970 {

        bonusBirdNextTime = now?.dateByAddingTimeInterval(NSTimeInterval(timeBetweenBonusBirds))

        createBonusBird()

    }
2

There are 2 answers

1
pbodsk On

Maybe this is not the correct solution, but it'll simplify things at least.

A couple of things to consider.

  • Right now you are generating a new timeBetweenBirds value in each update loop, but you're only using it if you end up in the if statement

    override func update(currentTime: CFTimeInterval) {
    
        timeBetweenBirds = Int(arc4random_uniform(3)) //Created on each update loop
        ...
        now = NSDate()
    
        if now?.timeIntervalSince1970 > nextTime?.timeIntervalSince1970 {
            //Only used here           
            nextTime = now?.dateByAddingTimeInterval(NSTimeInterval(timeBetweenBirds)) 
            createBird()
        }
    

    So a place to start could be to update the timeBetweenBirds value only when needed.

  • As I see it, you don't need to create all these dates and compare between them.

    Every time update is called, you get a currentTime property for free :-) This property could be used to check against a nextTime variable like so:

    var nextTime: CFTimeInterval = 0
    ...
    override func update(currentTime: CFTimeInterval) {
        if currentTime > nextTime {
            nextTime = currentTime + CFTimeInterval(arc4random_uniform(3))
            createBird()
        }
        //And so on with your other if statements
    }
    

As I said, I don't know if this speeds things up, but it'll simplify your code, which is always good :-)

0
Ryan Dines On

I always give each function that update calls its own timing variable so that it doesn't have to run so many blocks of code every 1/60th of a second. Example:

var timeOfLastUpdateForUserMotion:CFTimeInterval = 0

func processUserMotionForUpdate(currentTime: CFTimeInterval){
    if (currentTime - timeOfLastUpdateForUserMotion > 0.1) {
        ...
        timeOfLastUpdateForUserMotion = currentTime
    }
}
override func update(currentTime: CFTimeInterval) {
    processUserMotionForUpdate(currentTime)
}

In this particular case I'm checking the accelerometer once every 3 frames. In your case:

var timeOfLastUpdateForRandomVariable
var birdOneInterval:Double = 0
var birdTwoInterval:Double = 0

func updateRandomVariables(currentTime:CFTimeInterval){
    if (currentTime - timeOfLastUpdateForRandomVariable > 1.0){
        birdOneInterval = Int(arc4random_uniform(3)+1)
        birdTwoInterval = Int(arc4random_uniform(3) + 2)
        timeOfLastUpdateForRandomVariable = currentTime
    }
}
    override func update(currentTime: CFTimeInterval) {
        updateRandomVariables(currentTime)
    }

Make sure not to get the interval, birdOneInterval, for example, too close to zero, or you could get a machine gun effect of birds flying everywhere; happens to me occasionally.