![]() |
Further proof that I’m an idiot
July 8, 2008 on 4:36 pm | In Uncategorized | | Jeremy ReadFor 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.
5 Comments »
RSS feed for comments on this post. TrackBack URI
Leave a comment
You must be logged in to post a comment.
Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds.
Valid XHTML and CSS. ^Top^

Some don’t understand what’s going on in the various quadrants. Although theta is the same, it should be in the lower left quadrant:
ang = theta + pi
I’ll draw a marginally better diagram later on tonight.
Comment by Jeremy Read — 8:00 pm — July 8, 2008 #
See what happens with homeschooling is that your teachers don’t drill into you that atan is not particularly useful since it’s a ratio of sin to cos and thus signs cancel.
Of course if you went to boarding school teachers drilled other stuff into you, or so I hear.
So, how goes the TD progression? When’s beta testing?
Comment by DarkSentinel — 10:10 pm — July 8, 2008 #
I “could” use atan if I checked if x<0 and added pi. I think. Too late and night to think this one through.
Comment by Jeremy Read — 12:55 am — July 9, 2008 #
And beta testing, well um. It doesn’t do much at the moment. As soon as I figure out the Tower Widget. And getting the towers to fire at monsters, then everything should be good.
Comment by Jeremy Read — 1:01 am — July 9, 2008 #
[...] upon the previous post, while refactoring the Tower class in the Tower Defence I made a mistake that resulted in a rather [...]
Pingback by Life Outside PLT1 » Further proof that I’m an idiot (yet again) — 11:59 pm — July 9, 2008 #