我创建了一个iOS应用程序,我需要能够同时移动,旋转和缩放精灵(我正在使用Apple的Sprite Kit)。在大多数情况下,我有这个工作。我目前可以用1个手指触摸并移动精灵,如果我用两个手指,我可以缩放和旋转精灵。为此,我使用UIPanGestureRecognizer,UIPinchGestureRecognizer和UIRotateGestureRecognizer。这很好。我想要的是,当我拖动时,用右手旋转和缩放一个精灵,我可以用左手拖动旋转并缩放另一个精灵,与其他精灵无关。
目前我正在使用iOS手势来移动,旋转和缩放精灵。我使用的代码非常接近我在Ray Wenderlich的网站上发现的Sprite Kit的Drag and Drop Sprites教程。 http://www.raywenderlich.com/44270/sprite-kit-tutorial-how-to-drag-and-drop-sprites。当我开始使用UIPanGestureRecognizers而不仅仅是触摸方法时,我正在使用的部分接近底部。
就像我说的那样,手势一次可以在一个精灵上正常工作。如何使它在多个精灵上工作?
例如,对于UIPanGesturRecognizer,我添加以下代码:
- (void)didMoveToView:(SKView *)view {
UIPanGestureRecognizer *gestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
[[self view] addGestureRecognizer:gestureRecognizer];
}
然后我有一个名为gestureRecognizer的方法:
- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {
if (recognizer.state == UIGestureRecognizerStateBegan) {
CGPoint touchLocation = [recognizer locationInView:recognizer.view];
touchLocation = [self convertPointFromView:touchLocation];
[self selectNodeForTouch:touchLocation]; // This just returns the node that has been touched
} else if (recognizer.state == UIGestureRecognizerStateChanged) {
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) {
[_selectedNode removeAllActions];
}
}
最后有一个移动精灵的方法:
- (void)panForTranslation:(CGPoint)translation {
if([[_selectedNode name] isEqualToString:kAnimalNodeName]) {
CGPoint position = [_selectedNode position];
// Set variable for the point to move selected node
CGPoint movePoint = CGPointMake(position.x + translation.x, position.y + translation.y);
[_selectedNode setPosition:newPos];
}
}
现在示例代码仅显示了UIPanGestureRecognizer的方法,但我也有类似的旋转和捏合手势方法。所有这些代码都在我的场景类中。
感谢您的帮助。
答案 0 :(得分:1)
好吧,你发布的教程几乎说明了如何做到这一点......
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint positionInScene = [touch locationInNode:self];
[self selectNodeForTouch:positionInScene];
}
- (void)selectNodeForTouch:(CGPoint)touchLocation {
//The below statement assigns touchedNode from a sprite that contains touchLocation
SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:touchLocation];
//2
if(![_selectedNode isEqual:touchedNode]) {
[_selectedNode removeAllActions];
[_selectedNode runAction:[SKAction rotateToAngle:0.0f duration:0.1]];
_selectedNode = touchedNode;
//the below if statement determines what SKNode is to be given a SKAction
if([[touchedNode name] isEqualToString:kAnimalNodeName]) {
SKAction *sequence = [SKAction sequence:@[[SKAction rotateByAngle:degToRad(-4.0f) duration:0.1],
[SKAction rotateByAngle:0.0 duration:0.1],
[SKAction rotateByAngle:degToRad(4.0f) duration:0.1]]];
[_selectedNode runAction:[SKAction repeatActionForever:sequence]];
}
}
}
因此,如果要将操作应用于多个节点,只需为它们指定相同的名称即可。我建议命名你的节点,将它们放在一个数组中,然后迭代它们检查它们是否具有相同的名称。 如果您有任何其他问题,请发表评论。
更新:1
- (void)panForTranslation:(CGPoint)translation {
//Once again you would do the same thing. Just give the nodes the same name.
if([[_selectedNode name] isEqualToString:kAnimalNodeName]) {
CGPoint position = [_selectedNode position];
// Set variable for the point to move selected nodes
CGPoint movePoint = CGPointMake(position.x + translation.x, position.y + translation.y);
[_selectedNode setPosition:newPos];
}
答案 1 :(得分:0)
我也在使用该教程做类似的事情。示例代码依赖于实例变量selectedNode
,该变量表示所选的一个节点。
为了使这个工作适用于多个节点,我建议使用NSMutableArray
selectedNodes或子类化SKSpriteNode
来存储它当前是否已“选中”。祝你好运!