更新:
我已经解决了这个问题,并且找到了一个比提供答案更简单的方法。我的解决方案是使SPACESHIP的速度等于从手指触摸到的距离。为了加快运动速度,可以将该速度乘以一个常数。在这种情况下,我使用了16。我还摆脱了在touchesEnd事件中将lastTouch设置为nil的问题。这样,即使我松开手指,船仍会停下来。
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
if let touch = lastTouch {
myShip.physicsBody.velocity = CGVector(dx: (lastTouch!.x - myShip.position.x) * 16, dy: 0)
}
}
===============================
我有一个SPACESHIP节点,其运动仅限于X轴。当用户在屏幕上的某个位置按下并按住时,我希望SPACESHIP能够移动到手指的x坐标,而不希望在松开手指之前不停止向手指移动。如果“空格键”靠近用户的手指并且用户的手指仍被按下,则希望它逐渐减速并停止。我还希望当SPACESHIP改变方向,开始和停止时应用这种平滑运动。
我正在尝试找出最佳方法。
到目前为止,我已经创建了节点并且它可以正确移动,但是存在一个问题:如果我按下屏幕并按住不放,船最终将越过我的手指并继续移动。这是因为仅当我移动手指时才会触发更改船方向的逻辑。因此,基本上,将我的手指移到船上以改变船的方向是可行的,但如果船越过我的静止指头,则不会改变方向
我需要SPACESHIP节点来识别它何时越过我的静止手指,并根据其与我手指的接近程度来更改其方向或停止。
以下是相关代码:
第1部分: 当用户按下时,找出触摸来自何处,并使用速度相应地移动myShip(SPACESHIP)
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
/* Called when a touch begins */
let touch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
if (touchLocation.x < myShip.position.x) {
myShip.xVelocity = -200
} else {
myShip.xVelocity = 200
}
}
第2部分: 当用户移动手指时,触发一个事件,检查该手指是否现在已移至船的另一侧。如果是这样,请更改船的方向。
override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
let touch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
//distanceToShip value will eventually be used to figure out when to stop the ship
let xDist: CGFloat = (touchLocation.x - myShip.position.x)
let yDist: CGFloat = (touchLocation.y - myShip.position.y)
let distanceToShip: CGFloat = sqrt((xDist * xDist) + (yDist * yDist))
if (myShip.position.x < touchLocation.x) && (shipLeft == false) {
shipLeft = true
myShip.xVelocity = 200
}
if (myShip.position.x > touchLocation.x) && (shipLeft == true) {
shipLeft = false
myShip.xVelocity = -200
}
}
第3部分: 当用户从屏幕上松开手指时,我希望飞船停止移动。
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
myShip.xVelocity = 0
}
第4部分 更新事件,更改船的位置
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
let rate: CGFloat = 0.5; //Controls rate of motion. 1.0 instantaneous, 0.0 none.
let relativeVelocity: CGVector = CGVector(dx:myShip.xVelocity - myShip.physicsBody.velocity.dx, dy:0);
myShip.physicsBody.velocity = CGVector(dx:myShip.physicsBody.velocity.dx + relativeVelocity.dx*rate, dy:0);
感谢您的阅读,并期待得到答复!
使用以下命令可以为您省去很多麻烦myShip.physicsBody.applyImpluse(vector)
。它的工作方式就像您myShip
在方向vector
点上施加了推力一样。如果您计算的vector
是从上次触摸位置到的x距离myShip
,则它会加速,减速,改变方向等。与您描述的方式非常接近,因为它只会在正确的方向上进行少量推动每个update
。
基本上,您存储了最后一次触摸的位置,然后在update
函数中计算了CGVector
从myShip
到的指向,lastTouch
并将其作为对物理身体的冲动。
就像是:
var lastTouch: CGPoint? = nil
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
}
override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) {
let touch = touches.anyObject() as UITouch
let touchLocation = touch.locationInNode(self)
lastTouch = touchLocation
}
// Be sure to clear lastTouch when touches end so that the impulses stop being applies
override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) {
lastTouch = nil
}
override func update(currentTime: CFTimeInterval) {
// Only add an impulse if there's a lastTouch stored
if let touch = lastTouch {
let impulseVector = CGVector(touch.x - myShip.position.x, 0)
// If myShip starts moving too fast or too slow, you can multiply impulseVector by a constant or clamp its range
myShip.physicsBody.applyImpluse(impulseVector)
}
}
您可能还想使用linearDamping
和的angularDamping
值myShip.physicsBody
。它们将帮助确定myShip
加速和减速的速度。
我最大化了1.0
我的应用程序中的值:
myShip.physicsBody.linearDamping = 1.0
myShip.physicsBody.angularDamping = 1.0
如果myShip
不能足够快地停止,您还可以尝试对update
函数进行一些中断:
override func update(currentTime: CFTimeInterval) {
// Only add an impulse if there's a lastTouch stored
if let touch = lastTouch {
let impulseVector = CGVector(touch.x - myShip.position.x, 0)
// If myShip starts moving too fast or too slow, you can multiply impulseVector by a constant or clamp its range
myShip.physicsBody.applyImpluse(impulseVector)
} else if !myShip.physicsBody.resting {
// Adjust the -0.5 constant accordingly
let impulseVector = CGVector(myShip.physicsBody.velocity.dx * -0.5, 0)
myShip.physicsBody.applyImpulse(impulseVector)
}
}
问题内容: 模拟器显示节点数,即有2个节点。但是为什么呢?由于只有一个var(ball)。有没有一种方法可以创建一个圆而不使它成为两个节点。 问题答案: 这是因为设置了SKShapeNode 。显然,设置或时,它们每个都需要附加的节点和附加的绘制过程。默认情况下,已经设置了strokeColor(一个节点,一个绘制过程),并且由于另外设置了,因此要渲染形状需要两个节点(和两个绘制过程)。 由于明显
问题内容: 我试图弄清楚如何确定一个节点在屏幕上还是屏幕外可见。这仅仅是节点的true / false属性吗?谢谢。(使用swift spritekit) 问题答案: 您可以使用以下命令测试场景中是否有节点: 假设这是一个子类,例如。
Swift-SpriteKit-Analog-Stick 虚拟操纵杆 (Swift+Sprite Kit)。
我在馆长2.12.0中使用动物园管理员。 通过使用watcher调用getChildren(我事先不知道完整的节点路径),我成功地监视了新节点,watcher再次提交任务以调用getChildren with watcher。现在我想看节点移除和仅移除。我打电话给守望者。但如果节点由于某种原因不存在,它实际上将是节点创建的观察者,在我的例子中,这是永远不会发生的。因此,我将留下越来越多的“鞭打”观
问题内容: 我正在迅速进行一个项目,并且能够制作精灵。我试图在许多不同的地方制作精灵。作为测试,我将游戏场景中的代码替换为: 我不明白的是,这段代码在左下角产生了一个精灵。正如预期的那样,在y方向上仅显示了一半的精灵,但是x方向似乎完全偏离了。如果我尝试将x值设置为289以下的任何数字,它将不会出现。0,0点真的是289,0还是我缺少什么?我正在为iPhone 6编程,如果有所作为。 谢谢! 问题
问题内容: 如图所示,该图是从y = 0行开始的,这里我想从 y = 50开始绘制一个图,如何在JFreeChart?中指定呢? 这是一些代码: 问题答案: 您可以使用 ValueAxis类的setLowerBound()方法指定Y轴的底部值。 使用您的示例: