如何在SpriteKit中将UIGestureRecognizer的速度设置为我的物理体的速度?



我计算了UIGestureRecognizer的速度,我想在SpriteKit中将其用作Physicsbody的速度。

我该怎么做,因为速度是在触摸开始和触摸结束方法中计算的,而我的物理身体被包裹在向上滑动和向下滑动等函数中,无法访问速度变量?

这是我的代码:

class GameScene: SKScene, SKPhysicsContactDelegate, SKViewDelegate, UIGestureRecognizerDelegate, UIViewControllerTransitioningDelegate {
    var Kite = SKSpriteNode(imageNamed: "ASC_8025_large.jpg")


@objc let minusButton = SKSpriteNode(imageNamed: "minus.jpg")
@objc let plusButton = SKSpriteNode(imageNamed: "plus.png")
//override init(Kite: SKSpriteNode) {








//For long Long press gesture to work
let longPressGestureRecPlus = UILongPressGestureRecognizer()
let longPressGestureRecMinus = UILongPressGestureRecognizer(target: self, action: #selector(longPressed(press:)))


//First we declare all of our Gestures...
//swipes
let swipeRightRec = UISwipeGestureRecognizer()
let swipeLeftRec = UISwipeGestureRecognizer()
let swipeUpRec = UISwipeGestureRecognizer()
let swipeDownRec = UISwipeGestureRecognizer()
//rotate
let rotateRec = UIRotationGestureRecognizer()
//taps
let tapRec = UITapGestureRecognizer()
let tapRec2 = UITapGestureRecognizer()




override func didMove(to view: SKView) {
    // Get label node from scene and store it for use later


















    Kite.size = CGSize(width: 40.0, height: 40.0)
    Kite.position = CGPoint(x: frame.midX, y: frame.midY)
    plusButton.size =  CGSize(width: 30.0, height: 30.0)
    plusButton.position = CGPoint(x: frame.midX, y: frame.minY + 20.0)
    plusButton.name = "plusButton"
    //plusButton.isUserInteractionEnabled = true
    addChild(Kite)
    addChild(plusButton)

    swipeRightRec.addTarget(self, action: #selector(GameScene.swipedRight) )
    swipeRightRec.direction = .right
    self.view!.addGestureRecognizer(swipeRightRec)
    swipeLeftRec.addTarget(self, action: #selector(GameScene.swipedLeft) )
    swipeLeftRec.direction = .left
    self.view!.addGestureRecognizer(swipeLeftRec)

    swipeUpRec.addTarget(self, action: #selector(GameScene.swipedUp) )
    swipeUpRec.direction = .up
    self.view!.addGestureRecognizer(swipeUpRec)
    swipeDownRec.addTarget(self, action: #selector(GameScene.swipedDown) )
    swipeDownRec.direction = .down
    self.view!.addGestureRecognizer(swipeDownRec)
    //notice the function this calls has (_:) after it because we are passing in info about the gesture itself (the sender)
    rotateRec.addTarget(self, action: #selector (GameScene.rotatedView (_:) ))
    self.view!.addGestureRecognizer(rotateRec)

    // again notice (_:), we'll need this to find out where the tap occurred.
    tapRec.addTarget(self, action:#selector(GameScene.tappedView(_:) ))
    tapRec.numberOfTouchesRequired = 1
    tapRec.numberOfTapsRequired = 1
    self.view!.addGestureRecognizer(tapRec)

    tapRec2.addTarget(self, action:#selector(GameScene.tappedView2(_:) ))
    tapRec2.numberOfTouchesRequired = 1
    tapRec2.numberOfTapsRequired = 2  //2 taps instead of 1 this time
    self.view!.addGestureRecognizer(tapRec2)

   longPressGestureRecPlus.addTarget(self, action: #selector(longPressed(press:)))
   longPressGestureRecPlus.minimumPressDuration = 2.0
   self.view?.addGestureRecognizer(longPressGestureRecPlus)
}
//the functions that get called when swiping...
@objc func swipedRight() {

    print("Right")
    Kite.physicsBody?.velocity = CGVector(dx: 60, dy: 60)
    //Tilts the Kite towards Right
    let tiltRight = SKAction.rotate(toAngle: -1.00, duration: 0.1)
    Kite.run(tiltRight)

}

@objc func swipedLeft() {

    Kite.physicsBody?.velocity = CGVector(dx: -60, dy: 60)
     //Tilts the Kite towards Right
    let tiltLeft = SKAction.rotate(toAngle: 1.00, duration: 0.1)
    Kite.run(tiltLeft)
    print("Left")
}


@objc func swipedUp() {
   Kite.physicsBody?.velocity = CGVector(dx: 60, dy: 60)
    //Straightens the Kite

    let straightens = SKAction.rotate(toAngle: 0.00, duration: 0.1)
    Kite.run(straightens)


    print("Up")
}
@objc func swipedDown() {
   Kite.physicsBody?.velocity = CGVector(dx: 0, dy: -60)

    print("Down")
}

// what gets called when there's a single tap...
//notice the sender is a parameter. This is why we added (_:) that part to the selector earlier
@objc func tappedView(_ sender:UITapGestureRecognizer) {
    let point:CGPoint = sender.location(in: self.view)




    print("Single tap")
    print(point)
}
// what gets called when there's a double tap...
//notice the sender is a parameter. This is why we added (_:) that part to the selector earlier
@objc func tappedView2(_ sender:UITapGestureRecognizer) {
    let point:CGPoint = sender.location(in: self.view)

    print("Double tap")
    print(point)
}
//what gets called when there's a rotation gesture
//notice the sender is a parameter. This is why we added (_:) that part to the selector earlier
@objc func rotatedView(_ sender:UIRotationGestureRecognizer) {
    if (sender.state == .began) {
        print("rotation began")
    }
    if (sender.state == .changed) {
        print("rotation changed")
        //you could easily make any sprite's rotation equal this amount like so...
        //thePlayer.zRotation = -sender.rotation
        //convert rotation to degrees...
        let rotateAmount = Measurement(value: Double(sender.rotation), unit: UnitAngle.radians).converted(to: .degrees).value
        print("(rotateAmount) degreess" )

    }
    if (sender.state == .ended) {
        print("rotation ended")

    }

}
func removeAllGestures(){
    //if you need to remove all gesture recognizers with Swift you can do this....
    for gesture in (self.view?.gestureRecognizers)! {
        self.view?.removeGestureRecognizer(gesture)
    }
    //this is good to do before a SKScene transitions to another SKScene.

}
func removeAGesture()
{
    //To remove a single gesture you can use...
    self.view?.removeGestureRecognizer(swipeUpRec)
}

//Fix the gesture recognizing the plusButton
@objc func longPressed(press: UILongPressGestureRecognizer) {
    if press.state == .began {
        isUserInteractionEnabled = true

        let positionInScene = press.location(in: self.view)
        let touchedNode = self.atPoint(positionInScene)

        plusButton.name = "plusButton"
       Kite.physicsBody?.velocity = CGVector(dx: 0, dy: 60.0*3)

        print("Pressed on the screen")

        if let name = touchedNode.name {
            if name == "plusButton" {
                print("LONG TAPPED")

            }
        }
    }

}

var start: CGPoint?
var startTime: TimeInterval?

 var taps = 0
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    print("Began")
    Kite.physicsBody = SKPhysicsBody(rectangleOf: Kite.size)
    Kite.physicsBody?.affectedByGravity = false
    //Kite.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
    Kite.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 5))
    plusButton.name = "plusButton"
    plusButton.isUserInteractionEnabled = false

    //We figure how to interact with BUTTON in Spritekit
    let touch = touches.first
    let positionInScene = touch!.location(in: self)
    let touchedNode = self.atPoint(positionInScene)

    if let name = touchedNode.name {
        if name == "plusButton" {

            taps +=  1

            Kite.size = CGSize(width: 200, height: 200)
            print("tapped")
            print("Taps", taps)
    }
    }

    for touch in touches {
        let location:CGPoint = touch.location(in: self.view!)
        start = location
        startTime = touch.timestamp

    }





}


    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        print("Ended")

        //Calculating Speed of the Gestures
        for touch in touches {
            let location:CGPoint = touch.location(in: self.view!)
            var dx:CGFloat = location.x - start!.x;
            var dy:CGFloat = location.y - start!.y;
            var magnitude:CGFloat = sqrt(dx*dx+dy*dy)
            //Calculate Time
            var dt:CGFloat = CGFloat(touch.timestamp - startTime!)
            //Speed = Distance / Time
            var speed:CGFloat = magnitude / dt
            var speedX:CGFloat = dx/dt
            var speedY:CGFloat = dy/dt
            print("SpeedY", speedX)
            print("SpeedY", speedY)

            }


}

因此从 dx 和 dy 等向量计算速度是

let speed = sqrtf(Float(pow(dx!, 2) + pow(dy!, 2)))

因此,如果要将速度作为速度应用于对象,则至少需要一个方向。

let newDx = 0 // means in no x direction
// next you can change the formula to your new dy to match the given speed
let newDy = sqrtf(pow(speed, 2) - Float(pow(newDx, 2)))
yourNode.physicsBody?.velocity = CGVector(dx: newDx, dy: CGFloat(newDy))

最新更新