How to calibrate a sprites touchLocation after zoom - ios

I add a sprite on the background sprite and then zoom (pinch) the background and by that the sprite as well.
After the zoom i want to be able to click right on the "zoomed" sprite and then move (pan) it. However, to catch the sprite i have to click outside of the sprite. I guess that is due to the zoom and coordinates.
I would really need some help how to make it so that i always only need to click on the actual sprite if it is in it's original state or zoomed up or down.
I will also implement UIScrollView so i can move around the background but would like to fix this first.
Here is the code i use to test this:
- (void)didMoveToView:(SKView *)view {
_background = [SKSpriteNode spriteNodeWithImageNamed:#"background"];
_background.name = #"background";
[_background setAnchorPoint:CGPointZero];
// _background.anchorPoint = CGPointMake(0.0, 0.1);
self.scaleMode = SKSceneScaleModeResizeFill;
[self addChild:_background];
SKLabelNode *texT = [SKLabelNode labelNodeWithFontNamed:#"Ariel"];
texT.text = #"X";
texT.position = CGPointMake(160, 260);
[_background addChild:texT];
_panGesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:#selector(handlePan:)];
[self.view addGestureRecognizer:_panGesture];
_pinchGesture = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:#selector(handlePinch:)];
[self.view addGestureRecognizer:_pinchGesture];
/* Setup your scene here */
self.backgroundColor = [SKColor colorWithRed:0.15 green:0.15 blue:0.3 alpha:1.0];
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:#"Spaceship"];
sprite.xScale = 0.2;
sprite.yScale = 0.2;
sprite.position = CGPointMake(160, 260);
sprite.name = #"sprite";
[_background addChild:sprite];
}
- (void)handlePan:(UIPanGestureRecognizer *)sender {
NSLog(#"handlePan:");
if (![_currentNode.name isEqualToString:#"background"]) {
_touchLocation = [sender locationInView:sender.view];
_touchLocation = [self convertPointFromView:_touchLocation];
_currentNode.position = _touchLocation;
}
}
- (void)handlePinch:(UIPinchGestureRecognizer *) sender {
NSLog(#"handlePinch: %f",sender.scale);
[self runAction:[SKAction scaleBy:sender.scale duration:0]];
sender.scale = 1;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSLog(#"touchesBegan");
//////DO THE FIRST TOUCH//////
_actualTouch = [touches anyObject];
_touchLocation = [_actualTouch locationInNode:self];
_currentNode = [self nodeAtPoint:_touchLocation];
NSLog(#"TouchBegan:_touchLocation:%#", NSStringFromCGPoint(_touchLocation));
NSLog(#"_currentNode.name: %#", _currentNode.name);
}
#end

I had this same problem and I found that the solution is to resize instead of scale. The physics seem to still work as expected and now the touch events will too. I came across this solution here. The scaleMode in your didMoveToView needs to be changed as well, see below.
self.scaleMode = SKSceneScaleModeAspectFill;
- (void)handlePinch:(UIPinchGestureRecognizer *) sender {
NSLog(#"handlePinch: %f",sender.scale);
//[self runAction:[SKAction scaleBy:sender.scale duration:0]];
self.size = CGSizeMake(self.size.width/sender.scale,self.size.height/sender.scale);
sender.scale = 1;
}
In my own implementation I had set upper and lower limits to the zoom level as well.

Related

Spritekit: move SKSpritekitNode in arc with SKPhysicsBody

I'm trying to move an SKSpriteNode in an arc with physics in spritekit like so:
But am unsure as to which physic I should apply to it (applyImpulse, applyForce, applyTorque).
Currently using applyTorque, the code does not actually work, and produces no movement on the object:
_boy.physicsBody.velocity = CGVectorMake(1, 1);
CGVector thrustVector = CGVectorMake(0,100);
[_boy.physicsBody applyTorque:(CGFloat)atan2(_boy.physicsBody.velocity.dy, _boy.physicsBody.velocity.dx)];
applyTorque is not the right method for this. Torque is a twisting force that causes your node to rotate around its center point.
There is no one easy command for what you are looking to do. You also fail to mention your method of movement for your node. Apply force, impulse, etc... You are going to have to come up with a hack for this one.
The sample project below does what you are looking for and it will point you in the right direction. You are going to have to modify the code to suit your specific project's needs though.
Tap/click the screen once to start moving the node and tap/click the screen a second time to start to 90 degree movement change.
#import "GameScene.h"
#implementation GameScene {
int touchCounter;
BOOL changeDirection;
SKSpriteNode *node0;
}
-(void)didMoveToView:(SKView *)view {
self.backgroundColor = [SKColor whiteColor];
node0 = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(50, 50)];
node0.position = CGPointMake(150, 200);
node0.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node0.size];
node0.physicsBody.affectedByGravity = NO;
[self addChild:node0];
touchCounter = 0;
changeDirection = NO;
}
-(void)update:(CFTimeInterval)currentTime {
if(changeDirection)
[self changeMovement];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
touchCounter++;
for (UITouch *touch in touches) {
if(touchCounter == 1)
[node0.physicsBody applyImpulse:CGVectorMake(25, 0)];
if(touchCounter == 2)
changeDirection = YES;
}
}
-(void)changeMovement {
if(node0.physicsBody.velocity.dy<200) {
[node0.physicsBody applyImpulse:CGVectorMake(-0.1, 0.1)];
} else {
changeDirection = NO;
node0.physicsBody.velocity = CGVectorMake(0, node0.physicsBody.velocity.dy);
}
}

Can't seem to figure what's wrong here

I've used this same exact code before, and it worked perfect every time. However, I'm trying to use it to move the paddle sprite along a horizontal path at position 100 for y and it updates with the location of my touch but for some reason it's not moving at all. I can't spot what's wrong. Can someone take a look and let me know?
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
for (UITouch *touch in touches){
CGPoint location = [touch locationInNode:self];
CGPoint newPosition = CGPointMake(location.x, 100);
//stop the paddle from going too far
if (newPosition.x < self.paddle.size.width/ 2) {
newPosition.x = self.paddle.size.width/ 2;
}
if (newPosition.x > self.size.width - (self.paddle.size.width/ 2)) {
newPosition.x = self.size.width - (self.paddle.size.width/ 2);
}
self.paddle.position = newPosition;
}
}
-(void) addPlayer:(CGSize)size {
SKSpriteNode *paddle = [SKSpriteNode spriteNodeWithImageNamed:#"paddle"];
//resize sprite
paddle.size = CGSizeMake(125, 31.25);
//position sprite
paddle.position = CGPointMake(size.width/2, 100);
//add physics body to paddle
paddle.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:paddle.frame.size];
//change to static so wont be moved by physics
paddle.physicsBody.dynamic = NO;
//add sprite to scene
[self addChild:paddle];
}
-(instancetype)initWithSize:(CGSize)size {
if (self = [super initWithSize:size]){
self.backgroundColor = [SKColor colorWithRed:(29.0f/255) green:(29.0f/255) blue:(29.0f/255) alpha:1.0];
//change gravity
self.physicsWorld.gravity = CGVectorMake(0, 0);
//add physics body to scene
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
[self addPlayer:size];
[self addBricks:size];
[self addBall:size];
}
return self;
}

Moving a camera in SpriteKit

//UPDATE
The updated code has been added that works as I expected. See didSimulatePhysics method in the updated code below. In my case, I only care about moving a character left or right on the x axis where 0 on the x axis is the absolute left and right on the x axis is a configurable value. The Apple adventure game really helped a lot too.
//ORIGINAL POST BELOW
I'm working with Apple SpriteKit and I'm struggling to implement a camera as I would like it to behave. What I've done in the code is load a sprite character, two buttons, and a red box that is off to the right outside of the view at the start. What I'd like to be able to do is move the character with the buttons, and once the player reaches the middle or end of the screen, the camera will then re-adjust to uncover what couldn't be seen in the view. So moving to the right should eventually show the red box that is off outside of the view initially once the player gets there. However, with the code I'm using below, I'm unable to get the camera to follow and adjust the coordinates to the main character at all. I've looked at Apple's advanced scene processing doc as well as a few other stack overflow posts but can't seem to get it right. If anyone could offer some advice it would be appreciated.
#define cameraEdge 150
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size])
{
/* Setup your scene here */
//320 568
self.backgroundColor = [SKColor whiteColor];
myWorld = [[SKNode alloc] init];
[self addChild:myWorld];
mainCharacter = [SKSpriteNode spriteNodeWithImageNamed:#"0"];
mainCharacter.physicsBody.dynamic = YES;
mainCharacter.name = #"player";
mainCharacter.position = CGPointMake(20, 20);
CGRect totalScreenSize = CGRectMake(0, 0, 800, 320);
SKSpriteNode *box = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(60, 60)];
SKSpriteNode *boxTwo = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(60, 60)];
SKSpriteNode *boxThree = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(60, 60)];
boxThree.position = CGPointMake(40, 50);
[myWorld addChild:boxThree];
boxTwo.position = CGPointMake(1100, 50);
box.position = CGPointMake(650, 50);
[myWorld addChild:box];
[myWorld addChild:boxTwo];
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:totalScreenSize];
self.physicsWorld.gravity = CGVectorMake(0, -5);
mainCharacter.name = #"mainCharacter";
mainCharacter.physicsBody.linearDamping = 0;
mainCharacter.physicsBody.friction = 0;
mainCharacter.physicsBody.restitution = 0;
mainCharacter.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:mainCharacter.size];
[myWorld addChild:mainCharacter];
[self addChild:[self buildLeftButton]];
[self addChild:[self buildRightButton]];
}
return self;
}
- (void)didSimulatePhysics
{
SKSpriteNode *hero = mainCharacter;
if(hero)
{
CGPoint heroPosition = hero.position;
CGPoint worldPosition = myWorld.position;
NSLog(#"%f", heroPosition.x);
CGFloat xCoordinate = worldPosition.x + heroPosition.x;
if(xCoordinate < cameraEdge && heroPosition.x > 0)
{
worldPosition.x = worldPosition.x - xCoordinate + cameraEdge;
self.worldMovedForUpdate = YES;
}
else if(xCoordinate > (self.frame.size.width - cameraEdge) && heroPosition.x < 2000)
{
worldPosition.x = worldPosition.x + (self.frame.size.width - xCoordinate) - cameraEdge;
self.worldMovedForUpdate = YES;
}
myWorld.position = worldPosition;
}
}
-(SKSpriteNode *)buildLeftButton
{
SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:#"left"];
leftButton.position = CGPointMake(20, 20);
leftButton.name = #"leftButton";
leftButton.zPosition = 1.0;
return leftButton;
}
-(SKSpriteNode *)buildRightButton
{
SKSpriteNode *leftButton = [SKSpriteNode spriteNodeWithImageNamed:#"right"];
leftButton.position = CGPointMake(60, 20);
leftButton.name = #"rightButton";
leftButton.zPosition = 1.0;
return leftButton;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
SKNode *node = [self nodeAtPoint:location];
if([node.name isEqualToString:#"leftButton"])
{
[mainCharacter.physicsBody applyImpulse:CGVectorMake(-120, 0)];
}
else if([node.name isEqualToString:#"rightButton"])
{
[mainCharacter.physicsBody applyImpulse:CGVectorMake(120, 10)];
}
}
If you want the view to always be centered on your player's position, modify your code with these points in mind:
1) Create a SKNode and call it myWorld, worldNode or any other name like that.
2) Add the worldNode [self addChild:worldNode];
3) Add all other nodes to the worldNode, including your player.
4) In the didSimulatePhysics method, add this code:
worldNode.position = CGPointMake(-(player.position.x-(self.size.width/2)), -(player.position.y-(self.size.height/2)));
Your view will now always be centered on your player's position.
Update May 2015:
If you are using a map created with Tiled Map Editor, you can use the free SKAToolKit framework. Features include player camera auto follow, test player, test HUD and sprite buttons.

Really need SKSpriteNode children to shoot correctly

So I have a shipNode (which is initially facing right) with two children called _laserCannon1(and 2) that are configured by the method below:
-(void)initializeLaserCannonLocations
{
CGSize size = CGSizeMake(4.0, 4.0);
_laserCannon1 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:size];
_laserCannon2 = [SKSpriteNode spriteNodeWithColor:[SKColor yellowColor] size:size];
_laserCannon1.position = CGPointMake(self.size.width/2, self.size.height/2 + 15);
_laserCannon2.position = CGPointMake(self.size.width/2, self.size.height/2 - 15);
[self addChild:_laserCannon1];
[self addChild:_laserCannon2];
}
Then I am later "firing" lasers from them based off of the ship's zRotation as follows
-(void)fireLocalLaser
{
CGVector standardLaserVelocity = CGVectorMake(700*cosf(_myShip.zRotation - _myShip.laserCannon1.zRotation),
700*sinf(_myShip.zRotation - _myShip.laserCannon2.zRotation));
[self spawnLaserFrom:CGPointAdd(_myShip.laserCannon1.position, ship.position); withVelocity:standardLaserVelocity fromShip:_myShip];
[self spawnLaserFrom:CGPointAdd(_myShip.laserCannon2.position, ship.position); withVelocity:standardLaserVelocity fromShip:_myShip];
}
Now everything works fine when the ships is facing directly left or right, but for some odd reason as the ship begins to face more towards the top or bottom the shots are fired increasingly towards the middle of the ship, to the point that once the ship is facing vertically both shots are fired from the middle.position.x of the ship. Does it have to do with something from where I placed my _laserCannons?
I hope my math teacher doesn't see this!
Your problem is with the relative position of your 2 laser cannons as they rotate. I have included a picture so I don't have to go into a long winded description of what is happening.
I have included code for a kinda, sorta, duct tape solution on how you can do this if you really want to. It ain't pretty but it works. The code is good from 0 to 90 degrees so you should be able to work out the rest from there if you have your heart set on having 2 cannons. BUT I would strongly suggest your Mighty Space Empire invest in single cannon ships, as it will make your coding job a whole lot easier!
#implementation MyScene {
SKSpriteNode *ship1;
SKShapeNode *turret1;
SKShapeNode *turret2;
}
-(id)initWithSize:(CGSize)size
{
if (self = [super initWithSize:size]) {
self.physicsWorld.contactDelegate = self;
[self createSpaceships];
}
return self;
}
-(void)createSpaceships {
ship1 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(50, 50)];
ship1.position = CGPointMake(300, 150);
ship1.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ship1.size];
ship1.physicsBody.dynamic = NO;
[self addChild:ship1];
SKSpriteNode *frontOfShip = [SKSpriteNode spriteNodeWithColor:[SKColor grayColor] size:CGSizeMake(2, 50)];
frontOfShip.position = CGPointMake(25, 0);
[ship1 addChild:frontOfShip];
}
-(void)update:(CFTimeInterval)currentTime {
/* Called before each frame is rendered */
}
// touch the left side of the screen to rotate the ship by +0.0785398 radians
// touch the right hand side of the screen to fire lasers
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
CGPoint touchLocation = [touch locationInNode:self.scene];
if(touchLocation.x < self.size.width/2) // left side of screen
{
SKAction *block0 = [SKAction runBlock:^{
ship1.zRotation = ship1.zRotation +0.0785398;
}];
[self runAction:block0];
} else // right side of screen
{
float turret1offsetX = 0;
float turret1offsetY = 0;
float turret2offsetX = 0;
float turret2offsetY = 0;
if((ship1.zRotation >0) && (ship1.zRotation <=0.785399))
{
turret1offsetX = (14/0.785398) * ship1.zRotation;
turret1offsetY = (23/0.785398) * ship1.zRotation;
turret2offsetX = (-20/0.785398) * ship1.zRotation;
turret2offsetY = (10/0.785398) * ship1.zRotation;
}
if((ship1.zRotation >0.785399) && (ship1.zRotation <=1.570797))
{
turret1offsetX = (14 - (9/0.785398)) * ship1.zRotation;
turret1offsetY = -4 + (27/0.785398) * ship1.zRotation;
turret2offsetX = (3 - (25/0.785398)) * ship1.zRotation;
turret2offsetY = 20 - (10/0.785398) * ship1.zRotation;
}
int x = ship1.position.x + 1000 * cos(ship1.zRotation);
int y = ship1.position.y + 1000 * sin(ship1.zRotation);
turret1 = [SKShapeNode node];
CGMutablePathRef pathToDraw = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw, NULL, (ship1.position.x+20)+turret1offsetX, (ship1.position.y-25)+turret1offsetY);
CGPathAddLineToPoint(pathToDraw, NULL, x, y);
turret1.path = pathToDraw;
[turret1 setStrokeColor:[UIColor redColor]];
[self addChild:turret1];
turret2 = [SKShapeNode node];
CGMutablePathRef pathToDraw2 = CGPathCreateMutable();
CGPathMoveToPoint(pathToDraw2, NULL, (ship1.position.x+20)+turret2offsetX, (ship1.position.y+25)+turret2offsetY);
CGPathAddLineToPoint(pathToDraw2, NULL, x, y);
turret2.path = pathToDraw2;
[turret2 setStrokeColor:[UIColor redColor]];
[self addChild:turret2];
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
[turret1 removeFromParent];
[turret2 removeFromParent];
}
#end
Yes as sangony put it, it really just has to do with your relative positioning of the _laserCannons from your shipNode. I would personally just start with a singular laserCannon for now, and get more comfortable with the math involved until you feel ready to move on to adding more.

