我的SpriteKit游戏中有一个玩家对象,目前我正在使用以下代码移动它:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if (touches.count == 1)
{
[self touchesMoved:touches withEvent:event];
}
}
-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
if (touches.count == 1)
{
[_player runAction:[SKAction moveTo:[[touches anyObject] locationInNode:self] duration:0.01]];
}
}
但我只想在触摸位于该位置的特定范围内时移动播放器节点。
答案 0 :(得分:3)
由于看起来您只关心触摸与_player
对象的距离,我会将半径检测逻辑移动到您的_player
对象并使用SKRegion
来处理它
注意: 如果您需要知道触摸是否在多个节点的半径范围内,那么您可能希望使用this question中的方法。
要使用SKRegion
确定您的触摸是否在_player
的某个半径范围内,请在SKRegion
对象中添加_player
实例并使用半径初始化它你要。在[_player init]
或其对您的项目最有意义的地方:
self.touchRegion = [[SKRegion alloc] initWithRadius:radius];
然后添加一个方法来确定某个点是否在该区域内:
- (BOOL)pointIsInTouchRegion:(CGPoint)point {
return [self.touchRegion containsPoint: point];
}
接下来将您的touchesMoved
方法更改为:
-(void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
if (touches.count == 1)
{
UITouch *touch = [touches anyObject];
CGPoint point = [self locationInNode:_player]; // NOTE: It's important to use _player here!
if ([_player pointIsInTouchRegion: point]) {
[_player runAction:[SKAction moveTo:[[touches anyObject] locationInNode:self] duration:0.01]];
}
}
}
注意: 在_player
中使用[self locationInNode:_player];
至关重要,因为您的SKRegion
将在_player
节点的坐标系中定义。
还有一点需要注意:你不必将所有逻辑放在_player
中,这就是我的方式。您可以轻松地将SKRegion
存储在场景的类中,并直接在其上调用[region containsPoint: point]
。
更新:iOS 7方法
在iOS 7中执行此操作的主要区别在于,您需要存储您感兴趣的实际半径而不是SKRegion
(因为它仅在iOS 8中可用),然后自己进行计算在pointIsInTouchRegion:
。
因此,在_player
中,设置您之前设置touchRegion
的触摸半径:
self.touchRadius = radius
然后更改pointIsInTouchRegion:
方法,使其进行实际距离计算。
- (BOOL)pointIsInTouchRegion:(CGPoint)point {
CGPoint centerOfNode = CGPointMake(self.frame.size.width / 2.0, self.frame.size.height / 2.0); // NOTE: If this is in an SKSpriteNode, you might want to use self.anchorPoint instead
CGFloat distanceToCenter = return hypotf(point.x - centerOfNode.x, point.y - centerOfNode.y);
return (distanceToCenter <= self.radius);
}
touchesMoved
中的代码不需要任何更改。
答案 1 :(得分:1)
以下演示如何1)选择距离触摸事件指定距离内的精灵,以及2)将所选精灵拖放到新位置。
@interface MyScene()
@property (weak) SKSpriteNode *selectedNode;
@end
@implementation MyScene
-(id)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]) {
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
// Add three sprites to scene
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(32, 32)];
sprite.name = @"Blue";
sprite.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame)-64);
[self addChild:sprite];
sprite = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(32, 32)];
sprite.name = @"Red";
sprite.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame) + 64);
[self addChild:sprite];
sprite = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(32, 32)];
sprite.name = @"Green";
sprite.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
[self addChild:sprite];
}
return self;
}
#define kRadius 64
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
_selectedNode = nil;
CGFloat minDistance = kRadius+1;
for (UITouch *touch in touches) {
CGPoint location = [touch locationInNode:self];
for (SKSpriteNode *node in self.children) {
CGFloat dx = location.x - node.position.x;
CGFloat dy = location.y - node.position.y;
// Compute distance from sprite to tap point
CGFloat distance = sqrtf(dx*dx+dy*dy);
if (distance <= kRadius) {
if (distance < minDistance) {
// Select the closest node so far
_selectedNode = node;
minDistance = distance;
}
}
}
}
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
if (_selectedNode) {
// Move selected node to current touch position
_selectedNode.position = location;
}
}
- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// Unselect node
_selectedNode = nil;
}
- (void) update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
@end
答案 2 :(得分:0)
我认为你应该补充一下,如果我错误地理解你的问题,请原谅我:
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
CGPoint point = [touch locationInView:self.view];
if (touches.count == 1) && (point.x == yourObjectsXPosition) && (point.y == yourObjectsYPosition)
{
[self touchesMoved:touches withEvent:event];
}
}