00001
00002
00003
00004
00005
00006 namespace MontyHallGame
00007 {
00008 using System;
00009 using System.Threading;
00010
00011 using Microsoft.Xna.Framework;
00012 using Microsoft.Xna.Framework.Content;
00013 using Microsoft.Xna.Framework.Graphics;
00014 using Microsoft.Xna.Framework.Input;
00015
00016 using NewGamePhysics.StateManager;
00017 using NewGamePhysics.Utilities;
00018 using NewGamePhysics.GraphicalElements;
00019 using NewGamePhysics.PhysicalElements;
00020
00026 class MontyHallGameplayScreen : GameScreen
00027 {
00028 #region Fields
00029
00033 private ContentManager contentManager;
00034
00038 private ScrollingText scrollingInfoText;
00039
00043 private int[] doorState;
00044
00052 private int gamePhase;
00053
00057 private int selectorPosition;
00058
00062 private int preselectedDoor;
00063
00067 private int prizePosition;
00068
00072 private long waitTicks;
00073
00074 #endregion
00075
00076 #region Initialization
00077
00081 public MontyHallGameplayScreen()
00082 {
00083 TransitionOnTime = TimeSpan.FromSeconds(1.5);
00084 TransitionOffTime = TimeSpan.FromSeconds(1.5);
00085 }
00086
00090 public override void LoadContent()
00091 {
00092 if (this.contentManager == null)
00093 {
00094 this.contentManager = new ContentManager(ScreenManager.Game.Services, "Content");
00095 }
00096
00097
00098 doorState = new int[3];
00099 doorState[0] = 0;
00100 doorState[1] = 0;
00101 doorState[2] = 0;
00102
00103
00104 gamePhase = 1;
00105 preselectedDoor = -1;
00106 selectorPosition = 1;
00107
00108
00109 prizePosition = MontyHallGame.state.Rng.Next(0, 2);
00110
00111
00112 waitTicks = 0;
00113
00114
00115 ScreenManager.Game.ResetElapsedTime();
00116
00117
00118 MontyHallGame.state.playTime = 0.0;
00119
00120
00121 SpriteFont font = ScreenManager.Fonts["menu"];
00122 MontyHallGame game = (MontyHallGame)ScreenManager.Game;
00123 int width = game.GraphicsDevice.Viewport.Width;
00124 scrollingInfoText = new ScrollingText("", font, width, 30);
00125 scrollingInfoText.TextColor = Color.Black;
00126
00127
00128 ScreenManager.Sounds["show"].Play();
00129
00130
00131 scrollingInfoText.Text = "Press [Left] or [Right], then [Space] to pre-select a door to Open later.";
00132 }
00133
00137 public override void UnloadContent()
00138 {
00139 this.contentManager.Unload();
00140 }
00141
00142 #endregion
00143
00144 #region Update and Draw
00145
00151 public override void Update(GameTime gameTime, bool otherScreenHasFocus,
00152 bool coveredByOtherScreen)
00153 {
00154 base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
00155
00156 if (IsActive)
00157 {
00158
00159 MontyHallGame.state.playTime += gameTime.ElapsedRealTime.TotalSeconds;
00160
00161
00162 switch (gamePhase)
00163 {
00164 case 1:
00165
00166
00167 break;
00168 case 2:
00169
00170 NextDoor();
00171 break;
00172 case 3:
00173
00174
00175 break;
00176 case 4:
00177 if (waitTicks == 0)
00178 {
00179
00180 waitTicks = gameTime.TotalRealTime.Ticks + 1 * (1000000000/100);
00181 }
00182 else if (gameTime.TotalRealTime.Ticks > waitTicks)
00183 {
00184
00185 if (doorState[prizePosition] == 1)
00186 {
00187 MontyHallGame.state.Wins++;
00188
00189
00190 ScreenManager.AddScreen(
00191 new MontyHallGameOverScreen("*** Winner ***"), null);
00192
00193
00194 ScreenManager.Sounds["money"].Play();
00195 }
00196 else
00197 {
00198 MontyHallGame.state.Losses++;
00199
00200
00201 ScreenManager.AddScreen(
00202 new MontyHallGameOverScreen("Sorry - You Lost!"), null);
00203
00204
00205 ScreenManager.Sounds["loser"].Play();
00206 }
00207 }
00208 break;
00209 }
00210
00211
00212 scrollingInfoText.Update(gameTime);
00213 }
00214 }
00215
00220 public override void HandleInput(InputState input)
00221 {
00222 if (input == null)
00223 {
00224 throw new ArgumentNullException("input");
00225 }
00226
00227
00228 int playerIndex = (int)ControllingPlayer.Value;
00229
00230 KeyboardState keyboardState = input.CurrentKeyboardStates[playerIndex];
00231 GamePadState gamePadState = input.CurrentGamePadStates[playerIndex];
00232
00233
00234
00235
00236
00237 bool gamePadDisconnected = !gamePadState.IsConnected &&
00238 input.GamePadWasConnected[playerIndex];
00239
00240 if (input.IsInputCancel(ControllingPlayer) || gamePadDisconnected)
00241 {
00242 ScreenManager.AddScreen(new MontyHallPauseMenuScreen(), ControllingPlayer);
00243 }
00244 else
00245 {
00246
00247
00248 if (input.IsNewInputRight(ControllingPlayer))
00249 {
00250
00251 ScreenManager.Sounds["click"].Play();
00252
00253
00254 NextDoor();
00255 }
00256 else if (input.IsNewInputLeft(ControllingPlayer))
00257 {
00258
00259 ScreenManager.Sounds["click"].Play();
00260
00261
00262 PreviousDoor();
00263 }
00264
00265
00266 if (input.IsInputSelect(ControllingPlayer))
00267 {
00268 switch (gamePhase)
00269 {
00270 case 1:
00271
00272 preselectedDoor = selectorPosition;
00273
00274
00275 NextDoor();
00276
00277
00278 scrollingInfoText.Text = "Press [Space] and Monty will help by opening loosing door for you.";
00279
00280
00281 ScreenManager.Sounds["crowd"].Play(0.33f, 0.0f, 0.0f);
00282
00283
00284 gamePhase++;
00285 break;
00286 case 2:
00287
00288 if (selectorPosition == prizePosition)
00289 {
00290 NextDoor();
00291 }
00292
00293
00294 doorState[selectorPosition] = 1;
00295
00296
00297 ScreenManager.Sounds["door"].Play();
00298
00299
00300 selectorPosition = preselectedDoor;
00301
00302
00303 scrollingInfoText.Text = "Stay or switch doors? Use [Left] or [Right] to select another door, then press [Space] try to get your prize.";
00304
00305
00306 gamePhase++;
00307 break;
00308 case 3:
00309
00310 doorState[selectorPosition] = 1;
00311
00312
00313 if (selectorPosition != preselectedDoor)
00314 {
00315 MontyHallGame.state.Switches++;
00316 }
00317
00318
00319 scrollingInfoText.Text = "";
00320
00321
00322 ScreenManager.Sounds["door"].Play();
00323
00324
00325 gamePhase++;
00326 break;
00327 }
00328 }
00329 }
00330 }
00331
00335 public override void Draw(GameTime gameTime)
00336 {
00337
00338 PrimitiveBatch primitiveBatch = ScreenManager.PrimitiveBatch;
00339 SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
00340 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
00341
00342
00343 string doorTextureName = "mdoor_";
00344 doorTextureName += (doorState[0] == 0) ? "c" : "o";
00345 doorTextureName += (doorState[1] == 0) ? "c" : "o";
00346 doorTextureName += (doorState[2] == 0) ? "c" : "o";
00347 Texture2D doorTexture = ScreenManager.Textures[doorTextureName];
00348
00349
00350 double aspectRatio = 1024.0 / 768.0;
00351 int displayWidth = (int)Math.Truncate((double)viewport.Height * aspectRatio);
00352 Rectangle dest = new Rectangle(
00353 (viewport.Width - displayWidth) / 2, 0,
00354 displayWidth, viewport.Height);
00355 spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
00356 spriteBatch.Draw(doorTexture, dest, Color.White);
00357 spriteBatch.End();
00358
00359
00360 if ((gameTime.TotalRealTime.Milliseconds % 500) < 400)
00361 {
00362 switch (gamePhase)
00363 {
00364 case 1:
00365 dest = new Rectangle(
00366 viewport.Width / 2 +
00367 (int)((float)displayWidth * 0.29f * (float)(selectorPosition - 1))
00368 - 60,
00369 viewport.Height - 100,
00370 100, 50);
00371 spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
00372 spriteBatch.Draw(ScreenManager.Textures["opensign"], dest, Color.White);
00373 spriteBatch.End();
00374 break;
00375 case 2:
00376 for (int i = 0; i < 3; i++)
00377 {
00378 if (i != preselectedDoor)
00379 {
00380 dest = new Rectangle(
00381 viewport.Width / 2 +
00382 (int)((float)displayWidth * 0.29f * (float)(i - 1))
00383 - 55,
00384 viewport.Height - 100,
00385 90, 90);
00386 spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
00387 spriteBatch.Draw(ScreenManager.Textures["monty"], dest, Color.White);
00388 spriteBatch.End();
00389 }
00390 }
00391 break;
00392 case 3:
00393 dest = new Rectangle(
00394 viewport.Width / 2 +
00395 (int)((float)displayWidth * 0.29f * (float)(selectorPosition - 1))
00396 - 60,
00397 viewport.Height - 100,
00398 100, 100);
00399 spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
00400 spriteBatch.Draw(ScreenManager.Textures["key"], dest, Color.White);
00401 spriteBatch.End();
00402 break;
00403 }
00404 }
00405
00406
00407 if (preselectedDoor >= 0)
00408 {
00409 dest = new Rectangle(
00410 viewport.Width / 2 +
00411 (int)((float)displayWidth * 0.29f * (float)(preselectedDoor - 1))
00412 - 30,
00413 (int)((float)viewport.Height * 0.25f),
00414 50, 25);
00415 spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
00416 spriteBatch.Draw(ScreenManager.Textures["opensign"], dest, Color.White);
00417 spriteBatch.End();
00418 }
00419
00420
00421 if ((gamePhase == 4) && (doorState[prizePosition] != 0))
00422 {
00423 dest = new Rectangle(
00424 viewport.Width / 2 +
00425 (int)((float)displayWidth * 0.29f * (float)(prizePosition - 1))
00426 - 35,
00427 viewport.Height - 190,
00428 80, 80);
00429 spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
00430 spriteBatch.Draw(ScreenManager.Textures["potogold"], dest, Color.White);
00431 spriteBatch.End();
00432 }
00433
00434
00435 scrollingInfoText.Draw(gameTime, spriteBatch);
00436
00437
00438 if (TransitionPosition > 0)
00439 {
00440 ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
00441 }
00442 }
00443
00444 #endregion
00445
00450 private void NextDoor()
00451 {
00452 do
00453 {
00454 selectorPosition = (selectorPosition + 1);
00455 if (selectorPosition > 2)
00456 {
00457 selectorPosition = 0;
00458 }
00459 } while (((selectorPosition == preselectedDoor) && (gamePhase < 3)) ||
00460 (doorState[selectorPosition] != 0));
00461 }
00462
00467 private void PreviousDoor()
00468 {
00469 do
00470 {
00471 selectorPosition = (selectorPosition - 1);
00472 if (selectorPosition < 0)
00473 {
00474 selectorPosition = 2;
00475 }
00476 } while (((selectorPosition == preselectedDoor) && (gamePhase < 3)) ||
00477 (doorState[selectorPosition] != 0));
00478 }
00479 }
00480 }