(Swift SpriteKit) Rotate sprite in the direction of touch

前端 未结 4 1433
没有蜡笔的小新
没有蜡笔的小新 2021-02-10 08:06

On the screenshot provided, the red arrow and cross are just for demonstration purposes and are not in the game. I would like the sprite of the spaceship to face the direction o

相关标签:
4条回答
  • 2021-02-10 08:43

    I had been working some time ago in something like what you want so, here is my results

    first you need to use VectorMath.swift created by Nick Lockwood and this is my code to make my spider move towards user touch

    import SpriteKit
    import SceneKit
    
    class GameScene: SKScene {
        let sprite = SKSpriteNode(imageNamed:"Aranna")
        var velocity = Vector2(x: 0, y: 0)
        var positionV2D = Vector2(x: 0, y: 0)
        var headingVector = Vector2(x: 0, y: 1)
    
        override func didMoveToView(view: SKView) {
            /* Setup your scene here */
            let myLabel = SKLabelNode(fontNamed:"Chalkduster")
            myLabel.text = "Hello, World!";
            myLabel.fontSize = 45;
            myLabel.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));
    
            sprite.position = CGPoint(x:CGRectGetMidX(self.frame), y:CGRectGetMidY(self.frame));
            positionV2D = Vector2(point:sprite.position);
    
            let testVector = Vector2(x: 10, y: 14);
            velocity += testVector;
            print(velocity.toString());
            velocity += Vector2(x: 1, y: 1);
            //velocity = velocity + testVector;
            print(velocity.toString());
            velocity *= 0.5;
            velocity.printVector2D();
    
            velocity = Vector2(x: 2, y: 2);
            velocity.normalized();
            velocity.printVector2D();
    
            self.addChild(sprite)
        }
    
    
        func ToRad(grados:CGFloat) ->CGFloat
        {
            return ((CGFloat(M_PI) * grados) / 180.0)
        }
    
        func ToDeg(rad:CGFloat) ->CGFloat
        {
            return (180.0 * rad / CGFloat(M_PI))
        }
    
        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
           /* Called when a touch begins */
    
            for touch in touches {
                let location = touch.locationInNode(self)
    
                let toTarget = Vec2DNormalize(Vector2(point:location) - positionV2D);
    
    
                let angle2 = headingVector.angleWith(toTarget);
    
                print(ToDeg(CGFloat(angle2)));
    
                headingVector.printVector2D();
    
                self.sprite.runAction(SKAction.rotateToAngle(CGFloat(angle2), duration: 0.1))
                self.sprite.runAction(SKAction.moveTo(location, duration: 0.5))
                positionV2D = Vector2(point: location);
    
            }
        }
    
        override func update(currentTime: CFTimeInterval) {
            /* Called before each frame is rendered */
        }
    }
    

    I hope this helps you

    0 讨论(0)
  • 2021-02-10 09:00

    Here is the code I found which works perfectly.

    Rotate a sprite to sprite position not exact in SpriteKit with Swift

     let angle = atan2(location.y - cannon.position.y , location.x - cannon.position.x)
     cannon.zRotation = angle - CGFloat(M_PI_2)
    
    0 讨论(0)
  • 2021-02-10 09:07

    If you want to rotate only you shouldn't call the moveTo action. Calculate the angle between touch location and location of the cannon and call action rotateToAngel

    here is the code

            let angle = atan2(dy, dx) - CGFloat(M_PI_2)
            let direction = SKAction.rotateToAngle(angle, duration: 0.4, shortestUnitArc: true)
            cannon.runAction(direction)
    
    0 讨论(0)
  • 2021-02-10 09:07

    I found that with the answer submitted by James that this caused it to rotate in the wrong way, fine if you have something like a canonball but as it was used on my game which had a mage and a fireball with a trail it caused an issue, this can be easily fixed with

     let angle = atan2(touchlocation.x - cannon.position.x , touchlocation.y - 
     cannon.position.y)
     cannon.zRotation = -(angle - CGFloat(Double.pi/2))
    

    use Double.pi / 2 and M_PI_2 is depriciated now

    0 讨论(0)
提交回复
热议问题