Title: Head Game Designer
Section of Programming: AI
Although I was labeled Head Game Designer on this project, I think that the duties associated with said title were only taken into consideration early on when decisions needed to be made about which direction we were taking with our game. There was certainly an overall input from the group that really lead us to our final product. The work that I did was most prominently in the coding of the Artificial Intelligence.
Intro to AI:
I began my task by looking into TGB's tutorials to find out which ones would be of help to my section of coding. It was clear that the aStar tutorial (aStar being TGB's built in system for AI path finding) was a good place to start. Although, before I could get going with aStar I had to do a few preliminary tutorials on basic functionality which were required for the aStar tutorial. So to start I did a few basic tutorials on Tile Maps, Sprites, etc. to get a better idea of TGB's overall functionality. These tutorials were relatively simple and quick so I was moving onto aStar itself after a short period of time.
Working with aStar was frustrating at first since the tutorials were clearly written for an earlier version of TGB and showed some inconsistencies that cost me hours. However the time I spent reading code and messing around with files to try and get it working gave me a much better understanding of how aStar worked and in the end may have been somewhat beneficial.
Picture 1: This is after the first few steps of the aStar tutorial, I have gotten a grid of ball objects to appear that an be painted over using the mouse.
Picture 2: Just to show the paint process, I wrote my name with the mouse by clicking and dragging it over the grid. The code is set up so that the color of each circle will change periodically until it reaches the end of a cycle when it will turn back to grey.
The majority of the aStar tutorial was a process of copying and pasting code, which as it progressed, built up your "enemy" executable. The enemy in this case was a butterfly sprite that moved towards a destination (the Earth) and by the end of the tutorial, when all of the code had been placed in the right files, would have to move around the colored grid objects until it found a clear path.
This is a sequence of pictures to show the movement of the butterflies around the colored areas.
Once I had finished with initial tutorial, I spent a number of hours playing around with the code to get a better grasp on how it worked. My biggest issue after some experimental time was understanding how the pathGrid worked with the Tile Map. At times it seemed to work fine, but when the Tile Map was moved or variables were changed the butterflies would react differently to colored circles. Sometimes it seemed as if they were reacting, but in a way which suggested that the Tile Map was offset. So they would move over top of the colored circles but then try to avoid them as if they were 4 or 5 circles away from where they were actually painted. This issue wasn't fully worked out until the last week or so since I decided that moving on to write the Enemy class was a better idea.
The Enemy Class:
A lot of the code I started out with was taken from the code used in the tutorial. It utilized the correct methods for pathfinding, so it was relatively simple to make a few small changes and use that code for my own enemies. However, the pathfinding code was only good for just that, path finding. Not to say this wasn't very helpful to already possess the ability to make our tanks find a "location". I next had to determine how the tanks would shoot intelligently. I spent some time drawing up ways that the tanks could use the grid to find some sort of line of sight and developed a few ways that probably required a bit too much coding and or processing power, or were just otherwise too complicated to make any sense. It was at this point that Bresinghan's line algorithm was suggested. This pretty much solved the problem outright. Implementing it took a bit of code conversion but it didn't cause too much trouble. Once I had a way to determine line of sight, my next step was to give the enemies some relatively intelligent way of using it. My solution was to create a switch statement in method called modeOfAggression (see enemyTank.cs code). This method took a random number as a parameter and then used that number to determine which case to use. This way, the enemies had some unpredictability since the user would never really know which method the tanks would take next in their goal to eliminate the human tank. On top of the random integer determining which mode, their were varying randoms to determine how long each case would last as well. Once we had the game in it's full on working state I was able to go back and adjust some of these values to give the enemies an improvement on their behavior. For instance, one of the modes of aggression was to "unload" where they would just sit at their current location and fire shots at the user. Now this is definitely a useable strategy, however if the tanks just sat their for half the game and did this, it wouldn't be very interesting, nor intelligent, nor fun in my opinion. So the random which determines a change of mode after the "unload" case is called is only a second or 2. Although for a case like "findClear" which looks at the surrounding 30 or so tiles to find an unobstructed line of sight will last a bit longer because it would make more sense to find an unobstructed shot than to just sit in one spot and fire.
Picture Sequence 2: These are a few screens to show the enemy tanks in action as well as the walls created by the blocks.
To get the enemy tanks looking like tanks with working treads and rotatable turrets I really just borrowed the code written by Andrew and Pete and made a few changes to suit the enemies rather than the user.
Another task that I worked on towards the end was the placing of obstacles (wood blocks, rocks, shells, etc.) throughout the levels. Greg had originally written the code to randomize this process but we had issues with blocks spawning on top of each other and wanted to have a more systematic approach where obstacles could form walls and corners. I changed the code around a bit so that it basically had a quota of 8 blocks per quadrant and their are some random number generators to determine how many blocks are placed in each group but none will surpass 8. Although alot of the work I did here was sort of experimentation I have to admit I like the outcome. The blocks now form effective looking walls as well as L-shaped corner structures and they vary quite a but from map to map.
Here is my code, although other group members have made changes to it over the course of the project, this is generally where all my work was done.