我正在查看this drag and drop tutorial by Ray Wenderleich,它允许在屏幕上拖动精灵,但是,没有重力,并且一旦用户抬起手指,精灵就会被固定到位。
与此同时looking at this SpriteKit collision demo by Apple,它在对象之间发生了碰撞。
然后有this tutorial which shows how to apply impulse to sprites.
我将演示组合在一起,所以我的场景有重力,边缘碰撞和弹跳,但拖放代码仍然没有惯性。
如何将拖放行为修改为"拖放"对于精灵?我正在寻找类似于滚动视图中的视图的行为 - 加速度,减速度和惯性。
下面的代码有两种模式 - 轻弹,将脉冲应用于精灵,拖动,改变精灵的位置。我不确定如何将两个代码路径组合到
- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {
CGPoint touchLocation = [recognizer locationInView:recognizer.view];
touchLocation = [self convertPointFromView:touchLocation];
if (recognizer.state == UIGestureRecognizerStateBegan) {
[self selectNodeForTouch:touchLocation];
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
SKNode* node = [self selectNodeForTouch:touchLocation];
//this is the flick gesture - pings the
double angle = atan2(touchLocation.y-node.position.y,touchLocation.x-node.position.x);
[node.physicsBody applyImpulse:CGVectorMake(20*cos(angle), 20*sin(angle))];
//CGPoint translation = [recognizer translationInView:recognizer.view];
// translation = CGPointMake(translation.x, -translation.y);
// [self panForTranslation:translation];
// [recognizer setTranslation:CGPointZero inView:recognizer.view];
} else if (recognizer.state == UIGestureRecognizerStateEnded) {
}
}
这是拖放代码:
- (void)panForTranslation:(CGPoint)translation {
CGPoint position = [_selectedNode position];
if([[_selectedNode name] isEqualToString:kAnimalNodeName]) {
[_selectedNode setPosition:CGPointMake(position.x + translation.x, position.y + translation.y)];
} else {
CGPoint newPos = CGPointMake(position.x + translation.x, position.y + translation.y);
[_background setPosition:[self boundLayerPos:newPos]];
}
}
答案 0 :(得分:0)
当pan识别器将状态更改为结束时,您需要应用脉冲。在拖动过程中使物理体静止也是个好主意。最好的地方是touchesBegan,因为它是最快的。这是我在swift中的代码示例。
func handlePan(panGestureRecognizer recognizer:UIPanGestureRecognizer) {
let touchLocationView = recognizer.location(in: recognizer.view)
let touchLocationScene = self.convertPoint(fromView: touchLocationView)
switch recognizer.state {
case .began:
let canditateNode = self.touchedNode(touchLocationScene)
if let name = canditateNode.name, name.contains(kMovableNode) {
self.selectedNode = canditateNode
}
case .changed:
let translation = recognizer.translation(in: recognizer.view)
if let position = self.selectedNode?.position {
self.selectedNode?.position = CGPoint(x: position.x + translation.x, y: position.y - translation.y)
recognizer.setTranslation(CGPoint.zero, in: recognizer.view)
}
case .ended:
self.selectedNode?.physicsBody?.isDynamic = true;
let velocity = recognizer.velocity(in: recognizer.view)
self.selectedNode?.physicsBody?.applyImpulse(CGVector(dx: velocity.x, dy: -velocity.y))
self.selectedNode = nil
default:
break
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
NSLog("touchesBegan")
if let touch = touches.first {
let touchLocationScene = touch.location(in: self)
let canditateNode = self.touchedNode(touchLocationScene)
if let name = canditateNode.name, name.contains(kMovableNode) {
self.selectedNode = canditateNode
self.selectedNode?.physicsBody?.isDynamic = false
}
}
}