TGB/ScriptTutorials/ScoreTutorial

From TDN

Contents


Introduction


This tutorial will show you how to add a basic counter to keep track of the score in a game. Adding the GUI elements and hooking them in to our script will be covered. The following is written for beginner level users of TGB and will feature editing of the ExampleMyFishGame project. This is not a tutorial about how to use the GUI editor, basic knowledge of it is expected.


The Level Builder


Opening an existing Project


This tutorial assumes you have never made changes to the ExampleMyFishGame - either in the level builder or in script. To start off, open the project (File > Open Project...).

You should now see a screen similar to this:


Figure 1.1

We need to add something in script before we start editing though, so exit out of the level builder now. Load up the main.cs file in the ExampleMyFishGame folder.



GUI Profiles

In the main.cs file, we are going to add a new GUI profile. Profiles allow you to easily create a template for how GUI elements should appear. Our score elements will be purely text based, so this profile is going to set the size of the font and the color. Add this to the top of the main.cs file above the initializeProject function:

new GuiControlProfile (GuiText24WhiteProfile : GuiTextProfile)
{
   fontSize = 24;
   fontColor = "255 255 255";
};

This should be easy to understand, we are naming this profile GuiText24WhiteProfile and it's parent is the base GuiTextProfile. The font size is 24 and the color is set to white (255 255 255).

Save the script file and load up the Level Builder again.


The GUI Editor


The first thing we will add are the GUI elements needed to let the player know what the score is. To access the GUI Editor go to Project > GUI Editor.... You should now see the level builder inside the GUI editor window. We don't want to edit the level builder GUI, only our in game GUI. To switch GUIs, at the top of the screen there are 3 pull down menus. The middle menu is a list of all initialized GUIs. Find and select mainScreenGui from the list. You should now see a black screen like Figure 1.4:

Image:TGB_ScoreTutorial_2.jpg
Figure 1.2

Image:TGB_ScoreTutorial_3.jpg
Figure 1.3

Image:TGB_ScoreTutorial_4.jpg
Figure 1.4

To add a text based GUI element, in the first drop down menu called "New Control" select the GuiTextCtrl. You can drag the text control to the bottom left corner of the screen or alter the position directly in the position field to 16 431. In the extent field, change it to 67 34. Above in the general rollout, type Score: into the text field. We also need to change the profile to our GuiText24WhiteProfile and set the HorizSizing and VertSizing to relative.

Image:TGB_ScoreTutorial_5.jpg
Figure 1.5

Now create another GuiTextCtrl. Set the position of this new text control to 84 431. The extent can be 67 34 like the our Score: text. For this control we are not going to put anything into the text field, this will be controlled via script. To let our future script calls recgonize this GuiTextCtrl, set it's name to score and click apply. Change the profile to our custom profile and sizing to relative.

Image:TGB_ScoreTutorial_6.jpg
Figure 1.6

Image:TGB_ScoreTutorial_7.jpg
Figure 1.7

And that's it for our GUI. Before we exit the GUI Editor, save the GUI (File > Save GUI...). We are going to overwrite mainScreenGui.gui so make sure it gets saved as this. If you exit the GUI editor now, you will not be back in the Level Builder! We need to change our GUI back to LevelBuilderBase, which if you remember, is done from the middle drop down menu.

Now exit out of the Level Builder, it's time to do some more scripting.


Get Rewarded...for Eating


If you have played with the stock Fish Game before, you know the goal is to eat the little bubble like "food" while avoiding the mines. We are going to keep things simple and only reward the player with an increase in the score when our fish successfully eats food.

Open up the FishFood.cs file in the ExampleMyFishGame/gameScripts/ folder and change the onLevelLoaded function to look like this below:

function FishFood::onLevelLoaded(%this, %scenegraph)
{
   %this.startPositionY = %this.getPositionY();
   %this.setLinearVelocityY(getRandom(%this.minSpeed, %this.maxSpeed));
   
   // Initialize the score to 0 and display it.
   $score = 0;
   score.setText($score);
}

