TitleMenu.cs 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. //-----------------------------------------------------------------------------
  2. // TitleMenu.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using Microsoft.Xna.Framework;
  12. using Microsoft.Xna.Framework.Graphics;
  13. namespace XnaGraphicsDemo
  14. {
  15. /// <summary>
  16. /// The main menu screen allows users to choose between the various demo screens.
  17. /// </summary>
  18. class TitleMenu : MenuComponent
  19. {
  20. // Constants.
  21. const float XnaSpawnRate = 1.5f;
  22. const float XnaLifespan = 7;
  23. // Fields.
  24. /// <summary>
  25. /// Gets or sets the current attract mode cycle index.
  26. /// </summary>
  27. /// <summary>
  28. /// Gets or sets the elapsed time for floating label updates.
  29. /// </summary>
  30. float time;
  31. Random random = new Random();
  32. // We display a set of floating "xna" text labels in the background of the menu.
  33. class FloatingXna
  34. {
  35. public Vector2 Position;
  36. public float Age;
  37. public float Size;
  38. }
  39. List<FloatingXna> floatingXnas = new List<FloatingXna>();
  40. /// <summary>
  41. /// Initializes a new instance of the <see cref="TitleMenu"/> class and sets up menu entries.
  42. /// </summary>
  43. /// <param name="game">The game instance.</param>
  44. public TitleMenu(DemoGame game)
  45. : base(game)
  46. {
  47. Entries.Add(new MenuEntry { Text = "basic effect", Clicked = delegate { Game.SetActiveMenu(1); } });
  48. Entries.Add(new MenuEntry { Text = "dual texture effect", Clicked = delegate { Game.SetActiveMenu(2); } });
  49. Entries.Add(new MenuEntry { Text = "alpha test effect", Clicked = delegate { Game.SetActiveMenu(3); } });
  50. Entries.Add(new MenuEntry { Text = "skinned effect", Clicked = delegate { Game.SetActiveMenu(4); } });
  51. Entries.Add(new MenuEntry { Text = "environment map effect", Clicked = delegate { Game.SetActiveMenu(5); } });
  52. Entries.Add(new MenuEntry { Text = "particles", Clicked = delegate { Game.SetActiveMenu(6); } });
  53. #if !IOS
  54. Entries.Add(new MenuEntry { Text = "quit", Clicked = delegate { game.Exit(); } });
  55. #endif
  56. }
  57. /// <summary>
  58. /// Resets the menu state and clears floating labels.
  59. /// </summary>
  60. public override void Reset()
  61. {
  62. floatingXnas.Clear();
  63. time = 0;
  64. base.Reset();
  65. }
  66. /// <summary>
  67. /// Gets the attract mode delay for the main menu (shorter than other screens).
  68. /// </summary>
  69. override protected TimeSpan AttractDelay { get { return TimeSpan.FromSeconds(3); } }
  70. /// <summary>
  71. /// When the attract mode timeout is reached, cycles through each demo screen in turn.
  72. /// </summary>
  73. override protected void OnAttract()
  74. {
  75. Entries[selectedEntry].OnClicked();
  76. selectedEntry = (selectedEntry + 1) % (Entries.Count - 1); // Loop, skip "quit"
  77. }
  78. /// <summary>
  79. /// Updates the floating "xna" background labels and handles their animation and removal.
  80. /// </summary>
  81. /// <param name="gameTime">The current game time.</param>
  82. public override void Update(GameTime gameTime)
  83. {
  84. time += (float)gameTime.ElapsedGameTime.TotalSeconds;
  85. // Spawn a new label?
  86. if (time > XnaSpawnRate)
  87. {
  88. FloatingXna xna = new FloatingXna();
  89. xna.Size = (float)random.NextDouble() * 2 + 0.5f;
  90. xna.Position.X = (float)random.NextDouble() * 320 + 80;
  91. xna.Position.Y = (float)random.NextDouble() * 700 + 50;
  92. floatingXnas.Add(xna);
  93. time -= XnaSpawnRate;
  94. }
  95. // Animate the existing labels.
  96. int i = 0;
  97. while (i < floatingXnas.Count)
  98. {
  99. FloatingXna xna = floatingXnas[i];
  100. xna.Age += (float)gameTime.ElapsedGameTime.TotalSeconds;
  101. // Different size labels move at different speeds.
  102. float speed = 1.5f - xna.Size;
  103. if (Math.Abs(speed) > 0.01f)
  104. xna.Position.Y -= xna.Age * xna.Age / speed / 10;
  105. // Remove old labels.
  106. if (xna.Age >= XnaLifespan)
  107. floatingXnas.RemoveAt(i);
  108. else
  109. i++;
  110. }
  111. base.Update(gameTime);
  112. }
  113. /// <summary>
  114. /// Draws the main menu, including floating labels and menu items.
  115. /// </summary>
  116. /// <param name="gameTime">The current game time.</param>
  117. public override void Draw(GameTime gameTime)
  118. {
  119. DrawTitle("MonoGame demo", Color.CornflowerBlue, Color.Lerp(Color.Blue, Color.CornflowerBlue, 0.85f));
  120. // Draw the background "xna" labels.
  121. SpriteBatch.Begin();
  122. foreach (FloatingXna blob in floatingXnas)
  123. {
  124. float alpha = Math.Min(blob.Age, 1) * Math.Min((XnaLifespan - blob.Age) / (XnaLifespan - 2), 1);
  125. alpha *= alpha;
  126. alpha /= 8;
  127. SpriteBatch.DrawString(BigFont, "MonoGame", blob.Position, Color.Blue * alpha, MathHelper.PiOver2, Vector2.Zero, blob.Size, 0, 0);
  128. }
  129. SpriteBatch.End();
  130. // This will draw the various menu items.
  131. base.Draw(gameTime);
  132. }
  133. }
  134. }