Stuck Beginner
Stuck Beginner

Reputation: 93

My code seems to run too quickly

I am in the process of writing a Simon style memory game, the phase of the game where the program shows the user the current list of stuff to remember seems to run instantly.

The idea is to step through the list (in the code I have placed 1 of each item as debug data) and change the colour on screen for a set period then move to the next.

I thought using for each item in memory array and then call a simple procedure to check which one it is and then change colour for a set period then back to original.

The code I have added here will work if I put breaks in between the test change colour (grey) and the original colour. But for some reason the timer does not seem too work.

Any ideas ?

import UIKit
import Foundation

var gameisrunning = false
var playererror = false
var memoryArray = [Int]()
var currentScore = 0

var timer = NSTimer()

class ViewController: UIViewController {

    @IBAction func startGameButton(sender: UIButton) {

        if gameisrunning == false {

            gameisrunning = true
            memoryArray.append(1) //for debug
            memoryArray.append(2) //for debug
            memoryArray.append(3) //for debug
            memoryArray.append(4) //for debug
            print(memoryArray) //for debug
            gameStart()

        } else {


        }

    }


    //these are to be implemented once i get the showing sequence sorted.

    @IBAction func redButton(sender: UIButton) {

    }

    @IBAction func greenButton(sender: UIButton) {

    }

    @IBAction func yellowButton(sender: UIButton) {

    }

    @IBAction func blueButton(sender: UIButton) {

    }

    @IBOutlet weak var redLabel: UILabel!
    @IBOutlet weak var greenLabel: UILabel!
    @IBOutlet weak var yellowLabel: UILabel!
    @IBOutlet weak var blueLabel: UILabel!
    @IBOutlet weak var scoreLabel: UILabel!

    func addAnotherItemToMemory () {

        // adds another item to the memory

        memoryArray.append(Int(arc4random_uniform(4)+1))
    }

    func gameStart () {

        // main body of game
        showPlayerTheMemory()
    }


    func showPlayerTheMemory () {

        // go through list and highlight the colors one at a time

        for eachItem in memoryArray {
            self.showColor(eachItem)
        }
    }


    func pauseForAWhile(length: Double) {

        timer = NSTimer.scheduledTimerWithTimeInterval(length, target:self, selector: nil , userInfo: nil, repeats: false)
        timer.invalidate()

    }


