(Swift SpriteKit) Поворот спрайта в направлении касания

На приведенном скриншоте красная стрелка и крестик приведены только для демонстрации и отсутствуют в игре. Я бы хотел, чтобы спрайт космического корабля был направлен в сторону шара, который он стреляет.

Ссылка на изображение

Вот мой текущий код для сенсорного местоположения

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */

    for touch in touches {
        let location = touch.locationInNode(self)

        var bullet = SKSpriteNode(imageNamed: "bullet")
        bullet.position = cannon.position
        bullet.size = CGSize(width: 35, height: 35)

        //physics
        bullet.physicsBody = SKPhysicsBody(circleOfRadius: bullet.size.width/2)
        bullet.physicsBody?.categoryBitMask = PhysicsCategory.bullet
        bullet.physicsBody?.collisionBitMask = PhysicsCategory.enemy
        bullet.physicsBody?.contactTestBitMask = PhysicsCategory.enemy
        bullet.name = "bullet"
        bullet.physicsBody?.affectedByGravity = false

        self.addChild(bullet)

        var dx = CGFloat(location.x - cannon.position.x)
        var dy = CGFloat(location.y - cannon.position.y)

        let magnitude = sqrt(dx * dx + dy * dy)

        dx /= magnitude
        dy /= magnitude

        let vector = CGVector(dx: 120.0 * dx, dy: 120.0 * dy) //adjust constant to increase impluse.

        bullet.physicsBody?.applyImpulse(vector)

        // I found this code bellow this comment, but it just moves the cannon's y position

        let direction = SKAction.moveTo(
            CGPointMake(
                400 * -cos(bullet.zRotation - CGFloat(M_PI_2)) + bullet.position.x,
                400 * -sin(bullet.zRotation - CGFloat(M_PI_2)) + bullet.position.y
            ),
            duration: 0.8)

        cannon.runAction(direction)
    }
}
 A Tyshka24 июн. 2016 г., 17:23
Пожалуйста, предоставьте свой код для сенсорной обработки и съемки

Ответы на вопрос(4)

Я обнаружил, что с ответом, представленным Джеймсом, что это заставило его вращаться неправильно, хорошо, если у вас есть что-то вроде пушечного ядра, но так как это использовалось в моей игре, в которой были маг и огненный шар с следом, это вызвало проблему , это можно легко исправить с помощью

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

используйте Double.pi / 2 и M_PI_2 теперь исключены

Я работал некоторое время назад в чем-то вроде того, что вы хотите, вот мои результаты

сначала вам нужно использоватьVectorMath.swift созданный Ником Локвудом, и это мой код, чтобы заставить моего паука двигаться к прикосновению пользователя

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 */
    }
}

Я надеюсь, это поможет вам

 james24 июн. 2016 г., 18:41
Привет! Я нашел еще один фрагмент кода, который отлично работает в две строки, я добавлю ответ.

Если вы хотите повернуть только, вы не должны вызывать действие moveTo. Рассчитайте угол между расположением касания и местоположением пушки и вызовите действие rotateToAngel

вот код

        let angle = atan2(dy, dx) - CGFloat(M_PI_2)
        let direction = SKAction.rotateToAngle(angle, duration: 0.4, shortestUnitArc: true)
        cannon.runAction(direction)

Вот код, который я нашел, который работает отлично.

Поворот спрайта в положение спрайта не точное в SpriteKit с помощью Swift

 let angle = atan2(location.y - cannon.position.y , location.x - cannon.position.x)
 cannon.zRotation = angle - CGFloat(M_PI_2)

Ваш ответ на вопрос