swift - How to apply impulse to the node on touch angle -
i want node move in right direction impulse 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 horrible
version 2 okay, expensive
version 3: not expensive , apply impulse 15-100 strength, because if touch @ edges of screen node should move 15-100 of current possition without reaching touch position
both methods you've detailed above work i'm not sure you're problem is. also, i'm not sure method 2 it's expensive, having frame rate drops using it?
but i've got way you're after, it's second version cleaned up. firstly wanted point out couple things current code:
1. don't need ;
end of each line.
2. instead of using vecadd
, vecsub
etc overload +
, -
, *
, /
operators make code cleaner , clearer. way, operators global use them anywhere else need manipulate vectors.
anyway, here's attempt @ it:
firstly, extend cgvector
add functionality need. things length
, defining functions, properties of cgvector
:
extension cgvector { init(p1: cgpoint, p2: cgpoint) { self.dx = p1.x - p2.x self.dy = p1.y - p2.y } var length: cgfloat { { return hypot(dx, dy) } set { normalise() dx *= newvalue dy *= newvalue } } mutating func normalise() { dx /= length dy /= length } }
secondly, using new methods:
var vec = cgvector(p1: location, p2: ghost.position) vec.length = 40 ghost.physicsbody!.applyimpulse(vec)
alternatively, if wanted size of impulse relate how far away ghost user pressed, use following:
vec.length *= 0.1
hope helps!
Comments
Post a Comment