230 likes | 390 Views
Timers. Computer Programming 2. Game Idea: Mob Reaction Timer. Use a timer variable to keep track of time and a variable for each player to measure the reaction time of that player. Those variables are declared in the following code : // Game World int timer ; // Gamepad 1 scores
E N D
Timers Computer Programming 2
Game Idea: Mob Reaction Timer • Use a timer variable to keep track of time and a variable for each player to measure the reaction time of that player. • Those variables are declared in the following code: // Game World int timer; // Gamepad 1 scores int ascore1; int bscore1; int xscore1; int yscore1;
Game Idea: Mob Reaction Timer • The timer starts counting up from zero when the sound plays. • Each time that XNA calls the Update method, the value in timer is increased by one and the program checks to see if the player has pressed his or her button. • If the button has been pressed, the value of the timer is copied into the score variable for that button. • The player with the lowest value is the winner.
Game Idea: Mob Reaction Timer • The first problem we have to solve is how to start the game. • If the sound is produced as soon the game begins, the player who starts the game has an obvious advantage. • One way to make this work is to make the timer a negative number when the game starts and increase it each time Update is called. • When it reaches the value 0, the sound is played and the game starts counting
Game Idea: Mob Reaction Timer • Each time Update is called, the flow in Figure 8-1 is performed. • If the Start button is pressed, the timer variable is set to –120. • Each time Update runs, the value in timer is made one bigger. • When timer reaches zero, the sound is played. • When a button press is detected, the program copies the current value of timer into the score for that button. • If a player presses a button before the sound has been played, he or she has a negative timer value. • The player who gets the smallest positive value is the winner.
Game Idea: Mob Reaction Timer protected override void Update(GameTimegameTime) { pad1 = GamePad.GetState(PlayerIndex.One); if (pad1.Buttons.Back == ButtonState.Pressed) { this.Exit(); } // start a new game if (pad1.Buttons.Start == ButtonState.Pressed) { timer = -120; ascore1 = 0; bscore1 = 0; xscore1 = 0; yscore1 = 0; } timer++; // update the timer // play the sound at the start of the game if (timer == 0) { dingSound.Play(); } // if A is pressed copy the timer if (oldpad1.Buttons.A == ButtonState.Released && pad1.Buttons.A == ButtonState.Pressed) { ascore1 = timer; } // repeat for buttons B, X and Y oldpad1 = pad1; // repeat for gamepads 2, 3 and 4 base.Update(gameTime); }
Reaction Timer Bug • If you look at the code in the Update method, you find that there’s nothing to stop a naughty player from pressing his or her button lots of times. • There’s no penalty for pressing the button before the sound plays because the player can just press the button again. • You’ve designed the game without allowing for the fact that players might cheat
Possible Solutions to the Bug • The problem occurs because you’re not detecting when the player releases the button as well as when it’s pressed. • The problem occurs because you should be using level detection on the buttons, not edge detection. • The problem occurs because you should register only the first press of the button. • The problem occurs because you need to reset the gamepad after it’s been read.
Which Solution is Best? • The problem occurs because you’re not detecting when the player releases the button as well as when it’s pressed. • The problem occurs because you should be using level detection on the buttons, not edge detection. • The problem occurs because you should register only the first press of the button. • The problem occurs because you need to reset the gamepad after it’s been read.
Reaction Timer Bug Fix • The program works by copying the value of the timer into the score for each player. • When the Start button is pressed, the program loads zero into the score values for each of the players. • The very first time the player presses his or her button, the zero is replaced with a time value. • Next time he or she presses the button, the score is not zero, so you should not update this value.
Reaction Timer Bug Fix // if A is pressed and ascore1 is 0 copy the timer if (oldpad1.Buttons.A == ButtonState.Released&& pad1.Buttons.A == ButtonState.Pressed && ascore1 == 0) { ascore1 = timer; }
Finding Winners Using Arrays Xna Game Studio 4.0
Creating an Array • A variable that holds a list of values is called an array. • Arrays can be declared and initialized just like any other C# variable: dataType[] arrName = new dataType[size]; • Example int[] scores = new int[4]; • This declares an array variable called scores that can refer to one-dimensional integer arrays and makes it refer to a new 4-element array instance.
Creating an Array • You can think of an array as a row of numbered boxes, each of which can hold a single value. • A single “box” in an array is called an element. • Note that the first element is at the index position 0. • The index position can also be called a subscript.
Using Data in an Array • Example of using an array. if (oldpad1.Buttons.A == ButtonState.Released && pad1.Buttons.A == ButtonState.Pressed && scores[0] == 0) { scores[0] = timer; } • This code uses the first element in the array, scores[0], instead of a variable called ascore1. • You can use scores[1] as bscore1, the score for the B button on gamepad 1 and so on.
Using Data in an Array • You can use a for loop construction that takes the value of i from 0 to 3 (remember that when the value of i reaches 4, the test “i less than 4” fails and the loop stops). • The value of i is used as a subscript for the array access. for ( int i = 0; i < 4 ; i++ ) { scores[i] = 0; } • If you step outside what are called the boundsof an array, your program is stopped in its tracks by an exception because this is just not allowed to happen in a proper language like C#.
Scanning an Array • You use an array to help you find the best score. • You can’t say to the C# compiler, “Look along the row and find me the winner.” • You will have to provide code.
Scanning an Array intwinningValue = 120; for (int i = 0; i < 16; i++) { if (scores[i] > 0) { if (scores[i] < winningValue) { winningValue= scores[i]; } } } string winnerName; if ( scores[0] == winningValue ) { winnerName= "Gamepad 1 button A"; } if ( scores[1] == winningValue ) { winnerName= "Gamepad 1 button B"; }
Using an Array as a Lookup Table • Find out the position in the array of the winning score intwinningValue = 120; intwinnerSubscript = 0; for (int i = 0; i < 16; i++) { if (scores[i] > 0) { if (scores[i] < winningValue) { winningValue= scores[i]; winnerSubscript= i; } } } • winnerSubscript that holds the position in the array of the winning value
Using an Array as a Lookup Table • Now that you have the subscript value of the winning score, you can use it in another array to find the string that describes that player. • This is an array of strings of text. There is an element in the array for each of the buttons on gamepad 1, and the names are lined up with the buttons that are tested.
Using an Array as a Lookup Table string[] names = new string[] { "Gamepad 1 A", "Gamepad 1 B", "Gamepad 1 X", "Gamepad 1 Y" }; No Size Needed with Initializer List
Displaying the Winner A good time to display the winner would be two seconds after the sound was produced, which is when the timer value reaches 120. By then, all the players should have pressed their buttons.
Displaying the Winner protected override void Update(GameTimegameTime) { pad1 = GamePad.GetState(PlayerIndex.One); if (pad1.Buttons.Back == ButtonState.Pressed) { t his.Exit(); } // start a new game if (pad1.Buttons.Start == ButtonState.Pressed) { for (int i = 0; i < 16; i++) { scores[i] = 0; } winnerName= ""; timer = -120; } // update the timer timer++; // play the sound at the start of the game if (timer == 0) { dingSound.Play(); } // if A is pressed and scores[0] is 0 copy the timer if (oldpad1.Buttons.A == ButtonState.Released && pad1.Buttons.A == ButtonState.Pressed && scores[0] == 0) { scores[0] = timer; } // Repeat for other buttons and gamepads if (timer == 120) { intwinningValue = 120; intwinnerSubscript = 0; for (int i = 0; i < 16; i++) { if (scores[i] > 0) { if (scores[i] < winningValue) { winningValue= scores[i]; winnerSubscript= i; } } } if (winningValue != 120) { winnerName= names[winnerSubscript]; } else { winnerName= "**NO WINNER**"; } } base.Update(gameTime); }