As the comment in the code suggests, we are creating a $score global variable and setting it to 0. The next line is telling our score GUI text control to display the value of $score. We have a lot of things named similarly, hopefully it is clear as mud. To repeat, we have a global variable now named $score, which will keep track of the score value. We have a GuiTextCtrl named score which originally we left blank and now through script are using the setText function to display the actual score. There is also the GuiTextCtrl which does not have a name but only contains the text "Score:".

Our score is now 0, let's allow a way for the player to increase the score. In the same script file, scroll down and find the FishFood::onCollision function. Change it to look like this:

function FishFood::onCollision(%srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
   if(%dstObj.class $= "PlayerFish")
   {
      %srcObj.spawn();
      %dstObj.modifyLife(%srcObj.lifeValue);
      
      // Take our score and add 10 points.
      $score = $score + 10;
      score.setText($score);
      
   } else if (%dstObj.class $= "Fish")
   {
      %srcObj.spawn();
   }
}

What we just did is when the fish food collides with the player, our score increases by 10 points and the new value of $score is displayed on screen.

Save FishFood.cs and head back into the Level Builder. Try out the game now (though the play button), you should see our score displayed in the lower left corner of the screen and it increases whenever we catch food.

Image:TGB_ScoreTutorial_8.jpg
Figure 1.8

Thanks for reading!



End of original tutorial by Mike Lilligreen




Keeping Score: A New Hope

More like a new headache...



I worked my way through this tutorial the other day and I thought I would add on to it. What I am adding to our project is a high scores display screen, a new dialog box, and file input/output. I hope you find this useful. I consider this to be very messy code, but I haven't touched a programing language in 1-2 years, so I'm kind of rusty. I also just starting using Torque 4 days ago so bear with me if some of my methods seem kind of strange. Hopefully they don't too much.

Before you begin you should know that the way I designed this was a little stupid. The name and score should have been written on seperate lines instead of the same one. Also I should have used two GuiMLTextCtrls instead of just one. Regardless, you might still learn something.  :)

Enjoy,


Aaron Goselin 11:08, 19 September 2006 (PST)


Designing our GUI elements

The main screen GUI



Start up TGB and make sure MyExampleFishGame is loaded. Go into your GUI editor by hitting F9 and then F10 (or whatever your prefered method is.) We want to display our high scores, so the first thing we will do is add a few things and change a few things. You will be adding 4 GuiTextCtrl's and modifying 2 that are already there.

If you've read this far, you should definately know how to do this, so I will list data from my GUI files so you can verify settings (but I will delete every property I don't care about). Create everything listed and arrange it exactly or similar to how I have it.

   new GuiTextCtrl(scoreCounterTitle) {
      Profile = "GuiText24WhiteProfile";
      HorizSizing = "relative";
      VertSizing = "relative";
      position = "3 515";
      Extent = "75 25";
      text = "Score:";
   };
   new GuiTextCtrl(score) {
      Profile = "GuiText24WhiteProfile";
      HorizSizing = "relative";
      VertSizing = "relative";
      position = "75 515";
      Extent = "313 25";
   };
   new GuiTextCtrl(highScoresTitle) {
      Profile = "GuiText24WhiteProfile";
      HorizSizing = "right";
      VertSizing = "bottom";
      position = "310 109";
      Extent = "174 30";
      text = "High Scores Table";
   };
   new GuiTextCtrl(nameTitle) {
      Profile = "GuiText24WhiteProfile";
      HorizSizing = "right";
      VertSizing = "bottom";
      position = "251 160";
      Extent = "64 64";
      text = "Name";
   };
   new GuiTextCtrl(scoreTitle) {
      Profile = "GuiText24WhiteProfile";
      HorizSizing = "right";
      VertSizing = "bottom";
      position = "508 161";
      Extent = "64 64";
      text = "Score";
   };
   new GuiMLTextCtrl(scoreTable) {
      Profile = "GuiText24WhiteProfile";
      HorizSizing = "right";
      VertSizing = "bottom";
      position = "253 253";
      Extent = "360 240";
      lineSpacing = "2";
   };

