简体   繁体   中英

How to block touches began while action is executed

I have a game with such mechanics:

Player touches the screen and arrow appears

Player drags his finger, changing arrow orientation

Player lifts his finger and arrow shoots.

It works great when performed accurately. But if player accidentally double tap, game shoots two arrows and it's 99% game over. I want to prevent that but don't know how to do so. I tried userInteractionEnabled, it blocks interaction but not unblock it when needed.

I'm adding arrow on screen like so:

func addArrow() {
    arrow = SKSpriteNode(imageNamed: "red")

    arrow.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) - self.arrow.size.height)
    arrow.zPosition = 1
    addChild(arrow)
    arrowAppear.play()

    let moveToShoot = SKAction.moveTo(CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMinY(self.frame) + self.arrow.size.height + 50), duration: 0.2)
    arrow.runAction(moveToShoot)
    SKActionTimingMode.EaseOut  
}

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if !GameOver {
    runAction(SKAction.runBlock(addArrow))
    }
}

In the touchesBegan method, change the if statement to be something like this:

if !GameOver && !arrow.hasActions() {
    runAction(SKAction.runBlock(addArrow))
}

This will check with your global SKSpriteNode arrow to see if there are running actions on it already. Then, if there's not, it will run the new actions. If you have multiple actions on this arrow , you may wish to call arrow.actionForKey("your key") to get the action if there is one, where you then check if it exists. And put arrow.runAction(moveToShoot, withKey: "your key") instead of arrow.runAction(moveToShoot) .

Edit An example of this would be:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if !GameOver {
        if let action = arrow.actionForKey("your key") {
            // Has the action already, do not add an action
        } else {
            // Does not have the action, add it
            runAction(SKAction.runBlock(addArrow))
        }
    }
}

And then in your addArrow function:

func addArrow() {
    arrow = SKSpriteNode(imageNamed: "red")

    arrow.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame) - self.arrow.size.height)
    arrow.zPosition = 1
    addChild(arrow)
    arrowAppear.play()

    let moveToShoot = SKAction.moveTo(CGPoint(x: CGRectGetMidX(self.frame), y: CGRectGetMinY(self.frame) + self.arrow.size.height + 50), duration: 0.2)
    // This is where you run your action with the key
    arrow.runAction(moveToShoot, withKey: "your key")
    SKActionTimingMode.EaseOut  
}

I'm not sure what the SKActionTimingMode.EaseOut is doing, but I'm just going to point that out. I think you need to put that onto the SKAction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM