2016-06-24 5 views
2

На снимке экрана красная стрелка и крест предназначены только для демонстрации и не находятся в игре. Я хотел бы, чтобы спрайт космического корабля был направлен в сторону шара, который он стреляет.(Swift SpriteKit) Поворот спрайта в направлении касания

Link to image

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

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) 
    } 
} 
+0

Введите код F или касание и стрельба –

ответ

3

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

enter image description here

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

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

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

+0

Привет Там Я нашел еще немного кода, который отлично работает в двух строках, я добавлю ответ. – james

1

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

здесь код

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

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

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 является depriciated Теперь

Смежные вопросы