Code 4.1: Data from mainScreen.gui


Image:guiObjectTree.gif
Figure 4.1: What your object tree should look like.

Image:scoreDisplayGuiDesign.gif
Figure 4.2: How your main screens GUI should look in the GUI editor.

Make sure you save your gui file (save over mainScreenGui.gui).


The Name Dialog



Now we are going to modify one of TGB's gui's. From the middle drop down box select MessageBoxOKDlg.

Image:selectMessageBoxOKDlg.gif
Figure 4.3: Selecting MessageBoxOKDlg.gui

Set it's name to namePopUpDlg. Select the GuiButtonCtrl. Change the command field to:

MessageCallback(namePopUpDlg,namePopUpDlg.callback);

Code 4.2: The command property of the OK button.


From the left hand (first) drop down menu select GuiTextEditCtrl. Set it's name to nameEntryBox. Set position to "34 61", and extent to "231 18".

Your right hand object tree should look like this:

Image:namePopUpDlgObjectTree.gif
Figure 4.4: What your object tree should look like for your name pop up dialog.

      new GuiButtonCtrl() {
         HorizSizing = "right";
         VertSizing = "top";
         position = "97 88";
         Extent = "110 23";
         Command = "getPlayerName();";
      };
      new GuiTextEditCtrl(nameEntryBox) {
         Profile = "GuiTextEditProfile";
         HorizSizing = "right";
         VertSizing = "bottom";
         position = "34 61";
         Extent = "231 18";
         maxLength = "5";
      };

Code 4.3: Code from namePopUpDlg.gui


Save this file as namePopUpDlg.gui. What we have just done is create a generic dialog box that can recieve input and can say a short message when you display the dialog.

Writing our Code

File Input / Output



Now load up your favourite text editor / IDE, it's time for code.

Create the new file fileIO.cs in your gameScripts folder. Add in the following code and save:

// ============================================================
// Project      :   ExampleMyFishGame
// File         :   .\gameScripts\fileIO.cs
// Copyright    :   © Indolent Games 2006
// Author       :   Aaron Goselin
// Editor       :   Codeweaver 1.2.2199.34718
// 
// Description  :   File input/output
//                 
//				:	Use this as you like.
//				:	I wouldn't post this if I had a problem
//				:	with it being used.  If you find it
//				:	particularily useful then feel free to
//				:	mention me in your credits or whatever.  :)
// ============================================================


// Note:  Your files will be located in data/files/

