00001
00002
00003
00004
00005
00006 namespace PendulumGame
00007 {
00008 using System;
00009 using System.IO;
00010 using System.Text;
00011 using System.Threading;
00012 using Microsoft.Xna.Framework;
00013 using Microsoft.Xna.Framework.Content;
00014 using Microsoft.Xna.Framework.Graphics;
00015 using Microsoft.Xna.Framework.Input;
00016
00017 using NewGamePhysics.StateManager;
00018 using NewGamePhysics.Mathematics;
00019 using NewGamePhysics.Physics;
00020 using NewGamePhysics.GraphicalElements;
00021 using NewGamePhysics.PhysicalElements;
00022 using NewGamePhysics.Utilities;
00023 using NewGamePhysics.Networking;
00024
00025 using Microsoft.DirectX.DirectSound;
00026
00030 class PendulumGameplayScreen : GameScreen
00031 {
00032 #region Fields
00033
00037 private const double MinimumEnergyForEntropyCollection = 10.0;
00038
00042 private ContentManager contentManager;
00043
00047 private DirectXAudio audioPlayer;
00048
00052 private DoubleRegularPendulum animatedDoubleRegularPendulum;
00053
00057 private DoubleSquarePendulum animatedDoubleSquarePendulum;
00058
00062 private VectorN[] pendulumOrigins = new VectorN[2];
00063
00067 private double[] pendulumScales = new double[2];
00068
00072 private DoubleRegularPendulumSimulation audioPendulum1 = null;
00073
00077 private DoubleSquarePendulumSimulation audioPendulum2 = null;
00078
00082 private int[] audioPendulumSamplesRemaining = new int[2];
00083
00087 private DotPlotter[] dotPlotters;
00088
00092 private Vector2[] dotPlotterDisplacement;
00093
00097 private LaplaceOverlay laplaceOverlay;
00098
00102 private BloomOverlay bloomOverlay;
00103
00107 private EnergyIndicator[] energyIndicators;
00108
00112 private ValueIndicator[] valueIndicators;
00113
00117 private ShootingGallery shootingGallery;
00118
00122 private AdvancedEntropyCollector[] entropyCollectors;
00123
00127 private RotationalActionIndicator[] actionIndicators;
00128
00132 private Vector2 screenOrigin;
00133
00137 private double screenScale;
00138
00142 private bool triggerAudio1 = false;
00143
00147 private bool triggerAudio2 = false;
00148
00149 #endregion
00150
00151 #region Initialization
00152
00156 public PendulumGameplayScreen()
00157 {
00158 TransitionOnTime = TimeSpan.FromSeconds(1.0);
00159 TransitionOffTime = TimeSpan.FromSeconds(1.0);
00160
00161
00162 this.audioPlayer = new DirectXAudio((Device)null, 22050, (short)16, (short)2);
00163 }
00164
00168 public override void LoadContent()
00169 {
00170 if (contentManager == null)
00171 {
00172 contentManager = new ContentManager(ScreenManager.Game.Services, "Content");
00173 }
00174
00175
00176 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
00177
00178
00179 for (int i = 0; i < PendulumGameState.NumPlayers; i++)
00180 {
00181 PendulumGame.State.Players[i] = new GamePlayer();
00182 PendulumGame.State.Players[i].ActionMarker = DoublePendulumHinges.Hinge1;
00183 }
00184
00185
00186 GravityCalculator gravityCalculator = new GravityCalculator(PendulumGame.State.CurrentCelestialObject);
00187 PendulumGame.State.CurrentGravity = gravityCalculator.Value;
00188
00189
00190 double size = 1.0;
00191 double size2 = 1.0;
00192 double mass = 1.0;
00193 double mass2 = 1.0;
00194
00195 this.screenOrigin =
00196 new Vector2((float)(viewport.Width / 2.0), (float)(viewport.Height / 2.0));
00197 this.screenScale = 140.0;
00198
00199
00200 this.animatedDoubleRegularPendulum = new DoubleRegularPendulum(
00201 ScreenManager,
00202 new Vector2(-2.0f, 0.0f),
00203 size,
00204 mass,
00205 size2,
00206 mass2,
00207 PendulumGame.State.CurrentGravity,
00208 PendulumGame.State.CurrentRotationalFrictionType,
00209 screenOrigin,
00210 screenScale);
00211
00212 this.animatedDoubleSquarePendulum = new DoubleSquarePendulum(
00213 ScreenManager,
00214 new Vector2(2.0f, 0.0f),
00215 size * (82.8427 / 100.0),
00216 mass,
00217 PendulumGame.State.CurrentGravity,
00218 PendulumGame.State.CurrentRotationalFrictionType,
00219 screenOrigin,
00220 screenScale);
00221
00222
00223 dotPlotters = new DotPlotter[2];
00224 dotPlotters[0] = new DotPlotter(2 * 1024);
00225 dotPlotters[1] = new DotPlotter(2 * 1024);
00226 dotPlotterDisplacement = new Vector2[2];
00227 dotPlotterDisplacement[0] =
00228 new Vector2(0.5f * PendulumGame.State.Scale.X, 0.0f);
00229 dotPlotterDisplacement[1] =
00230 new Vector2(-0.5f * PendulumGame.State.Scale.X, 0.0f);
00231
00232
00233 energyIndicators = new EnergyIndicator[2];
00234 energyIndicators[0] = new EnergyIndicator(ScreenManager, "E");
00235 energyIndicators[1] = new EnergyIndicator(ScreenManager, "E");
00236
00237
00238 valueIndicators = new ValueIndicator[8];
00239 valueIndicators[0] = new ValueIndicator(ScreenManager, "A Angle Inner", "{0,20:####.##} deg", -180, 180);
00240 valueIndicators[1] = new ValueIndicator(ScreenManager, "B Angle Inner", "{0,20:####.##} deg", -180, 180);
00241 valueIndicators[2] = new ValueIndicator(ScreenManager, "A Angle Outer", "{0,20:####.##} deg", -180, 180);
00242 valueIndicators[3] = new ValueIndicator(ScreenManager, "B Angle Outer", "{0,20:####.##} deg", -180, 180);
00243 valueIndicators[4] = new ValueIndicator(ScreenManager, "A Speed Inner", "{0,20:####.##} 1/s", -20, 20);
00244 valueIndicators[5] = new ValueIndicator(ScreenManager, "B Speed Inner", "{0,20:####.##} 1/s", -20, 20);
00245 valueIndicators[6] = new ValueIndicator(ScreenManager, "A Speed Outer", "{0,20:####.##} 1/s", -20, 20);
00246 valueIndicators[7] = new ValueIndicator(ScreenManager, "B Speed Outer", "{0,20:####.##} 1/s", -20, 20);
00247
00248
00249 float yPos;
00250 yPos = viewport.Height - EnergyIndicator.Height - 10.0f;
00251 energyIndicators[0].SetPosition(new Vector2(5.0f, yPos));
00252 energyIndicators[1].SetPosition(new Vector2(viewport.Width - EnergyIndicator.Width - 5.0f, yPos));
00253 yPos = viewport.Height - ValueIndicator.Height - 10.0f + 1.0f;
00254 for (int i = 0; i < 4; i++)
00255 {
00256 valueIndicators[2 * i].SetPosition(new Vector2(25.0f, yPos));
00257 valueIndicators[2 * i + 1].SetPosition(new Vector2(viewport.Width - ValueIndicator.Width - 25.0f, yPos));
00258 }
00259
00260
00261 float simulationHeight = 0.3f;
00262 float simulationWidth = 8.0f;
00263 this.shootingGallery =
00264 new ShootingGallery(
00265 ScreenManager,
00266 new Vector2(-simulationWidth / 2.0f, -2.0f),
00267 simulationWidth,
00268 simulationHeight,
00269 screenOrigin,
00270 screenScale);
00271 this.shootingGallery.TargetConveyerSpeed = 0.005;
00272 CelestialBody celestialBody =
00273 new CelestialBody(PendulumGame.State.CurrentCelestialObject);
00274 string[] targetTypes = new string[12];
00275 string[] targetChoices = Enum.GetNames(typeof(ShootingGalleryTargetType));
00276 for (int i = 0; i < targetTypes.Length; i++)
00277 {
00278 int randomChoice = PendulumGame.State.PhysicalRandomNumberGenerator.Next(
00279 0,
00280 targetChoices.Length - 1);
00281 targetTypes[i] = targetChoices[randomChoice];
00282 }
00283
00284 shootingGallery.Reset(
00285 targetTypes,
00286 PendulumGame.State.CurrentGravity,
00287 celestialBody.GetAtmosphericDensity());
00288
00289 PendulumGame.State.PhysicalRandomNumberGenerator.Next(0, 2);
00290
00291
00292 actionIndicators = new RotationalActionIndicator[2];
00293 actionIndicators[0] = new RotationalActionIndicator(ScreenManager);
00294 actionIndicators[1] = new RotationalActionIndicator(ScreenManager);
00295
00296
00297 entropyCollectors = new AdvancedEntropyCollector[2];
00298 entropyCollectors[0] = new AdvancedEntropyCollector();
00299 entropyCollectors[1] = new AdvancedEntropyCollector();
00300
00301
00302 PendulumGame.State.SubmittedEntropyBits = 0;
00303
00304
00305 Program.Game.SendRandomInfoLink("Randomness");
00306
00307
00308 this.laplaceOverlay = new LaplaceOverlay(this.ScreenManager);
00309 this.laplaceOverlay.LoadContent();
00310
00311
00312 this.bloomOverlay = new BloomOverlay(this.ScreenManager);
00313 this.bloomOverlay.LoadContent();
00314
00315
00316 ScreenManager.Game.ResetElapsedTime();
00317
00318
00319 this.audioPlayer.Play(new PullAudioCallback(PendulumFiller));
00320 }
00321
00325 public override void UnloadContent()
00326 {
00327
00328 this.audioPlayer.Stop();
00329
00330
00331 this.laplaceOverlay.UnloadContent();
00332
00333
00334 this.bloomOverlay.UnloadContent();
00335
00336
00337 Program.Game.SendRandomInfoLink("Randomness");
00338
00339
00340 CheckAndSubmitEntropy(0, 1);
00341 CheckAndSubmitEntropy(1, 1);
00342
00343
00344 contentManager.Unload();
00345
00346
00347 base.UnloadContent();
00348 }
00349
00350 #endregion
00351
00352 #region Update and Draw
00353
00354
00360 public override void Update(GameTime gameTime, bool otherScreenHasFocus,
00361 bool coveredByOtherScreen)
00362 {
00363 base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);
00364
00365 if (IsActive)
00366 {
00367 Vector2[] pendulumPoints;
00368 double rotation;
00369
00370
00371
00372 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
00373
00374
00375 dotPlotters[0].MoveDots(dotPlotterDisplacement[0]);
00376 dotPlotters[1].MoveDots(dotPlotterDisplacement[1]);
00377
00378
00379
00380
00381 rotation = animatedDoubleRegularPendulum.Pendulum.Drive(
00382 PendulumGame.State.Players[0].ActionMarker,
00383 PendulumGame.State.Players[0].ActionIntensity);
00384
00385
00386 actionIndicators[0].Animate(rotation);
00387
00388
00389 animatedDoubleRegularPendulum.Pendulum.Animate();
00390
00391
00392 pendulumPoints =
00393 animatedDoubleRegularPendulum.Pendulum.GetPosition(this.screenOrigin, this.screenScale);
00394
00395
00396 dotPlotters[0].AddDot(pendulumPoints[2], new Color(255, 0, 0), 0);
00397
00398
00399 switch (PendulumGame.State.Players[0].ActionMarker)
00400 {
00401 case DoublePendulumHinges.Hinge1:
00402 actionIndicators[0].SetPosition(pendulumPoints[0]);
00403 break;
00404 case DoublePendulumHinges.Hinge2:
00405 actionIndicators[0].SetPosition(pendulumPoints[1]);
00406 break;
00407 }
00408
00409
00410 pendulumPoints =
00411 animatedDoubleRegularPendulum.Pendulum.GetPosition();
00412
00413
00414 int hitsA = shootingGallery.ShootAtTargets(pendulumPoints[2], 0.01);
00415 if (hitsA > 0)
00416 {
00417 PendulumGame.State.Players[0].Points += hitsA;
00418
00419
00420 Program.Game.SendRandomInfoLink("DoublePendulum");
00421 }
00422
00423
00424
00425
00426 rotation = animatedDoubleSquarePendulum.Pendulum.Drive(
00427 PendulumGame.State.Players[1].ActionMarker,
00428 PendulumGame.State.Players[1].ActionIntensity);
00429
00430
00431 actionIndicators[1].Animate(rotation);
00432
00433
00434 animatedDoubleSquarePendulum.Pendulum.Animate();
00435
00436
00437 pendulumPoints =
00438 animatedDoubleSquarePendulum.Pendulum.GetPosition(this.screenOrigin, this.screenScale);
00439
00440
00441 dotPlotters[1].AddDot(pendulumPoints[6], new Color(0, 0, 192), 0);
00442
00443
00444 switch (PendulumGame.State.Players[1].ActionMarker)
00445 {
00446 case DoublePendulumHinges.Hinge1:
00447 actionIndicators[1].SetPosition(pendulumPoints[0]);
00448 break;
00449 case DoublePendulumHinges.Hinge2:
00450 actionIndicators[1].SetPosition(pendulumPoints[4]);
00451 break;
00452 }
00453
00454
00455 pendulumPoints =
00456 animatedDoubleSquarePendulum.Pendulum.GetPosition();
00457
00458
00459 int hitsB = shootingGallery.ShootAtTargets(pendulumPoints[6], 0.01);
00460 if (hitsB > 0)
00461 {
00462 PendulumGame.State.Players[1].Points += hitsB;
00463
00464
00465 Program.Game.SendRandomInfoLink("DoublePendulum");
00466 }
00467
00468
00469 shootingGallery.Update(gameTime);
00470
00471
00472 if (shootingGallery.NumActiveTargets == 0)
00473 {
00474
00475 CheckAndSubmitEntropy(0, 1);
00476 CheckAndSubmitEntropy(1, 1);
00477
00478 ScreenManager.AddScreen(
00479 new PendulumGameOverScreen(), null);
00480 }
00481
00482
00483 double e1 = animatedDoubleRegularPendulum.Pendulum.GetEnergy();
00484 energyIndicators[0].SetValue(e1);
00485
00486 double e2 = animatedDoubleSquarePendulum.Pendulum.GetEnergy();
00487 energyIndicators[1].SetValue(e2);
00488
00489 double[] a1 = animatedDoubleRegularPendulum.Pendulum.GetAngle();
00490 valueIndicators[0].SetValue(ToDegree(a1[0]));
00491 valueIndicators[2].SetValue(ToDegree(a1[1]));
00492
00493 double[] a2 = animatedDoubleSquarePendulum.Pendulum.GetAngle();
00494 valueIndicators[1].SetValue(ToDegree(a2[0]));
00495 valueIndicators[3].SetValue(ToDegree(a2[1]));
00496
00497 double[] v1 = animatedDoubleRegularPendulum.Pendulum.GetVelocity();
00498 valueIndicators[4].SetValue(v1[0]);
00499 valueIndicators[6].SetValue(v1[1]);
00500
00501 double[] v2 = animatedDoubleSquarePendulum.Pendulum.GetVelocity();
00502 valueIndicators[5].SetValue(v2[0]);
00503 valueIndicators[7].SetValue(v2[1]);
00504
00505
00506
00507
00508 if (e1 > MinimumEnergyForEntropyCollection)
00509 {
00510 if (PendulumGame.State.Players[1].ActionIntensityChanged())
00511 {
00512 CollectEntropyFromPlayerA();
00513 }
00514 }
00515
00516
00517 if (e2 > MinimumEnergyForEntropyCollection)
00518 {
00519 if (PendulumGame.State.Players[0].ActionIntensityChanged())
00520 {
00521 CollectEntropyFromPlayerB();
00522 }
00523 }
00524
00525
00526 if ((this.audioPendulum1 == null) &&
00527 (this.audioPendulumSamplesRemaining[0] == 0))
00528 {
00529 if ((!PendulumGame.State.RealtimeAudioOnDemand) || (triggerAudio1))
00530 {
00531
00532 triggerAudio1 = false;
00533
00534
00535 double[] angles = this.animatedDoubleRegularPendulum.Pendulum.GetAngle();
00536 double[] velocities = this.animatedDoubleRegularPendulum.Pendulum.GetVelocity();
00537
00538 float theta1 = MathHelper.WrapAngle((float)angles[0]);
00539 float theta2 = MathHelper.WrapAngle((float)angles[1]);
00540
00541
00542 DoubleRegularPendulumSimulation audioPendulum =
00543 new DoubleRegularPendulumSimulation(
00544 new Vector2(),
00545 0.1, 1.0, 0.1, 1.0,
00546 PendulumGame.State.CurrentGravity,
00547 PendulumGame.State.CurrentRotationalFrictionType);
00548 audioPendulum.SetInitialConditions(
00549 (double)theta1, velocities[0], (double)theta2, velocities[1]);
00550
00551
00552 this.audioPendulumSamplesRemaining[0] = 38000;
00553 this.audioPendulum1 = audioPendulum;
00554 }
00555 }
00556 else
00557 {
00558 if (this.audioPendulumSamplesRemaining[0] == 0)
00559 {
00560 this.audioPendulum1 = null;
00561 }
00562 }
00563
00564
00565 if ((this.audioPendulum2 == null) &&
00566 (this.audioPendulumSamplesRemaining[1] == 0))
00567 {
00568 if ((!PendulumGame.State.RealtimeAudioOnDemand) || (triggerAudio2))
00569 {
00570
00571 triggerAudio2 = false;
00572
00573
00574 double[] angles = this.animatedDoubleSquarePendulum.Pendulum.GetAngle();
00575 double[] velocities = this.animatedDoubleSquarePendulum.Pendulum.GetVelocity();
00576
00577 float theta1 = MathHelper.WrapAngle((float)angles[0]);
00578 float theta2 = MathHelper.WrapAngle((float)angles[1]);
00579
00580
00581 DoubleSquarePendulumSimulation audioPendulum =
00582 new DoubleSquarePendulumSimulation(
00583 new Vector2(),
00584 0.1, 1.0,
00585 PendulumGame.State.CurrentGravity,
00586 PendulumGame.State.CurrentRotationalFrictionType);
00587 audioPendulum.SetInitialConditions(
00588 (double)theta1, velocities[0], (double)theta2, velocities[1]);
00589
00590
00591 this.audioPendulumSamplesRemaining[1] = 44000;
00592 this.audioPendulum2 = audioPendulum;
00593 }
00594 }
00595 else
00596 {
00597 if (this.audioPendulumSamplesRemaining[1] == 0)
00598 {
00599 this.audioPendulum2 = null;
00600 }
00601 }
00602 }
00603 }
00604
00609 public override void HandleInput(InputState input)
00610 {
00611 if (input == null)
00612 {
00613 throw new ArgumentNullException("input");
00614 }
00615
00616 PlayerIndex playerIndex;
00617
00618 if (input.IsInputCancel(null) || input.IsDisconnected(null))
00619 {
00620 ScreenManager.AddScreen(new PendulumPauseMenuScreen(), null);
00621 }
00622 else
00623 {
00624
00625 for (int i = 0; i < PendulumGameState.NumPlayers; i++)
00626 {
00627 PendulumGame.State.Players[i].TrackActionIntensity();
00628 }
00629
00630
00631 if (input.IsNewKeyPress(Keys.Q, null, out playerIndex) ||
00632 input.IsNewButtonPress(Buttons.B, PlayerIndex.One, out playerIndex))
00633 {
00634 PendulumGame.State.Players[0].ActionMarker = DoublePendulumHinges.Hinge1;
00635 }
00636
00637
00638 if (input.IsNewKeyPress(Keys.A, null, out playerIndex) ||
00639 input.IsNewButtonPress(Buttons.A, PlayerIndex.One, out playerIndex))
00640 {
00641 PendulumGame.State.Players[0].ActionMarker = DoublePendulumHinges.Hinge2;
00642 }
00643
00644
00645 if (input.IsNewKeyPress(Keys.Up, null, out playerIndex) ||
00646 input.IsNewButtonPress(Buttons.B, PlayerIndex.Two, out playerIndex) ||
00647 (PendulumGame.State.UseOnlyOneGamepad && input.IsNewButtonPress(Buttons.Y, PlayerIndex.One, out playerIndex)))
00648 {
00649 PendulumGame.State.Players[1].ActionMarker = DoublePendulumHinges.Hinge1;
00650 }
00651
00652
00653 if (input.IsNewKeyPress(Keys.Down, null, out playerIndex) ||
00654 input.IsNewButtonPress(Buttons.A, PlayerIndex.Two, out playerIndex) ||
00655 (PendulumGame.State.UseOnlyOneGamepad && input.IsNewButtonPress(Buttons.X, PlayerIndex.One, out playerIndex)))
00656 {
00657 PendulumGame.State.Players[1].ActionMarker = DoublePendulumHinges.Hinge2;
00658 }
00659
00660
00661 if (input.IsKeyDown(Keys.Z, null, out playerIndex))
00662 {
00663 PendulumGame.State.Players[0].ActionIntensity = -1.0;
00664 }
00665 else if (input.IsKeyDown(Keys.X, null, out playerIndex))
00666 {
00667 PendulumGame.State.Players[0].ActionIntensity = 1.0;
00668 }
00669 else
00670 {
00671 PendulumGame.State.Players[0].ActionIntensity =
00672 input.CurrentGamePadStates[0].ThumbSticks.Left.X;
00673 }
00674
00675
00676 if (input.IsKeyDown(Keys.Left, null, out playerIndex))
00677 {
00678 PendulumGame.State.Players[1].ActionIntensity = -1.0;
00679 }
00680 else if (input.IsKeyDown(Keys.Right, null, out playerIndex))
00681 {
00682 PendulumGame.State.Players[1].ActionIntensity = 1.0;
00683 }
00684 else
00685 {
00686
00687
00688 if (PendulumGame.State.UseOnlyOneGamepad)
00689 {
00690 PendulumGame.State.Players[1].ActionIntensity =
00691 input.CurrentGamePadStates[0].ThumbSticks.Right.X;
00692 }
00693 else
00694 {
00695 PendulumGame.State.Players[1].ActionIntensity =
00696 input.CurrentGamePadStates[1].ThumbSticks.Left.X;
00697 }
00698 }
00699
00700
00701 for (int i = 0; i < PendulumGameState.NumPlayers; i++)
00702 {
00703 PendulumGame.State.Players[i].TrackActionIntensity();
00704 }
00705
00706
00707 if (input.IsNewKeyPress(Keys.LeftShift, null, out playerIndex) ||
00708 input.IsNewButtonPress(Buttons.LeftTrigger, PlayerIndex.One, out playerIndex))
00709 {
00710 PendulumGame.State.Players[0].SelectedIndicator++;
00711 PendulumGame.State.Players[0].SelectedIndicator %= (valueIndicators.Length / 2);
00712 triggerAudio1 = true;
00713 }
00714 else if (input.IsNewButtonPress(Buttons.RightTrigger, PlayerIndex.One, out playerIndex))
00715 {
00716 PendulumGame.State.Players[0].SelectedIndicator--;
00717 if (PendulumGame.State.Players[0].SelectedIndicator < 0)
00718 {
00719 PendulumGame.State.Players[0].SelectedIndicator += (valueIndicators.Length / 2);
00720 }
00721 }
00722
00723
00724 if (input.IsNewKeyPress(Keys.RightShift, null, out playerIndex) ||
00725 input.IsNewButtonPress(Buttons.LeftTrigger, PlayerIndex.Two, out playerIndex) ||
00726 (PendulumGame.State.UseOnlyOneGamepad &&
00727 input.IsNewButtonPress(Buttons.RightTrigger, PlayerIndex.One, out playerIndex)))
00728 {
00729 PendulumGame.State.Players[1].SelectedIndicator++;
00730 PendulumGame.State.Players[1].SelectedIndicator %= (valueIndicators.Length / 2);
00731 triggerAudio2 = true;
00732 }
00733 else if (input.IsNewButtonPress(Buttons.RightTrigger, PlayerIndex.Two, out playerIndex))
00734 {
00735 PendulumGame.State.Players[1].SelectedIndicator--;
00736 if (PendulumGame.State.Players[1].SelectedIndicator < 0)
00737 {
00738 PendulumGame.State.Players[1].SelectedIndicator += (valueIndicators.Length / 2);
00739 }
00740 }
00741
00742
00743 if (input.IsNewKeyPress(Keys.G, null, out playerIndex))
00744 {
00745 ScreenManager.AddScreen(
00746 new PendulumGameOverScreen(), null);
00747 }
00748 }
00749 }
00750
00754 public override void Draw(GameTime gameTime)
00755 {
00756
00757 ScreenManager.GraphicsDevice.Clear(ClearOptions.Target,
00758 Color.Black, 0, 0);
00759
00760 SpriteBatch spriteBatch = ScreenManager.SpriteBatch;
00761 PrimitiveBatch primitiveBatch = ScreenManager.PrimitiveBatch;
00762 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
00763
00764
00765
00766 dotPlotters[0].Draw(gameTime, primitiveBatch);
00767 dotPlotters[1].Draw(gameTime, primitiveBatch);
00768
00769
00770 if (!PendulumGame.State.DisablePixelShaderEffects)
00771 {
00772 this.bloomOverlay.Draw(gameTime);
00773 }
00774
00775
00776 if ((!PendulumGame.State.DisablePixelShaderEffects) &&
00777 (this.shootingGallery.NumActiveTargets > 0))
00778 {
00779 shootingGallery.Draw(gameTime);
00780 this.laplaceOverlay.Draw(gameTime);
00781 }
00782
00783
00784 animatedDoubleRegularPendulum.Draw(
00785 gameTime);
00786 animatedDoubleSquarePendulum.Draw(
00787 gameTime);
00788
00789
00790 actionIndicators[0].Draw(gameTime);
00791 actionIndicators[1].Draw(gameTime);
00792
00793
00794 shootingGallery.Draw(gameTime);
00795
00796
00797 energyIndicators[0].Draw(gameTime);
00798 energyIndicators[1].Draw(gameTime);
00799 valueIndicators[PendulumGame.State.Players[0].SelectedIndicator * 2].Draw(gameTime);
00800 valueIndicators[PendulumGame.State.Players[1].SelectedIndicator * 2 + 1].Draw(gameTime);
00801
00802
00803 primitiveBatch.Begin(PrimitiveType.LineList);
00804 primitiveBatch.AddVertex(new Vector2(viewport.Width * 0.5f, viewport.Height - 50.0f), Color.White);
00805 primitiveBatch.AddVertex(new Vector2(viewport.Width * 0.5f, viewport.Height - 10.0f), Color.White);
00806 primitiveBatch.End();
00807
00808
00809 DrawEntropyStatus(spriteBatch);
00810
00811
00812 DrawPlayers(spriteBatch);
00813
00814
00815 if (TransitionPosition > 0)
00816 {
00817 ScreenManager.FadeBackBufferToBlack(255 - TransitionAlpha);
00818 }
00819 }
00820
00821 #endregion
00822
00826 private void CollectEntropyFromPlayerA()
00827 {
00828 entropyCollectors[1].AddValue(
00829 animatedDoubleRegularPendulum.Pendulum.GetAngle(PendulumGame.State.Players[1].ActionMarker));
00830 dotPlotters[0].SetTypeAtHead(1);
00831 }
00832
00836 private void CollectEntropyFromPlayerB()
00837 {
00838 entropyCollectors[0].AddValue(
00839 animatedDoubleSquarePendulum.Pendulum.GetAngle(PendulumGame.State.Players[0].ActionMarker));
00840 dotPlotters[1].SetTypeAtHead(1);
00841 }
00842
00851 private void CheckAndSubmitEntropy(int playerIndex, int checkLimit)
00852 {
00853
00854 string entropy = entropyCollectors[playerIndex].ToString();
00855
00856
00857 if (entropy.Length >= checkLimit)
00858 {
00859 PendulumGame.State.SubmittedEntropyBits += entropy.Length;
00860 Program.Game.SubmitEntropyBits(entropy);
00861 entropyCollectors[playerIndex].Reset();
00862 }
00863 }
00864
00869 private void DrawEntropyStatus(SpriteBatch spriteBatch)
00870 {
00871
00872 int countA = entropyCollectors[0].ValuePoolSize;
00873 int countB = entropyCollectors[1].ValuePoolSize;
00874
00875 SpriteFont font = ScreenManager.Fonts["small"];
00876 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
00877 Color color = Color.White;
00878 Vector2 origin = new Vector2(0, 0);
00879 Vector2 position = new Vector2(viewport.Width * 0.28f, viewport.Height - font.LineSpacing - 10.0f);
00880 string message = "A Collected: " + countA.ToString();
00881 spriteBatch.Begin();
00882 spriteBatch.DrawString(
00883 font,
00884 message,
00885 position,
00886 color,
00887 0,
00888 origin,
00889 1.0f,
00890 SpriteEffects.None,
00891 0);
00892 position = new Vector2(viewport.Width * 0.52f, viewport.Height - font.LineSpacing - 10.0f);
00893 message = "B Collected: " + countB.ToString();
00894 spriteBatch.DrawString(
00895 font,
00896 message,
00897 position,
00898 color,
00899 0,
00900 origin,
00901 1.0f,
00902 SpriteEffects.None,
00903 0);
00904 spriteBatch.End();
00905 }
00906
00911 private void DrawPlayers(SpriteBatch spriteBatch)
00912 {
00913 SpriteFont font = ScreenManager.Fonts["small"];
00914 Viewport viewport = ScreenManager.GraphicsDevice.Viewport;
00915 Color color = Color.White;
00916 Vector2 origin = new Vector2(0, 0);
00917 Vector2 position = new Vector2(viewport.Width * 0.28f, viewport.Height - 2 * font.LineSpacing - 20.0f);
00918 string message = "Player A: " + PendulumGame.State.Players[0].Points + " points";
00919 spriteBatch.Begin();
00920 spriteBatch.DrawString(
00921 font,
00922 message,
00923 position,
00924 color,
00925 0,
00926 origin,
00927 1.0f,
00928 SpriteEffects.None,
00929 0);
00930 position = new Vector2(viewport.Width * 0.52f, viewport.Height - 2 * font.LineSpacing - 20.0f);
00931 message = "Player B: " + PendulumGame.State.Players[1].Points + " points";
00932 spriteBatch.DrawString(
00933 font,
00934 message,
00935 position,
00936 color,
00937 0,
00938 origin,
00939 1.0f,
00940 SpriteEffects.None,
00941 0);
00942 spriteBatch.End();
00943 }
00944
00950 private double ToDegree(double value)
00951 {
00952 value = value * 180.0 / Math.PI;
00953 if (value < 0.0)
00954 {
00955 while (value < -180.0)
00956 {
00957 value += 360.0;
00958 }
00959 }
00960 else
00961 {
00962 while (value > 180.0)
00963 {
00964 value -= 360.0;
00965 }
00966 }
00967
00968 return value;
00969 }
00970
00976 private void PendulumFiller(IntPtr dest, int size)
00977 {
00978
00979 const float maxAmplitude = 0.90f;
00980
00981
00982 int samples = size / 2;
00983
00984
00985 short[] buffer = new short[samples];
00986
00987
00988 if (this.audioPendulum1 != null)
00989 {
00990 int samplePos = 0;
00991 short sampleValue = 0;
00992 double[] angles;
00993 double[] velocities;
00994 float theta;
00995 float omega;
00996 float fvalue = 0.0f;
00997 while ((this.audioPendulumSamplesRemaining[0] > 0) && (samplePos < samples))
00998 {
00999
01000 this.audioPendulum1.Animate();
01001
01002
01003 switch (PendulumGame.State.Players[0].SelectedIndicator)
01004 {
01005 case 0:
01006 angles = audioPendulum1.GetAngle();
01007 theta = MathHelper.WrapAngle((float)angles[0]);
01008 fvalue = theta / (float)Math.PI * maxAmplitude * (float)(short.MaxValue);
01009 break;
01010 case 1:
01011 angles = audioPendulum1.GetAngle();
01012 theta = MathHelper.WrapAngle((float)angles[1]);
01013 fvalue = theta / (float)Math.PI * maxAmplitude * (float)(short.MaxValue);
01014 break;
01015 case 2:
01016 velocities = audioPendulum1.GetVelocity();
01017 omega = (float)velocities[0];
01018 fvalue = (float)omega * 0.1f;
01019 if (fvalue < -maxAmplitude)
01020 {
01021 fvalue = -maxAmplitude;
01022 }
01023 else if (fvalue > maxAmplitude)
01024 {
01025 fvalue = maxAmplitude;
01026 }
01027
01028 fvalue *= (float)(short.MaxValue);
01029 break;
01030 case 3:
01031 velocities = audioPendulum1.GetVelocity();
01032 omega = (float)velocities[1];
01033 fvalue = (float)omega * 0.1f;
01034 if (fvalue < -maxAmplitude)
01035 {
01036 fvalue = -maxAmplitude;
01037 }
01038 else if (fvalue > maxAmplitude)
01039 {
01040 fvalue = maxAmplitude;
01041 }
01042
01043 fvalue *= (float)(short.MaxValue);
01044 break;
01045 default:
01046 fvalue = 0.0f;
01047 break;
01048 }
01049
01050 sampleValue = Convert.ToInt16(fvalue);
01051 buffer[samplePos] = sampleValue;
01052 samplePos += 2;
01053
01054 this.audioPendulumSamplesRemaining[0]--;
01055 }
01056 }
01057
01058
01059 if (this.audioPendulum2 != null)
01060 {
01061 int samplePos = 1;
01062 short sampleValue = 0;
01063 double[] angles;
01064 double[] velocities;
01065 float theta;
01066 float omega;
01067 float fvalue = 0.0f;
01068 while ((this.audioPendulumSamplesRemaining[1] > 0) && (samplePos < samples))
01069 {
01070
01071 this.audioPendulum2.Animate();
01072
01073
01074 switch (PendulumGame.State.Players[1].SelectedIndicator)
01075 {
01076 case 0:
01077 angles = audioPendulum2.GetAngle();
01078 theta = MathHelper.WrapAngle((float)angles[0]);
01079 fvalue = theta / (float)Math.PI * maxAmplitude * (float)(short.MaxValue);
01080 break;
01081 case 1:
01082 angles = audioPendulum2.GetAngle();
01083 theta = MathHelper.WrapAngle((float)angles[1]);
01084 fvalue = theta / (float)Math.PI * maxAmplitude * (float)(short.MaxValue);
01085 break;
01086 case 2:
01087 velocities = audioPendulum2.GetVelocity();
01088 omega = (float)velocities[0];
01089 fvalue = (float)omega * 0.1f;
01090 if (fvalue < -maxAmplitude)
01091 {
01092 fvalue = -maxAmplitude;
01093 }
01094 else if (fvalue > maxAmplitude)
01095 {
01096 fvalue = maxAmplitude;
01097 }
01098
01099 fvalue *= (float)(short.MaxValue);
01100 break;
01101 case 3:
01102 velocities = audioPendulum2.GetVelocity();
01103 omega = (float)velocities[1];
01104 fvalue = (float)omega * 0.1f;
01105 if (fvalue < -maxAmplitude)
01106 {
01107 fvalue = -maxAmplitude;
01108 }
01109 else if (fvalue > maxAmplitude)
01110 {
01111 fvalue = maxAmplitude;
01112 }
01113
01114 fvalue *= (float)(short.MaxValue);
01115 break;
01116 default:
01117 fvalue = 0.0f;
01118 break;
01119 }
01120
01121
01122 sampleValue = Convert.ToInt16(fvalue);
01123 buffer[samplePos] = sampleValue;
01124 samplePos += 2;
01125
01126 this.audioPendulumSamplesRemaining[1]--;
01127 }
01128 }
01129
01130 System.Runtime.InteropServices.Marshal.Copy(buffer, 0, dest, samples);
01131 }
01132 }
01133 }