如何在Sprite Kit中实现鼠标连接?

我正在使用Cocos2d + Box2d for iOS编写的拖放function的实现。 我需要将它移植到Sprite Kit。 逻辑是非常基本的:

  • 当用户触摸屏幕时,在手指下find精灵
  • 在find的精灵和场景的物理体之间创build鼠标关节,将关节的目标设置为触摸的位置
  • 当触摸移动时,更新联合的目标到新的位置
  • 当触摸结束时,移除关节

一切工作都很好。 我喜欢触摸结束时模拟物理的方式 – 拖动的形状的速度取决于拖动的速度和方向,所以当我移动精灵的时候,我的手指离开屏幕,它将继续沿相同的方向移动,但是现在受到影响重力和阻尼。

不幸的是,我无法使用Sprite Kit重现相同的效果。 没有像鼠标关节这样的关节,但我尝试过使用其他关节types。 我几乎成功与SKPhysicsJointFixed – 我创build新的精灵和它之间的联合和拖动精灵,当触摸移动我移动新创build的精灵。 不幸的是,它不能像Cocos2d + Box2d中的鼠标关节那样工作 – 拖动精灵时,其速度总是等于零。 所以,每当我把手指从屏幕上移开时,被拖动的精灵就会立即停下来,并受重力影响而开始下坠。 无论拖动手指时移动的速度有多快,释放拖动的形状后,其行为方式都完全相同。

我的问题是如何在Sprite Kit中实现鼠标连接,或者如何实现如上所述的拖放function?

更新:这是一个box2d鼠标联合的例子,可以给你更清晰的视图,我想要使用Sprite Kit实现: http : //blog.allanbishop.com/wp-content/uploads/2010/09/Box2DJointTutorial1.swf

我对iOS开发非常新,所以我想这可能不是最好的方法,但这是我如何解决它,它似乎实际上工作相当顺利。

我正在使用UIPanGestureRecognizer来处理触摸事件。 我在我的didMoveToView:设置了这个didMoveToView:用这个代码:

 UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 

一个UIPanGestureRecognizer被传递给handlePan:如果被触摸停下来,我将使用UIPanGestureRecognizer recognizer.state == UIGestureRecognizerStateEnded检查。 这是我想“释放”对象并“让它飞走”的地方。 为此,我需要计算一些东西,首先我用这个代码得到手指/触摸的速度:

 CGPoint velocity = [recognizer velocityInView:recognizer.view]; 

(当触摸开始时,我使用与其他语句相同的方法( handlePan:来获取正确的对象,并且在移动时通过将对象的位置设置为触摸的位置来始终让对象处于手指之下)

现在我知道速度了,但是我仍然不知道需要多大的力才能应用到物体上。 您应该能够通过以下公式计算力:力=质量*加速度。 我们知道质量(object.physicsBody.mass),我们知道速度。 为了获得加速度,我们还需要时间,因为加速度=速度/时间。

在我update:每当一个新的框架将被渲染的方法,我计算上一次框架即将被渲染的差异之间做这样的事情:

 self.delta = currentTime - self.lastTime; self.lastTime = currentTime; 

我现在可以计算得到物体以速度移动所需要的力,我正在“拖动它”。 为此,我执行以下操作:

 [self.currentNode.physicsBody applyForce:CGVectorMake(velocity.x/self.delta * self.currentNode.physicsBody.mass, -velocity.y/self.delta * self.currentNode.physicsBody.mass)]; 

我把速度除以自上一帧( self.delta )以来的时间差来获得加速度,然后将其与物体的质量相乘以获得保持(或实际获得)物体移动所需的力量方向和速度与我的手指一样。

目前这个function对我很有帮助,我希望它也能帮助其他人,请告诉我是否有问题或者是否有更好的解决scheme。 到目前为止,我还没有find任何“本机解决scheme”。

如果唯一的问题是速度,那么很容易解决。

从上一个触摸位置减去当前的触摸位置,获取最后一次触摸和当前触摸之间的速度。 使用applyForce:将这个速度应用到正文。

为了防止身体在拖动的同时自行移动,请在调用applyForce:之后从体内读出新的速度applyForce:并将其保持在ivar中,并将主体的速度设置为零。

当触摸结束时,将身体的速度设置为您保持为伊娃的速度。

如果这不起作用,请尝试使用applyImpulse:和/或在调用这两种方法之前设置速度,即:

 sprite.physicsBody.velocity = bodyVelocity; [sprite.physicsBody applyForce:touchVelocity]; bodyVelocity = sprite.physicsBody.velocity; sprite.physicsBody.velocity = CGVectorMake(0, 0); 

这样,您可以保持身体的速度,而不会失去对拖拉的控制。