function writeFile()
{
	// Creating our object variable with which to control our file
	%file = new FileObject();
	
	// If file is open for write already then ok do code, if it
	// it is not open for write, open it.
	if(%file.openForWrite("~/data/files/score.sav"))
	{
		%temp = 1;
		
		// If file was empty, only write the current users name and score.
		if ($x == 0)
		{
			error("___________");
			echo("BEGIN WRITE\n");
			%file.writeLine($playerNameEntered @ "                                    " @ $score);
			echo($playerNameEntered @ $score);
			error("___________");
			echo("END WRITE");
			
			// Writing our lonely single score to the scoreboard.
			scoreTable.setText($playerNameEntered @ "                                    " @ $score);
			
			// Close the file, delete the object, and exit this function.
			%file.close();
			%file.delete();
			
			// Change the score text control to instructions.
			score.setText("P = Play Again      |     Q = Quit");
			
			$x = 1;  // Resetting the file counter.
			
			return;
		}		
		// If the counter is 1 or higher
		else
		{
			error("___________");
			echo("BEGIN WRITE\n");
				
			// If there was only one line read, print the current users name
			// and score and print one line from the array (all that should
			// be there.)
			if($x == 1)
			{
				%file.writeLine($playerNameEntered @ "                                    " @ $score);
				echo($playerNameEntered @ $score);
				%file.writeLine($lines.contents[%temp - 1]);
				echo($lines.contents[%temp - 1]);
				
				// Sending score to scoreboard.
				scoreTable.setText($playerNameEntered @ "                                    " @ $score
				NL $lines.contents[%temp - 1]);
				
				// Deleting the array, as it is no longer needed.
				$lines.delete();
				
				// Close the file, delete the object, and exit this function.
				%file.close();
				%file.delete();
				return;
			}
			// If the function has made it this far the file should not be
			// empty, or have only one entry.  To be clear, if we made it this
			// far, there is a file and it has more than one entry.
			
			// Putting the current player's name and score into the file first.
			%file.writeLine($playerNameEntered @ "                                    " @$score);
			echo($playerNameEntered  @ $score);
			
			// Now we write all the data from the array (or 9 lines anyway) into the file.
			// Including the entry right above here, that makes 10 scores.
			while(%temp != $x)
			{
				// If the file was empty
				%file.writeLine($lines.contents[%temp - 1]);
				echo($lines.contents[%temp - 1]);
				%temp += 1;
			}
		}
		
		error("___________");
		echo("END WRITE");
		
		%temp = 1;
		
		//-----------------------------------
		// Begin sending scores to scoreboard
		//-----------------------------------
		
		// Starting our string by putting the players name, a space,
		// and the score into the %scoreOutput variable.
		%scoreOutput = $playerNameEntered @ "                                    " @ $score;
		
		// Finishing off the string by adding on each line from the
		// array with line breaks after each one.
		while(%temp != $x)
		{
			%scoreOutput = %scoreOutput NL $lines.contents[%temp -1];
			%temp++;
		}
		echo(%scoreOutput);
		
		// Send the score to the scoreboard and we are done here.
		scoreTable.setText(%scoreOutput);
		
		//------------------------------------
		// Finish sending scores to scoreboard
		//------------------------------------
		
		// Change the score text control to instructions.
		score.setText("P = Play Again      |     Q = Quit");
		
		
		echo("File Written");
	}
	// This happens obviously if the file fails to open properly.
	else
	{
		error("File is not open for writing");
	}
	
	// Close the file, delete the object.
	%file.close();
	%file.delete();
}


function readFile()
{
	%file = new FileObject();
	
	// If file is open for read already then ok do code, if it
	// it is not open for read, open it.
	if(%file.openForRead("~/data/files/score.sav"))
	{		
		// Make sure the file isn't empty or broken or something.
		if(!%file.isEof())
		{
			$x = 1;  // Make sure our counter is set to 1.
			$lines = new scriptObject();  // Creating our array.
			
			// Read until the end of the file.
			while(!%file.isEof())
			{
				// Reading each line into a global array.
				%temp = %file.readLine();
				$lines.contents[$x - 1] = %temp;
			
				// Counting how many lines we read.
				$x++;
			}
		}
		else
		{
			// Set counter to zero (indicating an empty array/file.)
			$x = 0;
			error("File was empty!");
		}
		
		// If the second entry into the array is a blank line,
		// remove that index (so we can know there was only
		// one line.)
		if($lines.contents[1] $= "")
			$x -= 1;
		
		// Don't allow the file to keep more than 10 scores.
		if($x > 10)
			$x = 10;
		
		writeFile();
	}
	// This happens obviously if the file fails to open properly.
	else
	{
		$x = 0;
		error("File does not exist, creating it.");
		
		// File doesn't exist so creating it.
		%openAFile = new FileObject();
		if(%openAFile.openForWrite("~/data/files/score.sav"))
		{
			%openAFile.close();
			%openAFile.delete();
			writeFile();
			//readFile();
			//schedule(1000, 0, readFile);
		}
		else
		{
			// Ok now you are screwed, quitting.
			quit();
		}
	}

	%file.close();
	%file.delete();
}

Code 5.1: fileIO.cs


