For everyone who ever wanted conclusive proof that I’m an idiot. At the moment I’m currently working on the Java Tower Defence game, which is slowly progressing along, if you’re lucky it should be released later this week with the C# and XNA versions following. Hopefully Abhishek can get a Clojure version working and everyone will be happy. I’ve gone a little bit more overboard this time, rather than writing the simplest Tower Defence I could I’ve been writing a slightly more extendable version so people can have fun with it.

Anyway last night I was working on the pathing code for the Monsters.

This is seemingly a trivial piece of code.

You want to move the monster along the route towards the path token. Both the monster and path token are represented internally by the Java Point class. So they have both integer X and Y coordinates.

However the most we can move is the speed of the monster each turn. Which might not be the entire distance.

So basic 5th form trig should help us, and it’s that point I made a mistake that wasted about an hour of my time last night.

My initial thought was along these lines. For those who don’t know, atan() is inverse tan.

θ = atan( y/x)
sin(θ) * distance = new y
cost(θ) * distance = new x

Which works perfectly on the diagram. Doesn’t work perfectly in real life. I’d imagine that some of you have immediately spotted why it doesn’t work in practice and how it fails. However I’m going to expand in case others find themselves in a similar situation.

It falls apart horribly when you’re no longer dealing with the upper right quadrant (or for this particular problem the lower right, since when you’re drawing to the screen the top left pixel tends to be (0,0) ).

This is because:

θ = atan( y/x ) = atan( -y/-x )

And hence the formula to find the angle is flawed for half of the cases, since the sign switch isn’t handled correctly.

Thus the correct formula is:

x_θ = acos( x / distance between goal and monster )
y_θ = asin( y / distance between goal and monster )

new_x = cos(x_θ) * distance
new_y = sin(y_θ) * distance

Therefore proving that I am in fact an idiot as it took me at least an hour of proding my own code trying to work out why it was mysteriously failing some but not all cases. You can all laugh at me now.