使用Swift中的SpriteKit将精灵旋转到与精灵位置不完全匹配的位置

5

我正在尝试通过触摸来旋转一个玩家。使用touches move函数,我将位置设置为变量,然后调用一个函数。它可以工作,但是角度不正确。位置是全局变量,player是我想要旋转的精灵。它大约偏差15度。

   func rotatePlayer(){

     let angle = atan2(location!.y - player!.position.y , location!.x - player!.position.x)
    player?.zRotation = angle
}

1
zRotation为0时,你的玩家面向哪个方向? - 0x141E
这是默认的太空飞船,机头朝上。zRotation为0。 - paralaxbison
3个回答

2
根据SpriteKit最佳实践文档,使用与SpriteKit协调的游戏逻辑和艺术资源,这意味着将艺术品向右定位。如果您将艺术品定位到其他方向,则需要在艺术品使用的约定和SpriteKit使用的约定之间转换角度。
由于默认的太空飞船指向上方(当zRotation为0时),因此您需要将角度偏移90度(pi/2弧度),以便当zRotation为零时,飞船面向右侧。
player?.zRotation = angle - CGFloat(M_PI_2)

或者,您可以将宇宙飞船向右旋转。要旋转图像,请单击Assets.xcassets,然后单击Spaceship。右键单击Spaceship图像,选择“在外部编辑器中打开”菜单项。这将在预览应用程序中打开图像。在预览中,选择工具>向右旋转并退出预览。通过旋转艺术作品,您的代码应该可以正常工作,而无需进行任何更改。


1
尝试这样做:
//set sprite to image



Person = SKSpriteNode(imageNamed: "Person")




    //set size
    Person.size = CGSize(width: 40, height: 7)



    //set position
    Person.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 + 120)





    //rotate node 3.14 / 2 = to 90 degree angle
    Person.zRotation = 3.14 / 2



    Person.zPosition = 2.0

0
使用方向约束将您的对象旋转到触摸位置:
// Create two global Sprite properties:

var heroSprite = SKSpriteNode(imageNamed:"Spaceship")
var invisibleControllerSprite = SKSpriteNode()

override func didMoveToView(view: SKView) {         

   // Create the hero sprite and place it in the middle of the screen
   heroSprite.xScale = 0.15
   heroSprite.yScale = 0.15
   heroSprite.position = CGPointMake(self.frame.width/2, self.frame.height/2)
   self.addChild(heroSprite)

   // Define invisible sprite for rotating and steering behavior without trigonometry
   invisibleControllerSprite.size = CGSizeMake(0, 0)
   self.addChild(invisibleControllerSprite)

   // Define a constraint for the orientation behavior
   let rangeForOrientation = SKRange(constantValue: CGFloat(M_2_PI*7))

   heroSprite.constraints = [SKConstraint.orientToNode(invisibleControllerSprite, offset: rangeForOrientation)]

}

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    /* Called when a touch begins */        
    for touch: AnyObject in touches {

        // Determine the new position for the invisible sprite:
        // The calculation is needed to ensure the positions of both sprites 
        // are nearly the same, but different. Otherwise the hero sprite rotates
        // back to it's original orientation after reaching the location of 
        // the invisible sprite
        var xOffset:CGFloat = 1.0
        var yOffset:CGFloat = 1.0
        var location = touch.locationInNode(self)
        if location.x>heroSprite.position.x {
            xOffset = -1.0
        }
        if location.y>heroSprite.position.y {
            yOffset = -1.0
        }

        // Create an action to move the invisibleControllerSprite. 
        // This will cause automatic orientation changes for the hero sprite
        let actionMoveInvisibleNode = SKAction.moveTo(CGPointMake(location.x - xOffset, location.y - yOffset), duration: 0.2)
        invisibleControllerSprite.runAction(actionMoveInvisibleNode)

        // Optional: Create an action to move the hero sprite to the touch location
        let actionMove = SKAction.moveTo(location, duration: 1)
        heroSprite.runAction(actionMove)

    }

}

教程:http://stefansdevplayground.blogspot.de/2014/11/how-to-implement-space-shooter-with.html

视频:https://youtu.be/8d8MH_gXt84


我已经在我的回答中更新了示例代码,提供了一个更简单的解决方案。 - Stefan
我们真的需要使用约束吗?我们能否准确地找到角度并自动设置玩家的角度? - paralaxbison
我认为这也是可能的。但我不知道怎么做。我和你有同样的问题,放弃了计算方法。 - Stefan
我的代码加上所选答案确实可以工作。而且代码量也少了很多。 - paralaxbison

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接