Design and Implementation
At any given time, there are several characters, each with similar characteristics. Therefore, I created a class person which contains information such as the X, Y, and Z coordinates, direction facing, health, and time before being to punch again. A capability of GLUT, I created a glutIdleFunc called idle. This game, unlike our other programming assignments this semester, would need to operate in real time. Even though the user may not be inputting any information, the computer must still move its characters around. In addition to moving characters, this function also contains the computer AI for punching. If the computer is within striking distance of the player, it randomly decided whether or not it actually punches. After reading several books and tutorials, I decided to try using GLAUX to load in my images. This is done in the LoadGLTextures function, which is called in the initialization. Instead of loading targa image files, LoadGLTextures deals with bitmap bmp files that are some power of 2 in size. For example, my program uses bitmaps that are 128 x 128 in size. To handle user input, I use the glutSpecialFunc and glutKeyboardFunc. I first discovered the glutSpecialFunc while doing assignment 4, the Rubiks Cube (it turned out to be good timing as I was able to reply to a request for help on that subject). It is very similar to the glutKeyboardFunc that we were using from earlier, but reads in an integer instead of a character as a parameter. The glutKeyboardFunc also contains the code for the lighting in my project. This was done in an effort to reduce the number of functions. Lights are turned on or off in this function alone, since they are all controlled by the user. In retrospect, it was probably not a great idea, since the keyboard function should only handle keyboard duties. I should have created a separate lighting function. It allows the user to control eight lights, the maximum provided by most implementations of OpenGL. I use a questionable method to draw the characters on the screen. Instead of doing translates and rotates to draw the figures, I use hardcoded points that are relative to the characters X, Y, and Z position. There are different points depending on the characters direction, or the step or punch they are taking. To save some computational time, I create 38 temporary variables and do the addition and subtraction very early. This prevents the computer from having to recalculate many times. Depending on which person the user has chosen to play as and against, I texture map the face, color the hair, and give everything material properties. I found that without this, everything turns gray in a spotlight, which was not my intended effect. After drawing the rest of the bodies, the display function draws the rest of the scene. The road is one giant black quad with dashed white lines and solid yellow lines on it. However, after implementing lighting, I learned that OpenGLs lighting implementation will only affect the vertices it touches. Since the solid yellow lines were enormously long, they were not affected by the lights. In order to create a more realistic scene, I split the lines into very thin quads. This way, the lights would hit the vertices, and OpenGl would implement the lighting more properly. I declined to do this for the asphalt road as well as the dashed white lines. The road itself is too big, generating a similar lighting effect would require too many small quads. The dashed lines were, in my opinion, fine as they were. In order to spruce up the background, I added a texture mapping of the White House. The main function is very similar to the one given to us in the beginning of the semester. The only change worth noting is that double buffering is enabled to provide smoother movement. The DirectX version of my program includes several functions that were adapted from other resources. Because it is a Win32 application and does not use GLUT, I needed to learn how to create a window myself. After doing that, I needed to use its information to enable OpenGL, DirectSound, and DirectInput for it. At this point, the window acted very similar to one created in GLUT, with the exception of a DOS box and the ability to resize. In order to read input from the keyboard and joystick, I needed to create each device, set its cooperation level, and acquire it. The joystick takes an extra step, requiring me to enumerate it first. After this is done, I am able to poll the keyboard and joystick and read multiple things at once, unlike using GLUT. This does bring up an additional problem, which allows the user to press up and down at the same time, for example. DirectInput also simplifies reading from a keyboard by putting having DIK_ constants for every key. GLUT required two separate functions to handle alphanumeric characters and special keys. During testing, I found that the DirectX version was handling key presses too well. If I wanted to toggle a light, I needed to tap the key very quickly, or hope that it would not switch back. Simply pressing a key constitutes holding it down for DirectInput. While this can definitely be thought of as an advantage, it hampered my ability to port my GLUT code to DirectX.
Previous Page
Next Page