During the first week of class, I worked on Torque Game Builder/TorqueScript tutorials and worked with my group to plan our game that we would develop over the course of the month.
Our game design began in the second week of class. In addition to designing the GUI screens and buttons, I worked with Hannah to develop a functional GUI and to implement high score functionality. In the last few days of class, all members of our group worked together to combine our respective pieces of code into a single file and to debug this code, but my primary responsibility in preceding weeks was to work with Hannah develop a functional in-game timer and a high score system.
High Score System
Originally, we intended for our high score system to be simple: the game would not save high scores when the user quit the game, and only the best score (or, in our game, the shortest time to go from the first iceberg to the last) would be stored during the game. However, Hannah and I decided to make our game's high score system more extensive by storing the top 10 high scores (accompanied by the name of the person who received a particular score) on a user's computer so the scores could be read in at the beginning of the game, adjusted as necessary during the game, and then stored at the end of gameplay. We called it a "universal" high score system, since, in theory, a user could open and close the game at will without losing his high scores.
To develop such a system, we decided to store the scores in a text file rather than in global variables, since all variables in the game exist only when the game is open. In order to store a text file, we needed file input and output functionality. After doing extensive research, we developed a system to read in a text file, take the scores out of the text file and store them in global variables during gameplay, and then rewrite the updated high score table to the text file at the end of the game. We did all of our programming in Torque Script. Using the FileSystem class for file input and output, we created five functions that would be executed throughout gameplay:
- initializeHighScores(): this function would be called every time the user opened a new game. Using the isFile method from the FileSystem class, the function would first check to see if the text file, highscores.txt, existed. If so, it would read in the data currently stored in the file; if not, it would create the file and fill it with 10 fake high scores that the user would easily replace upon finishing the game. To read in the high scores, we created a temporary FileObject object, %file, that would read line by line and would store the names and accompanying high scores in two global arrays, $lineName and $lineScore. Since the object would be temporary, %file would be deleted at the end of the function.
- writeHighScores(): this function would be called right before the game was about to exit (i.e., when the "Play Again" button was pushed or when the user quit the game). It would go through the two global arrays, open the highscores.txt file to be written, and store the global data in the text file. This function would also use a local FileObject file.
- checkHighScore(): this function would be called as soon as the user reached the final iceberg. This function would check the user's time (stored in the $diff variable) against the "worst" of the top 10 high scores to see if the user's time was better. If so, a new high score would have been achieved, and this function would call newHighScore().
- newHighScore(): this function would be called whenever the user received a new high score. The first line of the function,
$lineName = enterName.getText();, replaced the previously worst high score name with the current user's name (as input in the previous GUI screen in a GuiTextCtrl object, "enterName"). The next line set the previously worst time to the most recent user's time. Then, the function executed a series of comparisons and swaps to move the new user's time into the correct place on the high score table. Although a basic insertion sort like this one is extremely inefficient for large amounts of data, our function was limited to a table of 10 high scores, so in the worst case, approximately twenty comparisons and twenty swaps would be performed. After placing the new high score and new user in the appropriate place, the function would clear the old high score GuiTextCtrlList objects (highScoresRank, highScoresName, and highScoresTime), so the new table could replace them.
- updateHighScores(): this function would be called at the end of the newHighScore function. It takes the newly-updated data in the $lineName and $lineScore arrays and puts it in the high score GUI.
The code for these functions, contained in the FileIO.cs file, is attached, and screenshots of the high score system working can be seen in Hannah's portfolio. We developed and implemented the code for this system together.
Unfortunately, when the time came to combine our code with the gameplay and artwork generated by other members of the group, we were (tragically) unsuccessful. For an unknown reason, the isFile function did not work correctly on any other computer--instead of returning false when no file existed, the function always returned true, even when there was no highscores.txt file. Therefore, the "dummy" high scores that should have appeared when the game was opened for the first time were never imported to the game. This malfunction caused the rest of the high score system to fail.
In the end, Hannah and I created a separate end-of-game GUI that displays the the time that the user took when he or she reaches the end of the game. There is no high score screen; instead of the complex GUI system that we originally created (where the user can view high scores or play/play again on virtually every screen, in addition to a "new high score screen" that displays the user's time and allows him to enter his name for the high scores list), we had to simplify the game to display either a "Game Over" screen (when the user falls into the water before reaching the end of the game) or a "Nice Work" screen (when a user completes the game). Pictures for these screens can be seen in our GUI presentation and in Hannah's portfolio.
- Designed all GUI images and buttons using Photoshop and artwork created by Sarah. A few examples of the screens and buttons are shown below:
- Worked with Hannah to create a functional timer. The timer uses a function from the t2dSceneGraph class, getSceneTime(), which returns the time that has elapsed since a scene graph was opened. Every .1 seconds during gameplay, a function that we created, updateTimer(), executes getSceneTime() and sends the time to a GuiTextCtrl object in the main screen GUI.
- Worked extensively with Dan and Kevin during last week of class to integrate GUI and debug the final version of the game (although the code worked well on our respective computers, debugging the finished code was much more complext than we had originally anticipated).
- Completed in-class assignment involving art search (view my results here).