As you can see, the code is heavily commented. This is what I have chosen to do rather than step through my code with you. This file both writes to a file and reads to a file for you. All the logic is fairly well explained in the code I think...I hope. I'm getting pretty tired about now, and therefore lazy.

What we have built is a very simple IO system. Later if you like you can research CSV (comma separated value) format, which would be one way you could make the game actually sort the high scores and decide if the new score even qualifies. I may even update this later to include that, but for now we won't go into it.


I'm not a playa, I just code a lot



Now here come the modifications to player.cs. Hopefully it's pretty obvious where I have changed things, since everything is commented.

function PlayerFish::onLevelLoaded(%this, %scenegraph)
{
   $FishPlayer = %this;

   // Hides the score display...  It also shows the onscreen score though :)
   hideScoreDisplay();
   // Make the name entry dialog pop up
   MBOKText.setText("Please enter your name:");  // Sets the text of the dialog.
   MBOKFrame.setText("Player Name");  // Sets the title of the dialog.
   $fishGamePaused = 1;  // Effectively pauses the game.
   Canvas.pushDialog( namePopUpDlg );  // Displays the dialog.

   moveMap.bindCmd(keyboard, "w", "fishPlayerUp();", "fishPlayerUpStop();");
   moveMap.bindCmd(keyboard, "s", "fishPlayerDown();", "fishPlayerDownStop();");
   moveMap.bindCmd(keyboard, "a", "fishPlayerLeft();", "fishPlayerLeftStop();");
   moveMap.bindCmd(keyboard, "d", "fishPlayerRight();", "fishPlayerRightStop();");
   moveMap.bindCmd(keyboard, "space", "fishPlayerBoost();", "fishPlayerBoostStop();");

   // Setting keys p and q for Play Again and Quit respectively.
   moveMap.bindCmd(keyboard, "p", "playAgain();", "doNothing();");
   moveMap.bindCmd(keyboard, "q", "quitGame();", "doNothing();");

   %this.lowerLife();
}

function playAgain()
{
	// Check to see if we have the game paused, if so do this crap.
	if($fishGamePaused == 1)
	{
		error("This is happening.");
		// Resetting game variables.
		$fishPlayer.life = 100;
		$fishPlayer.dead = false;
		$fishGamePaused = 0;  // Unpausing the game.
		$score = 0;  // Resetting the score.
		$x = 1;  // Resetting the file counter.
		score.setText($score);  // Setting the onscreen score display to 0.
		
		// Put the fish back in position, flip him (or her) back, and stop
		// that incessant floating up that he/she so loves to do.
		$fishPlayer.setPosition("0.502 -5.574");
		$fishPlayer.setFlipY(false);
   		$fishPlayer.setLinearVelocityY(0);

		// Yeah...I don't need to go over this again. :)
		hideScoreDisplay();
		
		// Get things going again.
		$fishPlayer.lowerLife();
	}
}

function quitGame()
{
	// If game is paused when the user hits q then quit.  Really you want
	// a way for the user to be able to quit while the game is playing too
	// but you can do what you want.  I just thought q would be a bad in
	// game quit function.
	if($fishGamePaused == 1)
		quit();
}

function doNothing(){}

function SceneWindow2D::onMouseMove(%this, %mod, %worldPosition)
{
	//..
	// Enable this to make the fish move with your mouse, but
	// GUI interferes with it so you'd have to do it another
	// way or know how to fix that.  :)  This makes the game
	// way too easy anyway.
	//..
	//$FishPlayer.setPosition(%worldPosition);
}

function PlayerFish::updateMovement(%this)
{
   if(%this.dead)
      return;

   if(%this.moveLeft)
   {
      $FishPlayer.setFlipX(false);
      $FishPlayer.setLinearVelocityX( -$FishPlayer.hSpeed );
   }

   if(%this.moveRight)
   {
      $FishPlayer.setFlipX(true);
      $FishPlayer.setLinearVelocityX( $FishPlayer.hSpeed );
   }

   if(%this.moveUp)
   {
      %this.setLinearVelocityY( -$FishPlayer.vSpeed );
   }

   if(%this.moveDown)
   {
      %this.setLinearVelocityY( $FishPlayer.vSpeed );
   }

   if(!%this.moveLeft && !%this.moveRight)
   {
      %this.setLinearVelocityX( 0 );
   } 

   if(!%this.moveUp && !%this.moveDown)
   {
      %this.setLinearVelocityY( 0 );
   } 
}

