Действие при удержании пальца на экране

swift3

#1

В общем нужно заставит объект ship двигаться при удержании пальца! на экране, пока не отпустишь. Я уже и touchesBegan/Ended и всякие условия и циклы с ним пробывал, хотя touchesMoved выполняет то что я хочу , но это когда пальцем елозишь по экрану, а нужно, чтоб нажал и не отпускаешь. Вроде есть некий UILongPressGestureRecognizer … но куда его?
Вы уж простите нуба

class GameScene: SKScene, SKPhysicsContactDelegate {

var ship: SKSpriteNode!

override func didMove(to view: SKView) {
    ship = childNode(withName: "ship") as! SKSpriteNode
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    ship.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 50))
}

}


#2

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

class GameScene: SKScene {
    
    private let node = SKShapeNode(rectOf: CGSize(width: 100, height: 100))
    
    override func didMove(to view: SKView) {
        addChild(node)
        node.position.y = -(scene!.frame.height / 2 - node.frame.size.height / 2)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        let action = SKAction.repeatForever(SKAction.moveBy(x: 0, y: 100, duration: 1))
        node.run(action, withKey: "Action")
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        node.removeAction(forKey: "Action")
    }
}


#3

Ну, SKAction.repeatForever что-то умеет, видимо я не умею им пользоваться

class GameScene: SKScene {
    var ship: SKSpriteNode!

override func didMove(to view: SKView) {
    ship = childNode(withName: "ship") as! SKSpriteNode
    ship.physicsBody?.affectedByGravity = true
    physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let action = SKAction.repeatForever(SKAction.applyImpulse(CGVector(dx: 0, dy: 400), duration: 0.0001))
    ship.run(action, withKey: "Action")
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    ship.removeAction(forKey: "Action")
    }
 }

Короче, объект дергается вверх вниз, игрался я с параметрами, еще больше стал дергаться.
Но прогресс есть, выполняет действие пока не отпустишь палец!
SKAction.applyAngularImpulse(…) забористая вещь, от нее объект носится по всему экрану, как умалешенный :slight_smile:


#4

Дергается потому что его гравитация вниз тянет, если у вас ship как бы летит над чем-то, поставьте гравитацию в ноль:

override func didMove(to view: SKView) {
    physicsWorld.gravity = CGVector(dx: 0, dy: 0)
}

#5

Дак, в этом и фишка, объект потихоньку падает(gravity -0.3), при нажатии он получает ‘толчок’ и по инерции летит вверх а потом теряет скорость и снов вниз падает.


#6

Проще по таймеру тогда:

class GameScene: SKScene {
    
    private let node = SKShapeNode(rectOf: CGSize(width: 100, height: 100))
    private var timer: Timer?
    
    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)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { _ in
            self.node.physicsBody!.applyImpulse(CGVector(dx: 0, dy: 100))
        }
    }
    
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        timer?.invalidate()
        timer = nil
    }
}

#7

Вот Спасибо тебе огромное
Я 3 дня ломал голову. То же пытался таймер использовать но знаний не хватило, ладно , буду учить основы.