For our design project, we decided to replicate the video game known as Scorched Earth: The Mother of All Games where two tanks fire missiles at one another by adjusting angles and power while adjusting for variable wind.
The objective of Scorched Earth is to destroy the enemy tank before your tank is destroyed. Two tanks are randomly positioned on their respective sides on a randomly chosen terrain. Through a trial and error process of adjusting angles and the strength of the tanks turret, each user can manipulate the trajectory of the bullets to eventually target the enemy tank. With three different weapons of different blast radii and three unique difficulty levels that incorporate variable wind speeds, the users can test their abilities as the most accurately firing tank. We wanted to recreate this game to allow players to relive childhood memories.
High Level Design
Rationale, Sources, and Hardware/Software Tradeoffs
The foremost reason we chose to simulate Scorched Earth was because no one had recreated this game as a final project during past years. Furthermore, we wanted to create a video game because we would not have any limitations within our budget regarding additional hardware. Since we do not have many sources for additional parts, an advantage that other groups possessed, a project that consisted entirely of code would allow us to make a project that was still fun and still extremely complex and challenging. The necessary hardware to run our project was simply the digital to analog converter circuit that displayed our program onto the television. After completion of the project, we also added sound (a pitch that gradually decreased as a bullet was in motion), which required very simple circuitry that also connected to the television.
We originally had other video game ideas in mind, but with the help of fellow ECE and housemate, Brandon Richter, we rediscovered this particularly entertaining game that immediately found its way to our hearts. During the brainstorming processes of recreating this game, we basically decided to implement everything that we successfully completed. We wanted to randomly draw terrains at the start of each game; however, this would have been too complicated since our code was dependent on the arrays of previously created terrains.
Upon starting the game, a startup screen displays a sample terrain and the two tanks as normally seen during an actual game. Scorched Earth and a difficulty of easy as its default setting are also shown on the screen. By pressing the debounced button C.6, the difficulty levels rotate from easy to med (medium), med to hard, and then hard back to easy. An easy difficulty level has zero wind effect on the bullets during the game, while a medium difficulty level has a constant wind throughout the entire game, and a hard difficulty level has a variable wind after both players have completed a round of firing a bullet.
To begin the game, the user must press C.7 to clear the screen and display a randomly chosen but previously created terrain. Player 1s tank will always be located on the left half the screen while player 2s tank will always be located on the right half of the screen. Along the top of the screen is an information bar that displays which players turn it is to fire, the power of that players shot, the angle at which that tanks turret is pointing, the weapon chosen, the number of remaining shots of that weapon, and the speed and direction (east or west) of wind. By using buttons C.4 and C.5 to increase and decrease the angle of the tanks turret and by using buttons C.2 and C.3 to increase and decrease the power of the tanks shot, the user can adjust the trajectory of their shot. At the default setting, weapon 1 is displayed on the screen with infinite number of shots. Using C.1, the user can cycle through to weapon 2 or weapon 3, of which each tank only has 3 and 1 bullets available during each game. As the user uses either weapon 2 or weapon 3, availability of the bullets, denoted with single pixels, will decrease in number. The user must then use button C.6 to fire the bullet. The settings used for the first player to go are saved and the second player can now perform the same procedure with the original default settings that will also be saved upon firing a shot as well.
Once a tank has been hit, a message that reads who is the winner will show up. To play another game or to simply see the number of accumulated wins each player has since reset, the user must press C.7. This clears the screen and displays the number of wins that each player has. Play Again is also displayed on the screen, and to do so, the user must press button C.6 to clear the screen again and redisplay another randomly chosen map and random starting positions for each of the tanks.
The standards that we used are the same as those in Lab 4 (Cornell University, ECE 476, Spring 2004): RS170 standards with the NTSC rate. The RS170 standard includes three voltages for black, white, and sync pulses with an aspect ratio of 4:3. The scan frequencies of the horizontal and vertical sync pulses are 15.75 KHz and 60 Hz respectively. The standard includes 525 interlaced lines per frame with 60 frames per second; however, we will be outputting a duplicate line for new line created.
Patents, Copyrights, and Intellectual Property
The foremost important copyright that must be addressed is the person(s) who originally created the game known as Scorched Earth. Unfortunately, since we are not able to find the names of those who deserve our appreciation, we can only publish the official website for the game: http://www.classicgaming.com/scorch/. However, must also thank Cornell Universitys Professor Bruce Land for providing the basic code for NTSC video, obtained from Lab 4 as previously mentioned. Professor Land also provided the basic code for sound implementation from the STK500 to the audio input on the back of the television. We must also obviously thank Professor Land for the knowledge that we have gained by taking his course (ECE 476).
Hardware and Software Design
Since our final project is a video game, our sole hardware necessary was the microcontroller unit, located on the STK500, pushbuttons to operate the game, also located on the STK500, and the video digital to analog converter shown in the design schematic below. We used PORT C for the pushbuttons and PORT D for the circuit to implement the television. The circuit was connected was wired to the yellow connector on the TV using clip leads and a RCA phone jack. The TV was set to video input.
Since we were able to use Professor Bruce Lands video generation code, all we had to do was write the code for the game and were able to use the video generation code to output all our date. In general the code was pretty straightforward to write and we didnt have any major problems with it. Our biggest problem was timing restrictions which forced us to break up our output into multiple frames/states so that we would not get artifacts.
The start screen has the game name, Scorched Earth, and a map with two tanks as the background. At this screen you are allowed to choose the difficulty of the game. There are 3 difficulties: Easy which has no wind, Medium where wind is randomly generated but doesnt change for the rest of the map, and Hard where wind changes after each player has shot.
Clear Screen/Draw Map
One of the trickier parts of the code were erasing the screen and drawing a new map. It took us a few tries to figure out how many lines we could draw or erase in each frame without causing artifacts to occur. We finally decided on only drawing or erasing 3 lines per frame to ensure that no artifacts would occur. We have 5 pre-generated maps that have been stored into memory of our cpu. We used a random number generator to randomize which map would be chosen. We also used a random number generator to randomize the starting location of P1 and P2.
We used a random number generator after drawing the maps to randomize which player gets to go first. At the start of the players turn, the player is allowed to change his power, angle and weapon, and fire when he feels he is ready. The values for power went from 0 to 99, the values for angle go from 0 to 180 and the weapon is cycled from 1 to 3. We debounced all the buttons used to increment/decrement the power, angle and weapon. We used a timed increment so that power and angle would be changed by one every quarter second. First we had it such that each button press would result in a change of one, but we found it tiresome to press a button 15 times, and it was much easier just to hold the button down. And for the weapon since it was only cycling through 3 possible values, we just decided to leave it as a simple debounced button where each press increments the value by 1. Also weapons 2 and 3, which are considered super weapons, have a limit on the number of shots available. Weapon 2 only has 3 shots while Weapon 1 only has 1 shot. Once the bullet is fired the trajectory of the bullet is calculated, how this is done is explained in the next section. Also you are not allowed to fire if you have no more shots left of the selected weapon.
First thing we did to determine the trajectory of our bullet was to divide the power of our shot into x and y components (xpow, ypow) using the sine and cosine functions. We had a start position (xpos, ypos) which was at the top of the turret of the tank and we changed these values by a factor of the power (xpos = xpos+xpow/25, ypos = ypos-ypow/25). Once we changed the position variables we changed the power variables, the xpow would be changed by a factor of wind/25 and ypow was reduced by one every frame to account for gravity. This caused us to skip a few points because at our highest power of 100 it was possible to skip 3 pixels ever frame and it was possible that our shots would skip over the top of the tank or not hit the top of the terrain but instead hit somewhere lower. In order to correct this we scaled our changes by so that we wouldnt skip any points, for example xpos now equaled xpos+xpow/100 and xpow = xpow + wind/100 and ypow = ypow – . This ensured that at full power we would only be moving one pixel, and though this increased the time it took for the bullet to travel from one point to other, it made the point of impact much more accurate. Also the xpos and ypos variables were stored into other variables (prevx,prevy) so that we know what the last position of the bullet was and delete it.
We decided to make the left and right walls absolute boundaries. If any of the shots hit these boundaries that players turn would end, we assumed that if the shot has passed the edge of the screen that it was shot too far and thus will not hit. The top of the screen however was not an absolute boundary, any shot went higher had a chance of coming back. We just stopped our program from drawing new points or erasing old points if the bullet went higher than the top of our screen, and we resumed drawing and erasing once the bullet re-entered the screen. This allows the player to take high shots to get over hills that they might be next to without worrying about hitting an absolute boundary.
End of Round
The round ends when one of the tanks is struck by the bullet. Regardless of which player shot the bullet, the player whose tank is hit loses and the other player wins. At this point we print out a message letting the players know which player has won the round. Then by pressing fire you go to another screen, where you have the option of changing the difficulty, this screen also shows the number of games each player has won. By pressing start at this screen you can start a new game. At this point all your weapons are refilled and once again which player starts is randomized.
The final part of our code that needs to be talked about is the sound effects. During the shot when the trajectory is being calculated we have a note which increases in pitch every quarter second. The timebase of quarter second was achieved by using a variable to count up to 15, and since each time it increments corresponds to one frame and each frame is 1/60th of a second, the counter hits 15 at approximately quarter second. We set OCR0 to 60 and ran timer0 without interrupts enabled on a prescaler of 100, to generate our initial note and every quarter second we incremented OCR0 by 1, to increase the pitch and thus make our sound a little more realistic. Also when a player tank is hit we have a much higher pitched sound with an OCR0 starting and 195 and going to 193 in order to create a sound for three-quarters of a second to simulate the explosion of a tank getting hit. Though since I, Karthik, did the sound in my free time and am not musically talented the sound is most likely quite a bit lacking in their effect.
As I mentioned earlier in this section we had no major problems with this code. The only part of the code that was tricky to figure out was trying to keep the artifacts from occurring when our bullet crossed our boundaries. When the bullet left the top it would erase part of the line or the last bullet location drawn would not be erased. This was a little tricky for us because we tried to play with which point we called our boundary, this was usually the pixel before the actual line itself, and we still ended up with the stray unerased bullet. We finally fixed this problem when we noticed that when we ended the turn due to the boundaries we would not erase the previous point because we would be skipping a state when compared to if the bullet had hit terrain. Once we figured this out it was easy to make the change and remove the stray unerased bullet point. Other parts of our code such as timing constraints for drawing the map, though they werent tricky took some experimenting to make sure that they were efficient.
Given our budget constraint of $40.00, we were well within our limitations, as seen:
STK500 Development Board
For more detail: Scorched Earth video game using Atmel Mega32