1
votes

I am working on a simple runner game, I have just 3 shapenodes a player node which is just a shapenode (redbox, 30 x 30) with left/right buttons basically two shapenodes.

I have managed to set flags and increment player node's position X and move it left and right with buttons in touchesBegan method and stop the movement in touchesEnded method everything works fine.

The problem is that if I touch lets say right button, the player moves to the right as expected. But if I touch and move my finger out of the button boundaries in any direction, the player keeps moving constantly as long as I touch that button again then it stops. Otherwise it keeps moving and the other button does not stop it as well.

I used touchesMoved method to stop the movement of the player when I move my finger but this does not fix the issue since touchesMoved method triggers with the slightest movement of the touch even when my finger slightly shakes. I want the touchesMoved method called when my finger is moved off the button, not on the button.

How can I stop the movement of a sprite when touched and moved out of the node ( button ) boundaries?

2

2 Answers

0
votes

You have 3 touch events:

  • touchesBegan; check if user tap is on one the move buttons (if yes - move player, if not - return)
  • touchesMoved; check if the user tap is still inside the boundaries of the move button (if yes - continue moving player, if not - stop movement)
  • touchesEnded; stop player movement

You can solve your problem by checking if the user finger is over the button area.

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?)
{
    // nothing here

    let touch = touches.first
    let position_in_scene = touch!.location(in: self)

    check_button(position: position_in_scene)
}

func check_button(position : CGPoint)
{

    if right_button.contains(position)
    {
        // the tap was inside button boundaries
        player.move_left()
    }
    else
    {
        // the tap was outside button boundaries
        player.stop()
    }
}
0
votes

I have this code running :

class GameScene: SKScene {

var player = SKSpriteNode()
var left = SKSpriteNode()
var right = SKSpriteNode()
var jumpbtn = SKSpriteNode()
var leftbtnPressed = false
var rightbtnPressed = false
var jump = false
var hSpeed: CGFloat = 2.0


override func didMove(to view: SKView) {

    let border = SKPhysicsBody(edgeLoopFrom: self.frame)
    border.friction = 0
    self.physicsBody = border

    jumpbtn = self.childNode(withName: "jumpbtn") as! SKSpriteNode
    player = self.childNode(withName: "r1") as! SKSpriteNode
    left = self.childNode(withName: "leftbtn") as! SKSpriteNode
    right = childNode(withName: "rightbtn") as! SKSpriteNode


}//didmove to view


func moveRight(){
    player.position = CGPoint(x: player.position.x + hSpeed, y: player.position.y)
}
func moveLeft (){
    player.position = CGPoint(x: player.position.x - hSpeed, y: player.position.y)
}

func movement (){
    if rightbtnPressed == true {
        moveRight()
    }
    if leftbtnPressed == true {
        moveLeft()
    }
}//movement


func CheckButton(position : CGPoint) {
    if right.contains(position){
        rightbtnPressed = true
    }
    if left.contains(position) {
        leftbtnPressed = true
    }
    else {
        leftbtnPressed = false
        rightbtnPressed = false
    }

}// checkbutton


func jumping (){
    if jump == true {
        player.physicsBody?.applyImpulse(CGVector(dx:0, dy: 5.0))
    }
}// jumping


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {
        let positionINScene = touch.location(in: self)
        let touchednode = self.atPoint(positionINScene).name

        if touchednode == "rightbtn"{
            rightbtnPressed = true
        }
        if touchednode == "leftbtn"{
            leftbtnPressed = true
        }
        if touchednode == "jumpbtn"{
            jump = true
            jumping()  
        }  
    }
}//touchesbegan


override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    let touch = touches.first
    let positionInScene = touch?.location(in: self)

    CheckButton(position: positionInScene!)
}


override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    for touch in touches {
        let positionINScene = touch.location(in: self)
        let touchednode = self.atPoint(positionINScene)

        if touchednode.name == "rightbtn"{
            rightbtnPressed = false
        }
        if touchednode.name == "leftbtn"{
            leftbtnPressed = false
        }
        if touchednode.name == "jumpbtn" {
            jump = false
        }
    }
}//touchesEnded

override func update(_ currentTime: TimeInterval) {
    movement()

}

When i touch either left or right button the player starts moving as expected but the problem is while the player is moving let say to the right if i touch the jump button the player pauses moving where it should be moving and jumping in simple words i can not move and jump at the same time