touchesBegan, "Одновременное нажатие", Multi touch, интерфейс на SpriteKit

swift
xcode
spritekit

#1

Две недели изучаю свифт и за неделю уже такую игруху забабахал. Ну, все я настоящий программист. Кинул на лапу 99$ … подключаю айпад (ну, целый день подключал) и вот…

Одновременное нажатие не работает как быть?
Есть ‘нод’ и две кнопки (спрайтовые) синяя и красная, одна поворачивает нод другая запускает его вверх. Здорово!
Внизу, код описывающий то, как у меня устроено управление в проекте. Можете запустить его только гравитацию выставьте -0.8 или около того.
-может я ваще не так делаю эти элементы управления (кнопки)?

class GameScene: SKScene {
    
    let node = SKShapeNode(rectOf: CGSize(width: 100, height: 100))
   
    var timer: Timer?
    var timer2: Timer?
    
    var btnImpulse: SKNode!
    var btnLocationImpulse: CGPoint!
    var btnTurnRight: SKNode!
    var btnLocationTurnRight: CGPoint!
    
    var rot: SKAction!
    
    override func didMove(to view: SKView) {
        physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
        node.physicsBody = SKPhysicsBody(rectangleOf: node.frame.size)
        node.position.y = -(scene!.frame.height / 2 - node.frame.size.height / 2)
        addChild(node)
        btnImpulse = SKSpriteNode(color: SKColor.red, size: CGSize(width: 100, height: 100))
        btnImpulse.position = CGPoint(x: 100, y: -100)
        addChild(btnImpulse)
        btnTurnRight = SKSpriteNode(color: SKColor.blue, size: CGSize(width: 100, height: 100))
        btnTurnRight.position = CGPoint(x: -100, y: -100)
        addChild(btnTurnRight)
        rot = SKAction.rotate(byAngle: 0.8, duration: 1)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            btnLocationImpulse = touch.location(in: self)
            btnLocationTurnRight = touch.location(in: self)
            
            if btnImpulse.contains(btnLocationImpulse){
                timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                    self.node.physicsBody!.applyImpulse(CGVector(dx: 0, dy: 10))
                }
            } else if btnTurnRight.contains(btnLocationTurnRight){
                timer2 = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                self.node.run(self.rot)     
                }
            }
        }
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        timer?.invalidate()
        timer = nil
        timer2?.invalidate()
        timer2 = nil
    }
 }

#2

Пробуйте так:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        
        if btnImpulse.contains(location) {
            timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                self.node.physicsBody!.applyImpulse(CGVector(dx: 0, dy: 10))
            }
        } else if btnTurnRight.contains(location) {
            timer2 = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                self.node.run(self.rot)
            }
        }
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        
        if btnImpulse.contains(location) {
            timer?.invalidate()
            timer = nil
        } else if btnTurnRight.contains(location) {
            timer2?.invalidate()
            timer2 = nil
        }
    }
}

#3

Спасибо, работает
Только иногда случаются залипания , будто постоянно кнопка нажата :confused: ?


#4

В симуляторе :confused: ?


#5

На железе
Понял ! как это происходит!
когда два пальца на одну кнопку жмешь тогда происходит залипание


#6

Наверно так:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        
        if btnImpulse.contains(location) && timer == nil {
            timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                self.node.physicsBody!.applyImpulse(CGVector(dx: 0, dy: 10))
            }
        } else if btnTurnRight.contains(location) && timer2 == nil {
            timer2 = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
                self.node.run(self.rot)
            }
        }
    }
}

#7

В примере выше все получилось но у меня в проекте 3 кнопки :kissing: и две из них поверх одной большой(выступает в качестве всей сенсорной области экрана), при нажатии на одну из них двумя пальцами залипает та которая под ними
Ну ладно не буду вас беспокоить , придется изменять расположение итерфейса и кнопок
Спасибо за все:+1:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            if interface.btnTurnLeft.contains(location) && plauer.timerLeft == nil && plauer.timerRight == nil{
                plauer.rotateLeft()
            } else if interface.btnTurnRight.contains(location) && plauer.timerRight == nil && plauer.timerLeft == nil {
                plauer.rotateRight()
            } else if interface.btnImpulse.contains(location) && plauer.timerTouches == nil {
                plauer.touchesBegan()
            } 
        }
    }