    func showColor(buttonItem: Int) {

        //check to see which color, change to grey (test color) and back to original after a set time.

        if buttonItem == 1  {

            self.redLabel.backgroundColor = UIColor.grayColor()
            pauseForAWhile(2)
            self.redLabel.backgroundColor = UIColor.redColor()
            print(buttonItem) //for debug

        } else if buttonItem == 2 {

            self.greenLabel.backgroundColor = UIColor.grayColor()
            pauseForAWhile(2)
            greenLabel.backgroundColor = UIColor.greenColor()
            print(buttonItem) //for debug

        } else if buttonItem == 3 {

            self.yellowLabel.backgroundColor = UIColor.grayColor()
            pauseForAWhile(2)
            yellowLabel.backgroundColor = UIColor.yellowColor()
            print(buttonItem) //for debug

        } else if buttonItem == 4 {

            self.blueLabel.backgroundColor = UIColor.grayColor()
            pauseForAWhile(2)
            blueLabel.backgroundColor = UIColor.blueColor()
            print(buttonItem) //for debug

        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

New relevant code changed to :

func colorChange (){

    self.redLabel.backgroundColor = UIColor.redColor()
    self.blueLabel.backgroundColor = UIColor.blueColor()
    self.yellowLabel.backgroundColor = UIColor.yellowColor()
    self.greenLabel.backgroundColor = UIColor.greenColor()
}

func showColor(buttonItem: Int, length: Double) {

    //check to see which color, change to grey (test color) and back to original after a set time.

    if buttonItem == 1  {

        self.redLabel.backgroundColor = UIColor.grayColor()
        timer = NSTimer.scheduledTimerWithTimeInterval(length, target:self, selector: ("colorChange") , userInfo: nil, repeats: false)
        print(buttonItem) //for debug

    } else if buttonItem == 2 {

        self.greenLabel.backgroundColor = UIColor.grayColor()
        timer = NSTimer.scheduledTimerWithTimeInterval(length, target:self, selector: ("colorChange") , userInfo: nil, repeats: false)
        print(buttonItem) //for debug

    } else if buttonItem == 3 {

        self.yellowLabel.backgroundColor = UIColor.grayColor()
        timer = NSTimer.scheduledTimerWithTimeInterval(length, target:self, selector: ("colorChange") , userInfo: nil, repeats: false)
        print(buttonItem) //for debug

    } else if buttonItem == 4 {

        self.blueLabel.backgroundColor = UIColor.grayColor()
        timer = NSTimer.scheduledTimerWithTimeInterval(length, target:self, selector: ("colorChange") , userInfo: nil, repeats: false)
        print(buttonItem) //for debug

    }
}

I have been scratching head all day trying to solve this issue which is baffling me. I have copied the new latest code in below, please discard code above.

I have four labels coloured red blue green and yellow. The array which has test data of 4 3 2 1 inside needs to step through each item - change the colour of the label for x secs then return it to normal colour. I have tried NSTimer, I have tried the current delay as in the code attached. Am I missing something as to where I place the code - should it be under viewdidload ??? I have tried for loops and the current code example shows switch in case it acted differently - it didnt !!

What happens basically is simultaneously all labels go grey (test colour right now) and then all go original colour after the x sec delay.

I need some help before I go insane. I honestly know it is something basic but I just cannot figure it out.

import UIKit
import Foundation

var gameisrunning = false
var playererror = false
var memoryArray = [Int]()
var currentScore = 0

class ViewController: UIViewController {

    @IBAction func startGameButton(sender: UIButton) {

        if gameisrunning == false {

            gameisrunning = true
            memoryArray.append(4) //for debug
            memoryArray.append(3) //for debug
            memoryArray.append(2) //for debug
            memoryArray.append(1) //for debug
            print(memoryArray) //for debug
            gameStart()

        } else {

        }
    }


    //these are to be implemented once i get the showing sequence sorted.

    @IBAction func redButton(sender: UIButton) {
    }
    @IBAction func greenButton(sender: UIButton) {
    }
    @IBAction func yellowButton(sender: UIButton) {
    }
    @IBAction func blueButton(sender: UIButton) {
    }

    @IBOutlet weak var redLabel: UILabel!
    @IBOutlet weak var greenLabel: UILabel!
    @IBOutlet weak var yellowLabel: UILabel!
    @IBOutlet weak var blueLabel: UILabel!
    @IBOutlet weak var scoreLabel: UILabel!

    func addAnotherItemToMemory () {
        // adds another item to the memory
        memoryArray.append(Int(arc4random_uniform(4)+1))
    }

    func gameStart () {
        // main body of game
        showPlayerTheMemory()
    }

    func delayProg (){
        //attempt 100093287492 to get a delay in program
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
            self.blueLabel.backgroundColor = UIColor.blueColor()
            self.yellowLabel.backgroundColor = UIColor.yellowColor()
            self.greenLabel.backgroundColor = UIColor.greenColor()
            self.redLabel.backgroundColor = UIColor.redColor()

        }
    }

    func showPlayerTheMemory () {

        // go through list and highlight the colors one at a time

        for var i=0; i <= memoryArray.count-1; i++ {
            self.showColor(memoryArray[i])
        }
    }


    func showColor(buttonItem: Int) {

        //check to see which color, change to grey (test color) and back to original after a set time.

        switch (buttonItem) {

        case 1:
            self.redLabel.backgroundColor = UIColor.grayColor()
            delayProg()
            print(buttonItem) //for debug
        case 2:
            self.greenLabel.backgroundColor = UIColor.grayColor()
            delayProg()
            print(buttonItem) //for debug
        case 3:
            self.yellowLabel.backgroundColor = UIColor.grayColor()
            delayProg()
            print(buttonItem) //for debug
        case 4:
            self.blueLabel.backgroundColor = UIColor.grayColor()
            delayProg()
            print(buttonItem) //for debug
        default:
            print("error")
        }
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Upvotes: 1

Views: 107

Answers (1)

MikeG
MikeG

Reputation: 4044

Here is an example of proper implementation of NSTimer()

var myTimer = NSTimer()

func startTimer() {
    myTimer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: "myFunction", userInfo: nil, repeats: true)
}

func myFunction() {
myTimer.invalidate()
    //do other stuff
}
//the selector is "myFunction", this will be the name of the function that you wish to call every time the timer reaches its specified intervl
//the interval in this case is 10 seconds. In my experience NSTimer is good down to the second but is not precise enough beyond that
//repeats: true ... this will tell the timer to repeat its action consistently firing the selector each time the given time interval is reached. If repeat is set to false then the timer only fires once
//use myTimer.invalidate to stop the timer and to stop calling the selector.

be sure to invalidate your timer or set repeats: false to make sure it doesn't go forever. Make sure your selector is spelled exactly the same as your function. if your function is func myFunction() then the selector should be "myFunction". Make sure you specify a valid time interval, which is taken as seconds.

Upvotes: 1

Related Questions