Sunday, January 23, 2011

i++ !== i--

(i +1 does not equal i-1)

Those of you who played Beta on the Beach know that the game lags when there's too many monsters on the screen.  As you defeat monsters however the game will speed back up again.  That's partially because the game is drawing less of course, but more because the code is actively clearing dead monsters from the hittest array.  I was honestly pretty proud of how it all worked. 

However, there was one hiccup that bugged me.  It pretty much is what made me decide to release Beta on the Beach.  The game builds a giant array for details about each monster on the screen, with each monster getting their own row.  As that monster dies, that row gets cleared, thus making the array smaller.  It's all controlled by a loop that looks like this:

for (i=0 ; i<_root.BGA.length ; i++)

If you don't read much code, all this does is start counting at zero, and continues counting rows upward until it's read the last row from the monster array (BGA = Bad Guy Array).  Now, the problem occurs when a bad guy actually dies.  I want the array to remove that line to make is smaller.  This naturally shifts all the rows below up one line.  BUT the loop counter doesn't know that the matrix has changed, so it continues on to the next row, which was 2 rows down when the loop started (the next row has moved up to where the deleted row used to be).

If you didn't catch all that, don't worry.  I didn't really put it all together at first either.  And there are ways to tell the loop to backup one level & retest the skipped row.  But if the counter (i) ever becomes a negative number, the loop just freaks & crashes.  The 'best' fix I could find was to tell it never to check row 0 (arrays start at 0 instead of 1), which meant any time the very first monster was killed, I briefly lost track of the second monster.  Not ideal, but I don't think anyone ever noticed.

Anyway, this weekend I finally figured out a more elegant solution, and it's painfully simple now that I see it. 

Run the loop backwards instead. 

for ( i=(_root.BGA.length -1) ; i >=0 ; i--)

Now when a row gets deleted, I don't care about the ones that get shifted, as I've already tested them.  This is probably the kind of stuff they teach in first year programming, so it's not like I can claim to be the next Einstein or nothing.  But I was still really happy to find such a simple solution, even if it is like 3 months later.  If this trend continues, I'll totally have my current Vcam problem solved by July.  ;P


No comments: