objective c - Detect touch within a radius of a node in SpriteKit -
i have player object in spritekit game , @ moment i'm moving using following code:
-(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]]; } }
but want move player node when touch within specific range of location.
since looks care distance of touch _player
object, move radius detection logic _player
object , use skregion
handle it.
note: if need know if touch within radius of multiple nodes might want use method this question instead.
to use skregion
determine if touch within radius of _player
, add skregion
instance _player
object , initialize radius want. in [_player init]
or wherever makes sense project:
self.touchregion = [[skregion alloc] initwithradius:radius];
then add method determine if point within region:
- (bool)pointisintouchregion:(cgpoint)point { return [self.touchregion containspoint: point]; }
next change touchesmoved
method like:
-(void)touchesmoved:(nsset*)touches withevent:(uievent*)event { if (touches.count == 1) { uitouch *touch = [touches anyobject]; cgpoint point = [self locationinnode:_player]; // note: it's important use _player here! if ([_player pointisintouchregion: point]) { [_player runaction:[skaction moveto:[[touches anyobject] locationinnode:self] duration:0.01]]; } } }
note: using _player
in [self locationinnode:_player];
critical since skregion
defined in _player
node's coordinate system.
one more note: don't have put logic in _player
, that's way it. store skregion
in scene's class , call [region containspoint: point]
on directly.
update: ios 7 method
the main difference doing ios 7 need store actual radius you're interested in rather skregion
(since it's available in ios 8), , calculation in pointisintouchregion:
.
so, in _player
, set touch radius setting touchregion
before:
self.touchradius = radius
then change pointisintouchregion:
method actual distance calculation.
- (bool)pointisintouchregion:(cgpoint)point { cgpoint centerofnode = cgpointmake(self.frame.size.width / 2.0, self.frame.size.height / 2.0); // note: if in skspritenode, might want use self.anchorpoint instead cgfloat distancetocenter = return hypotf(point.x - centerofnode.x, point.y - centerofnode.y); return (distancetocenter <= self.radius); }
the code in touchesmoved
should not need changes.
Comments
Post a Comment