## Predictive Shooting

January 19, 2008 by jobemakar

It has been quite a while since my last blog post. I have a lot of useful ideas that would make great posts but some super cool Electrotank projects have been sucking up my life.

One of our smaller projects is a tower defense game due out soon. For this game we developed a way to precisely answer this question: If a tower wants to fire off a bullet right now and hit a specific moving target, at what angle should it shoot?

The end result is a function that can find that angle for you. If you use it then you’ll get a direct hit every time! If that makes your AI too perfect, then tack on some random variation to the angle and it will be less precise the further away it is from the target.

The known information are these things:

- Current position of the target
- The target’s velocity (acceleration not supported here)
- Position of the tower
- Shot speed
- Length of tower muzzle, if any

The equations of motion for the target are:

**x1 = x1o + v1*cos(theta)*t**

y1 = y1o + v1*sin(theta)*t

- x1o – Current x position of target
- y1o – Current y position of target
- v1 – Speed of target
- theta – Angular direction of target
- t – Time variable

The equations of motion for the bullet are:

**x2 = (x2o+n*cos(alpha)) + v2*cos(alpha)*t**

**y2 = (y20+n*sin(alpha)) + v2*sin(alpha)*t**

- y1o – Y position of tower
- x2o – X position of tower
- v2 – Bullet speed
- alpha – The unknown angle to shoot
- n – The length of the muzzle
- t – Time variable

You can download the source code which contains the solution here:

Download source

click to view example

### Like this:

Like Loading...

*Related*

on March 24, 2008 at 11:45 pm |AshishHi Jobe,i use your game design book in my class, however all code examples are in AS2, do you have an upgraded version of all the code in AS3, my students would really appreciate it if they can get hands on the AS3 codeThanksashishamresh at asu dot edu

on April 16, 2008 at 4:09 am |AnonymousYeah same here, I’d appreciate if you can make the code in AS3. Thanks.

on May 14, 2008 at 1:31 pm |AnonymousWhen is your next game design book comming out for AS3. I loved your last one! I would love to see a section on tile based games, isometric (columnar and the more traditional diamond).

on August 16, 2008 at 7:26 pm |Jobe MakarHi ashish,Just about all the code we produce is AS3. This particular game was made for Comedy Central and they were at the time still tied to AS2. The important code is 99% copy-and-pasteable to AS3. The only change is switching Void to void. The UI code is way different, but you shouldn’t care about that. Just focus on the core calculation.

on August 16, 2008 at 7:27 pm |Jobe Makaranonymous – I currently don’t have any game books in the works. I had worked out a deal wit Peachpit to do an AS3 game book a about 18 months ago but running Electrotank has kept me from being able to do that.I still want to work on another one. But at the moment I have no time estimate.

on February 11, 2009 at 5:12 pm |AlexHi Jobe,I have been trying to use your code in AS3, and am having some difficulty. I guess in your code here the “4” and “2” are hard coded velocities for the guy and the bulletspeed:B * B – 4 * A * E; and here: var t1:Number = ( -B + sqrt) / (2 * A);//throw this out var t2:Number = ( -B – sqrt) / (2 * A);//use this one var t:Number = t2;Also, this function for finding sqrt simply returns NaN unless using Math.abs: var sqrt:Number = Math.sqrt(B * B – bulletSpeed * A * E);Even changing those things and changing the guy and bullet parameters for my own tower and guy, it still points wildly and erratically all over the place.I’d really like to use this. Any help appreciated. I can send screenshot or any other info you need.

on February 12, 2009 at 4:52 am |AlexI’ve taken this about as far as I can without delving into the complicated-looking maths functions with single letter variables. It now calculates a collision point that is ahead of the guy, but the bullet does not intersect it at the same time as the guy. Changes below://solve it var equ:Number = Math.abs(B * B – 1000/v2 * A * E); var sqrt:Number = Math.sqrt(equ); var t1:Number = ( -B + sqrt) / (1000/v1 * A);//throw this out| AR: For bullet slower than guy var t2:Number = ( -B – sqrt) / (1000/v1 * A);//use this one| AR: For bullet faster than guy var t:Number = t2; var collisionX:Number = (x1o+v1*cosTheta*t)-x20; var collisionY:Number = (y1o+v1*sinTheta*t)-y20; var alpha:Number = Math.atan2(collisionY, collisionX); Where 1000 is milliseconds (I am calculating velocities in pixels per second).

on February 12, 2009 at 3:02 pm |AlexI gave up on this one and made my own that solves it by moving the target’s velocity vector around. If anyone is interested, let me know.

on February 12, 2009 at 3:06 pm |Jobe MakarHi Alex,Sorry I can’t help much. Too slammed with work. But the provided source code should work perfectly.You asked about the ‘4’ and the ‘2’. Those are not values I made up, they are part of the quadratic formula. Good luck with your new solution!

on May 7, 2009 at 4:15 pm |Karim BeyroutiHi Jobe, thanks for sharing your work. Just a quick question – i am trying to solve the angle of the GUY in your source ( because that is an unknown in my game ) . I am using this Equation to derive the guy’s angle: calcGuyAngle = Math.atan2(prevYPos – guy._y , prevXPos – guy._x ) * 180 / Math.PI; trace(‘guyAngel: ‘ + guyAngel ) ; trace(‘calcAngle: ‘ + calcAngle ) ;However it yeilds different values to ‘guyAngel’ in your code (which i am using to check my calculation – this is the case in radians and degrees ). I am not sure where i am going wrong here. Would be great if you could point me in the right direction.RegardsKarim