如何在SpriteKit中将UIGestureRecognizer的速度设置为我的Physicsbody的速度?

时间:2017-11-13 07:00:24

标签: ios iphone swift sprite-kit game-physics

我计算了 UIGestureRecognizer 的速度,我想用它作为SpriteKit中Physicsbody的速度。

我怎么能这样做,因为速度是在接触开始计算并接触结束的方法,而我的物理体被包裹在swipeUp& swipeDown等功能,它们无法访问Speed变量?

这是我的代码:

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)


            }





}

1 个答案:

答案 0 :(得分:0)

所以从像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))