Sprite Kit Joints

I am trying to make an animated character that can reach out for things on the screen, without moving his torso.
If he can not reach than his hand should go the maximal amount in this direction and then be counteracted by the physical limitation of his static torso.
So in my code the green rectangle (hand) moves where I click and the torso follows.
I would like to be able to make the red rect (body) stationary and make the green rectangle "point" at the touch point position.
I have tried to apply a fixed joint to between the scene and the red body rectangle, but this did not seem to work.
- (void) createSceneContent
{
SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:body];
body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];
body.physicsBody.affectedByGravity = NO;
body.physicsBody.dynamic = YES;
self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(150, 20)];
self.hand.position = CGPointMake(body.position.x + body.size.width / 2 + self.hand.size.width / 2, body.position.y);
[self addChild:self.hand];
self.hand.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.hand.size];
self.hand.physicsBody.dynamic = NO;
self.scene.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
[self.physicsWorld addJoint:[SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:self.hand.physicsBody anchor:CGPointMake(body.position.x + body.size.width / 2, body.position.y)]];
[self.hand runAction:[SKAction moveByX:100 y:10 duration:0.1]];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
[self.hand runAction:[SKAction moveTo:location duration:0.1]];
}
First of all, you don't really need to use physics here, if you only want the arm to point at the touched location.
Just change the arm node's anchorPoint to the shoulder (where you would put the pin on the joint) and rotate it around that point (the point is held in a helper shoulderNode, so that it's easy to convert to its coordinates later). You can calculate the rotation angle using atan2f. Here's the code:
- (void) createSceneContent
{
SKSpriteNode *body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:body];
self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(150, 20)];
self.hand.position = CGPointMake(body.position.x + body.size.width*0.5, body.position.y);
self.hand.anchorPoint = CGPointMake(0, 0.5);
[self addChild:self.hand];
SKNode *shoulderNode = [SKNode node];
shoulderNode.position = self.hand.position;
shoulderNode.name = #"shoulderNode";
[self addChild:shoulderNode];
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];
CGPoint locationConv = [self convertPoint:location toNode:[self childNodeWithName:#"shoulderNode"]];
self.hand.zRotation = (atan2f(locationConv.y, locationConv.x));
}
On the other hand, if you ever need to use physics bodies here, it's probably a bad idea to use SKActions to move the arm, and you also might want to set body.physicsBody.dynamic = NO to make the torso static. Then, make sure you add the pin joint correctly, and set its frictionTorque property to a high value to get less dangling. One of the ways to make the hand point at the right location is its velocity vector set in the update method - just use the converted location coordinates (here they are relative to the body node's centre). Full example code:
- (void) createSceneContent {
self.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:self.frame];
body = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
body.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self addChild:body];
body.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:body.size];
body.physicsBody.dynamic = NO;
body.physicsBody.affectedByGravity = YES;
self.hand = [SKSpriteNode spriteNodeWithColor:[SKColor greenColor] size:CGSizeMake(20, 150)];
// experiment with the anchorPoint for different results
self.hand.anchorPoint = CGPointMake(0.5, 0);
self.hand.position = CGPointMake(body.position.x, body.position.y);
[self addChild:self.hand];
self.hand.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.hand.size];
self.hand.physicsBody.dynamic = YES;
self.hand.physicsBody.affectedByGravity = NO;
SKPhysicsJointPin *pinHand = [SKPhysicsJointPin jointWithBodyA:body.physicsBody bodyB:self.hand.physicsBody anchor:CGPointMake(body.position.x, body.position.y-5)];
[self.physicsWorld addJoint:pinHand];
// experiment with the friction torque value to achieve desired results
pinHand.frictionTorque = 1.0;
}
- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *touch = [touches anyObject];
location = [touch locationInNode:self];
}
-(void)update:(CFTimeInterval)currentTime {
CGPoint locationConv = [self convertPoint:location toNode:body];
// experiment with the multiplier (here: 10) for faster/slower movement
self.hand.physicsBody.velocity = CGVectorMake(locationConv.x*10, locationConv.y*10);
}
Hope that helps!

Resources