I want the node to move in the right direction but the impulse to be with set strength.
let node: SKSpriteNode!;
node = SKSpriteNode(color: UIColor.greenColor(), size: CGSizeMake(50, 50));
node.physicsBody = SKPhysicsBody(rectangleOfSize: node.size);
node.physicsBody?.affectedByGravity = false;
node.physicsBody?.allowsRotation = false;
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
node.physicsBody?.velocity = CGVectorMake(0, 0);
// ver 1
node.physicsBody?.applyImpulse(CGVectorMake((0.4) * (location.x - node.position.x), (0.4) * (location.y - node.position.y)), atPoint: CGPointMake(position.x,position.y));
// ver 2
let offset:CGPoint = self.vecSub(location, b: ghost.position);
let direction: CGPoint = self.vecNormalize(offset);
var len: CGPoint = self.vecMult(direction, b: 40);
let impulseVector:CGVector = CGVectorMake(len.x, len.y);
ghost.physicsBody?.applyImpulse(impulseVector);
}
func vecAdd(a: CGPoint, b:CGPoint) -> CGPoint {
return CGPointMake(a.x + b.x, a.y + b.y);
}
func vecSub(a: CGPoint, b:CGPoint) -> CGPoint {
return CGPointMake(a.x - b.x, a.y - b.y);
}
func vecMult(a: CGPoint, b:CGFloat) -> CGPoint {
return CGPointMake(a.x * b, a.y * b);
}
func vecLenght(a:CGPoint)->CGFloat{
return CGFloat( sqrtf( CFloat(a.x) * CFloat(a.x) + CFloat(a.y) * CFloat(a.y)));
}
func vecNormalize(a:CGPoint)->CGPoint{
let len : CGFloat = self.vecLenght(a);
return CGPointMake(a.x / len, a.y / len);
}
version 1 is horrible
version 2 is okay, but is too expensive
version 3: something not expensive and to apply impulse with 15-100 strength, because if the touch is at the edges of the screen the node should move only 15-100 of its current possition without reaching the touch position
Both the methods you've detailed above work so I'm not exactly sure what you're problem is. Also, I'm not sure method two is it's too expensive, are you having frame rate drops using it?
But I've got another way you could do what you're after, it's basically the second version but cleaned up. But firstly I just wanted to point out a couple things with your current code:
1. You don't need to
;
to the end of each line.2. Instead of using
vecAdd
,vecSub
etc you could overload the+
,-
,*
and/
operators which would make your code cleaner and clearer. This way, the operators would also be global so you could use them anywhere else you need to manipulate vectors.Anyway, here's my attempt at it:
Firstly, extend
CGVector
to add the functionality you need. Things likelength
, which you were defining as functions, could be properties ofCGVector
:Secondly, using the new methods:
Alternatively, if you wanted the size of the impulse to relate to how far away from the ghost the user pressed, use the following:
Hope that helps!