While in the process of trying to learn Python, I decided it would be a good idea to attempt to learn some AI and AI related concepts at the same time using the PyGame framework, as advised by AIGameDev.
For a while, I’ve had this really nice steering demo/white paper in my Delicious account, something that I’ve meant to try implementing myself. Because this was entirely new territory, and I know my physics/math isn’t up to scratch, I decided to try to implement some of the behaviors outlined in the previous paper in Actionscript 3.0 first, then when I got the hang of it, port it to Python.
After about 8 hours or so, I had finally puzzled out the seek/flee behavior, and tried to put together a demo as in the above page, when I hit a strange bug. If I put the seek behavior vehicle on the stage on it’s own, it performed correctly. If I placed the flee behavior vehicle on the stage on it’s own, it performed correctly. If I had both on the stage at once, they freaked out and opposed one another, and the two vehicles often got caught in a state of equilibrium, their velocities canceling each other out.
It seemed as if my little vehicle views were sharing the same vehicle model, and the two different behaviors were acting on the same vehicle model. Which didn’t make any sense, considering they were two separate instances of the same class.
After a lot of bug testing and fiddling around, I finally realise I had been caught by the way Actionscript passes parameters into functions/constructors: unless you’re passing a primitive data type, Actionscript passes by reference.
I was instantiating my vehicles with the same velocity and starting position, and I was using arrays to pass in this information into the constructors, little knowing that the actual array each class was manipulating was the same array.
You can easily bypass this by importing
and using the
method (remembering to cast it back to your desired data type, in my case an array).
So, if you find your instances seem to be sharing private variables they shouldn’t be, check your parameters and make sure you’re not passing things by reference to multiple instances and manipulating them.