My PVZ Development Log
Development Log #3
Overview
I just made about six pushes during the past three days. Many new features were implemented (actually they’re not “new” because they should be really familiar to those who’ve played the game before :P), but anyways, this is another log for all the updates.
Bugs encountered💀💀💀
So far I encountered three big bugs that confused me quite some while. Thanks god I managed to fix them all. Bugs that are the easiest to fix are those where problems are merely logics. That being said the goofiest and most devastating are stupid errors like typos.
for (int i = 0; i < num; i)
Notice how in the above for loop there’s no addition to i every iteration, which means something are not going to work out
zms[k] but k should be i. Similar to above, typo errors.
Accidentally put some code blocks into a supposedly empty loop (took me one day to notice the bug, literally carefully read through the entire code five times to find it out).
Bug 1
Zombies could not spawn.
At first I thought it is that there’s problem rendering the zombie and I couldn’t see it on the screen. So after making sure the logic for the zombie’s movement make sense I start the game and let the “invisible” zombie walk. However once I realize after a long period of time the game wouldn’t stop automatically I know for sure things go wrong with creating the zombie. So quickly I locate the function that explicitly does this, which is called createZM().
The problem is cause by me putting the code block that actually creating the zombie inside of an empty loop that should do nothing when zms[i].used is false. After extracting it out the bug is fixed.
Bug 2
Peashooter shoot even if zombies is behind it
This one is simply logical error. At first I didn’t consider the relative distance between each zombie and each peashooter. So the logic before the bug is fixed is that if there’s a zombie on the row, the peashooter would shoot the pea. However, since this logic failed to consider the case when peashooter is somehow planted behind the zombie, i.e. plant.x > zombie.x, the peashooter should stop shooting pea. That make more sense as regular peashooter’s head is confronting toward the right direction, and there’s no way it can shoot backward (there’s a reverse shooter which shoot backward, but we’re not making it in this game).
My resolution is by nesting another loop which traverse all possible zombies in the current zombie pool, and by analyzing the relative distance between each zombies and each plant, each peashooter can dynamically justify which zombie should it shoot and which should it not.
Later when I look back to my resolution to this bug, I found that such an extra loop causes further bugs.
Bug 3
Peashooter shooting too much at a time
From the resolution in bug 2 I traverse all zombies to analyze the relative distance between each zombie and each peashooter. Now, one thing is that I embedded the actual function of “shooting the pea” into the innermost side of the triple loop. The problem is quickly revealed: The more zombies on a same row, the faster each peashooter shoots than it should be.
In the original Plants-vs-Zombies, no matter how many zombies there’s in front of a peashooter, the peashooter should always shoot at a same frequency. Which means the frequency of shooting is a constant, rather than a variable.
The reason for the bug is because during the for-k-loop which loop through each zombie in the pool, the pea-shooting function specifically ran for that zombie, so let’s say if the peashooter shoot one pea per second per zombie, if there’s two zombies standing on a same row, then since the pea-shooting function is ran twice, the peashooter would shoot two peas per second. That being said the peashooter’s shooting frequency is positively related to the amount of zombies presented ahead of that specific peashooter. The more zombies ahead, seemingly the “faster” it shoots.
What confuses me the most is analyze and locate the problem. In fact the peashooter did not shoot faster at all. The frequency of it shooting peas are all the same. The fact that it seems like the peashooter shoots faster is because the program is ran more than one time, by which one at a time is ought to be the correct idea. Then the solution becomes much more clear, which is simply by restricting the amount of time the pea-shooting program is ran. By setting the program only allowed to run once at a time, the peashooter shoots in a normal speed again.
What’s more, the peashooter keep shooting after the first zombie is dead, and the flying peas that are shot before the dead zombie dies kept flying and hit the next zombie and causes damage. This is because all peas are individual and does not relate to the peashooter. The only job that the pea does is to fly toward the east and causes damage to any zombie when collide.
Conclusion
Debugging in C++ is a painful thing. The most critical step is not fixing the bug, but instead locating the bug. Honestly speaking though one would not be able to correctly locate a bug if he/she doesn’t understand why the bug occur. So once the bug is located, it is probable that you already understand the problem and are ready to fix it smoothly.