(Swift SpriteKit) 沿触摸方向旋转精灵
Posted
技术标签:
【中文标题】(Swift SpriteKit) 沿触摸方向旋转精灵【英文标题】:(Swift SpriteKit) Rotate sprite in the direction of touch 【发布时间】:2016-06-24 15:16:26 【问题描述】:在提供的屏幕截图中,红色箭头和十字仅用于演示目的,不在游戏中。我希望飞船的精灵朝向它射出的球的方向。
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)
【问题讨论】:
请提供您的触摸处理和拍摄代码 【参考方案1】:这是我找到的完美运行的代码。
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)
【讨论】:
【参考方案2】:我前段时间一直在做你想要的事情,这是我的结果
首先你需要使用由 Nick Lockwood 创建的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 */
希望对你有帮助
【讨论】:
嗨,我发现另一段代码在两行中完美运行,我将添加答案。【参考方案3】:如果您只想旋转,则不应调用 moveTo 操作。 计算触摸位置与大炮位置之间的角度并调用动作rotateToAngel
这里是代码
let angle = atan2(dy, dx) - CGFloat(M_PI_2)
let direction = SKAction.rotateToAngle(angle, duration: 0.4, shortestUnitArc: true)
cannon.runAction(direction)
【讨论】:
【参考方案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 现在已贬值
【讨论】:
以上是关于(Swift SpriteKit) 沿触摸方向旋转精灵的主要内容,如果未能解决你的问题,请参考以下文章
在 spritekit swift 中触摸节点时没有播放声音