function PlayerFish::modifyLife(%this, %dmg)
{
	if($fishGamePaused == 0)
	{
   		%this.life += %dmg;

   		if(%this.life > 100)
   		{
     		 %this.life = 100;
 		} 
		else if (%this.life < 0)
 		{
      		%this.life = 0;
   		}

   		if(%this.life <= 30)
   		{ 
			$fishGamePaused = 1;  // Let different functions pause.
      		%this.dead();  // Oh noes!  We be dead.
   		} 
		else
   		{
      		%this.updateLifeSize();
   		}
	}
}

function PlayerFish::updateLifeSize(%this)
{
   %lifeMultiplier = %this.life / 100;

   %newWidth = %this.maxWidth * %lifeMultiplier;
   %newHeight = %this.maxHeight * %lifeMultiplier;

   %this.setSize(%newWidth, %newHeight);      
}

function PlayerFish::dead(%this)
{
   %this.setFlipY(true);
   %this.setLinearVelocityY(-10);
   %this.dead = true;

	// Makes the score screen show up.
	highScoresTitle.setVisible(1);
	nameTitle.setVisible(1);
	scoreTitle.setVisible(1);
	scoreTable.setVisible(1);
	
	// Makes the score display (that shows when playing) disapear.
	scoreCounterTitle.setVisible(0);
	
	// Read the file, then write is called from read.
	readFile();
}

function PlayerFish::lowerLife(%this)
{
   %this.modifyLife(%this.lifeDrain);
   
   if(!%this.dead)
   {
      %this.schedule(500, "lowerLife");
   } 
}

function fishPlayerUp()
{
   $FishPlayer.moveUp = true;
   $FishPlayer.updateMovement();
}

function fishPlayerDown()
{
   $FishPlayer.moveDown = true;
   $FishPlayer.updateMovement();
}

function fishPlayerLeft()
{
   $FishPlayer.moveLeft = true;
   $FishPlayer.updateMovement();
}

function fishPlayerRight()
{
   $FishPlayer.moveRight = true;
   $FishPlayer.updateMovement();
}

function fishPlayerUpStop()
{
   $FishPlayer.moveUp = false;
   $FishPlayer.updateMovement();
}

function fishPlayerDownStop()
{
   $FishPlayer.moveDown = false;
   $FishPlayer.updateMovement();
}

function fishPlayerLeftStop()
{
   $FishPlayer.moveLeft = false;
   $FishPlayer.updateMovement();}

function fishPlayerRightStop()
{
   $FishPlayer.moveRight = false;
   $FishPlayer.updateMovement();
}

function fishPlayerBoost()
{
   if(%this.dead)
      return;

   %flipX = $FishPlayer.getFlipX();

   if(%flipX)
   {
      %hSpeed = $FishPlayer.hSpeed * 3;
   } else
   {
      %hSpeed = -$FishPlayer.hSpeed * 3;
   }

   $FishPlayer.setLinearVelocityX(%hSpeed);
}

function fishPlayerBoostStop()
{
   $FishPlayer.setLinearVelocityX(0);
}

Code 5.2: player.cs


This file does pretty much the same thing as before, except I have added a few things. First off it pops our dialog box and gets the player name from the user. It also includes functionality to pause the game and to display the high scores table when you die.

Goldfish are cheaper to buy than to feed




Despite my asinine way of labeling sections, this is almost our final file modification. The following is fishfood.cs, so eat it up.

