문제

So I generated an SKShapeNode, and need to know when that node is clicked. I do so by calling:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   UITouch *touch = [touches anyObject];
   CGPoint positionInScene = [touch locationInNode:self];
   SKNode *node = [self nodeAtPoint:positionInScene];
   if ([node.name isEqualToString:TARGET_NAME]) {
       // do whatever
    }
  }
}

So the result I'm getting is pretty weird. Clicking the dot itself does in fact work. However, pressing anywhere on the screen that is southwest of the SKShapeNode's position will also render the above code as true.

enter image description here

With the SKShapeNode represented by the red dot, any UITouch in the shaded region would render my code above as true.

Here is how I am building the SKShapeNode. It may also be important to note that my application runs in landscape mode.

#define RANDOM_NUMBER(min, max) (arc4random() % (max - min) + min)


- (SKShapeNode *)makeNodeWithName:(NSString *)name color:(UIColor *)color
{
  SKShapeNode *circle = [SKShapeNode new];

  int maxXCoord = self.frame.size.width;
  int maxYCoord = self.frame.size.height;
  CGFloat x = RANDOM_NUMBER((int)TARGET_RADIUS, (int)(maxXCoord - TARGET_RADIUS));
  CGFloat y = RANDOM_NUMBER((int)TARGET_RADIUS, (int)(maxYCoord - TARGET_RADIUS - 15));

  circle.fillColor = color;
  circle.strokeColor = color;
  circle.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, TARGET_RADIUS, TARGET_RADIUS)].CGPath;

  circle.name = name;
  return circle;
}

Thanks for any help!

도움이 되었습니까?

해결책

This happens because the circle node's position is at origin, and it draws the path in a rect starting at (x,y). So the node's frame is stretched to encompass everything between (0,0) to (x+TARGET_RADIUS, y+TARGET_RADIUS).

You can check this out for yourself, by visualizing the circle's frame:

SKSpriteNode *debugFrame = [SKSpriteNode spriteNodeWithColor:[NSColor yellowColor] size:circle.frame.size];
debugFrame.anchorPoint = CGPointMake(0, 0);
debugFrame.position = circle.frame.origin;
debugFrame.alpha = 0.5f;
[self addChild:test];

This reveals the actual clickable region (on OSX):

Visualized clickable region

To fix your issue, try this:

circle.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-TARGET_RADIUS/2.0f, -TARGET_RADIUS/2.0f, TARGET_RADIUS, TARGET_RADIUS)].CGPath;

and add

circle.position = CGPointMake(x, y);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top