0

I just started to learn Swift and Sprite Kit. I need assistance with the following code.

I have a countUp that when the ball is touched the countUp starts but my problem is that every time I tap the ball the rate of speed in the countUp increases. I want the CountUp to be stable. Any help will be appreciated.

class Game: SKScene {

var Ball = SKSpriteNode(imageNamed: "Red.png")
var QuitOption = SKLabelNode()
var ScoreLabel = SKLabelNode()
var timescore = Int()
var timesecond = Int()



override func didMoveToView(view: SKView) {


    backgroundColor = SKColor.blackColor() // background for the display

    self.physicsWorld.gravity = CGVectorMake(0, -9.8)

    let SceneBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
    SceneBody.friction = 0
    self.physicsBody = SceneBody


    Ball.size = CGSize(width: 120, height: 120)
    Ball.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height*0.7)
    Ball.physicsBody = SKPhysicsBody(circleOfRadius: 60)
    Ball.physicsBody?.affectedByGravity = true
    Ball.physicsBody?.restitution = 0.5 
    Ball.physicsBody?.linearDamping = 0
    Ball.name = "Ball"

    self.addChild(Ball)

    QuitOption.text = "Quit"
    QuitOption.fontName = "Noteworthy-Light"
    QuitOption.fontColor = SKColor.greenColor()
    QuitOption.fontSize = 35
    QuitOption.position = CGPoint(x: self.frame.size.width/2 - 160, y: self.frame.size.height*1 - 110)
    QuitOption.name = "Quit"

    addChild(QuitOption)

    ScoreLabel = SKLabelNode(fontNamed: "Noteworthy-Light")
    ScoreLabel.fontSize = 50                 // The + will move it to the right side and - to the left side for more accuracy.
    ScoreLabel.position = CGPoint(x: self.frame.size.width/2, y: self.frame.size.height/4 + 400)  // position of ScoreLabelNode
    ScoreLabel.name = "Score+"
    ScoreLabel.hidden = false

    self.addChild(ScoreLabel)


}

// Making the ball jump after user touches ball

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {


    var touch = touches.first as! UITouch
    var location = touch.locationInNode(self)
    var node = self.nodeAtPoint(location)


    if (node.name == "Quit"){

        let myScene = GameScene(size: self.size)
        myScene.scaleMode = scaleMode
        let reveal = SKTransition.fadeWithDuration(1)
        self.view?.presentScene(myScene, transition: reveal)

    }

    if (node.name == "Ball"){

        for touch: AnyObject in touches {

            let location = touch.locationInNode(self)

            Ball.physicsBody?.allowsRotation = true
            Ball.physicsBody?.velocity = CGVectorMake(0, 0)
            Ball.physicsBody?.applyImpulse(CGVectorMake(0, 100))

        }


    }

    var actionwait = SKAction.waitForDuration(0.5)

    var actionrun = SKAction.runBlock({
        self.timescore++
        self.timesecond++


        if self.timesecond == 60 {self.timesecond = 0}

        self.ScoreLabel.text = " \(self.timescore/60):\(self.timesecond)"})

    ScoreLabel.runAction(SKAction.repeatActionForever(SKAction.sequence([actionwait,actionrun])))



    }


}
Unheilig
  • 16,196
  • 193
  • 68
  • 98

1 Answers1

1

I guess that's happening because you are running same block over and over again after every touch. To ensure you run block only once, you can use some Bool indicator and after the first run, set its value appropriately, like this:

if(!self.locked){
        self.locked = true // at start, this value should be false
        var actionrun = SKAction.runBlock({


            self.timescore++

             self.timesecond++


            if self.timesecond == 60 {self.timesecond = 0}

            self.ScoreLabel.text = " \(self.timescore/60):\(self.timesecond)"})

        ScoreLabel.runAction(SKAction.repeatActionForever(SKAction.sequence([actionwait,actionrun])))

        }
        }

Something as an addition to this topic and for future readers could be found here.

Community
  • 1
  • 1
Whirlwind
  • 14,286
  • 11
  • 68
  • 157
  • That answer is exactly right! Great answer, Whirlwind, though it may have been a bit confusing. I found it hard to understand, and I already knew the concept Lol! – Christian Kreiter May 28 '15 at 14:55
  • @ChristianKRider Hi Christian... It just a single boolean value :) added to track of something that shouldn't run for multiple times. There are always more different ways in programming to do something, so if you have in mind something else, please post it, maybe it will help OP to learn from it. But I think that this answer at least points where the problem is. – Whirlwind May 28 '15 at 15:30
  • @HenryCastillo You are welcome.. I am glad it helped. – Whirlwind May 28 '15 at 19:50
  • @Whirlwind I looked over it a few more times. It seems to be a good answer. I wouldn't have added the runBlock({ ... }), though. That's all. I think the traditional OOP way of this code may have been more complicated, now that I think of it. Your code merely looks funny :P – Christian Kreiter May 29 '15 at 14:46
  • @ChristianKRider Ah, okay... About the the block part...Well that's the part of OP's code if you look better...I just wrapped all in one if statement ;) – Whirlwind May 29 '15 at 14:49