Astrum
Astrum

Reputation: 375

Applying impulse at angle based on touch location

I'm currently developing a game with a cannon that shoots a projectile, I'm having trouble figuring out how to get the projectile to fire at the angle based on the touch location and how far away it is from the cannon. this is the code i'm using below.

let dx = cannon.position.x - (touchLocation.x)
        let dy = cannon.position.y - (touchLocation.y)
        let angle = atan2(dy, dx)

        bullet.zRotation = angle
        bulletspeed = Double.random(in: 1...6)

        //let angle1 = Double.random(in: 0.2...5); let angle2 = Double.random(in: 1...4)

        // dx must be somewhere between 0.2 to 5
        bullet.physicsBody?.applyImpulse(CGVector(dx: -angle , dy: -angle))

this doesn't seem to work and i've resorted to using the angle as my x and y values which works but not well.

I'm trying to get the cannon to fire based on the angle of the touch location and to change the speed/power of the projectile by how far way the touch location is from the cannon. How can I do this?

Upvotes: 0

Views: 84

Answers (1)

Fogmeister
Fogmeister

Reputation: 77631

The vector you need to use takes in dx and dy as parameters. You already have these but you say the speed is too fast. That’s because the length of the vector is the speed.

So in your example the speed can be calculated like...

sqrt(dx*dx+dy*dy)

What you need to do is calculate a ‘unit vector’ that is, a vector with length equal to one.

You can do this by dividing dx and dy by the length of the vector.

So...

touchDX = //your calculation
touchDY = //your calculation

touchLength = sqrt(touchDX*touchDX+touchDY*touchDY)

unitVectorDX = touchDX / touchLength
unitVectorDY = touchDY / touchLength

// now put the speed you want in...

speed = 10

vector = CGVector(dx: unitVectorDX * speed, dy: unitVectorDY * speed)

Now, if you use the vector in your impulse it will have the correct direction and speed.

Quick side note, I’m typing on my iPad so don’t have access to code completion etc... you may be able to do this using APIs on CGVector. I think I remember a ‘unitVector’ property that returns a unit vector. But I may be mistaken.

Upvotes: 1

Related Questions