function FishFood::onLevelLoaded(%this, %scenegraph)
{
   %this.startPositionY = %this.getPositionY();
   %this.setLinearVelocityY(getRandom(%this.minSpeed, %this.maxSpeed));

// Initialize the score to 0 and display it.
   $score = 0;
   score.setText($score);

}

function FishFood::onWorldLimit(%this, %mode, %limit)
{
   if(%limit $= "bottom")
   {
     %this.spawn();
   }
}

function FishFood::spawn(%this)
{
   %this.setPosition(getRandom(-50, 50), %this.startPositionY);
   %this.setLinearVelocityY(getRandom(%this.minSpeed, %this.maxSpeed));
}

function FishFood::onCollision(%srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts)
{
   if(%dstObj.class $= "PlayerFish")
   {
      %srcObj.spawn();
      %dstObj.modifyLife(%srcObj.lifeValue);
	
	// If the game is not paused, take our score and add 10 points.
	if($fishGamePaused == 0)
	{
      $score = $score + 10;
      score.setText($score);
	}

   } else if (%dstObj.class $= "Fish")
   {
      %srcObj.spawn();
   }
}

Code 5.3: fishfood.cs


I posted the whole file, but the only change to fishfood.cs is this:

	// If the game is not paused, take our score and add 10 points.
	if($fishGamePaused == 0)
	{
      $score = $score + 10;
      score.setText($score);
	}

Code 5.4: The only change to fishfood.cs


I didn't even write the stuff inside the brackets, but you need this minor change to make things work properly. This simply makes sure the score doesn't update when the game is paused.

Executions and other fun for the whole family




In game.cs make sure you have the following execs (and the code below the execs):

   // Load our new dialog box
   exec("~/gui/namePopUpDlg.gui");
	
   // Execute all our gamescripts
   exec("./fileIO.cs");
   exec("./player.cs");
   exec("./fishfood.cs");
   exec("./fish.cs");
   exec("./mine.cs");

   // Freshening up our file counter
   $x = 0;

Code 5.5: Execs for game.cs


Add this code to game.cs right after the startGame function:

$fishGamePaused = 0;  // Pause game flag

// When OK button is pushed, store textbox value and close the pop up.
function getPlayerName()
{
	$playerNameEntered = nameEntryBox.getValue();   // Stores the entered name as a global variable
	MessageCallback(namePopUpDlg,namePopUpDlg.callback);  // Closes the dialog box
	$fishGamePaused = 0;  // Unpause the game
	error("Entered name:  " @ $playerNameEntered);
}

// Hides the high scores display and shows the onscreen score
function hideScoreDisplay()
{
	highScoresTitle.setVisible(0);
	nameTitle.setVisible(0);
	scoreTitle.setVisible(0);
	scoreTable.setVisible(0);
	score.setVisible(1);
	scoreCounterTitle.setVisible(1);
}

Code 5.6: Code for game.cs


ZOMG, this is almost fun now.

Look at that, it still sucks, but not as much.



We now have a game that doesn't totally suck. There is actually a point to playing now, and a framework to make things even better. If you play around with this code and you have never worked with File IO, be aware that there are some slight dangers. If you get stuck in a loop that writes to a file, that file will fill up very quickly. Many times when I was working this out I did just such a thing, and a file being filled with blank lines can generate 15-30 megs in 30 seconds or so. Treat this code like your stove and don't leave while frying up some FileObject sandwhiches.




Some final screenshots



Image:consoleOutput.gif
Console output is good for the soul


Image:namePopUpInAction.gif
Hi, my name is:


Image:scoresDisplay.gif
Ah, nothing feels better than a job sloppily done.





Source code files



Here are the source files.

Media:GameScripts.rar


Additional Resources

High Scores Object -- For those who may wish for a slightly more advanced High Scores table, this resource allows for you to create a High Scores table that limits the number of entries based on a configured value, and orders the results from Highest to Lowest, this resource also provides Save/Load functionality and can easily be integrated into the above mentioned GUI Examples with little work involved (An example, or an update to this resource may follow).