#region File Description //----------------------------------------------------------------------------- // TitleMenu.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; #endregion namespace XnaGraphicsDemo { /// /// The main menu screen allows users to choose between the various demo screens. /// class TitleMenu : MenuComponent { // Constants. const float XnaSpawnRate = 1.5f; const float XnaLifespan = 7; // Fields. int attractCycle; float time; Random random = new Random(); // We display a set of floating "xna" text labels in the background of the menu. class FloatingXna { public Vector2 Position; public float Age; public float Size; } List floatingXnas = new List(); /// /// Constructor. /// public TitleMenu(DemoGame game) : base(game) { Entries.Add(new MenuEntry { Text = "basic effect", Clicked = delegate { Game.SetActiveMenu(1); } }); Entries.Add(new MenuEntry { Text = "dual texture effect", Clicked = delegate { Game.SetActiveMenu(2); } }); Entries.Add(new MenuEntry { Text = "alpha test effect", Clicked = delegate { Game.SetActiveMenu(3); } }); Entries.Add(new MenuEntry { Text = "skinned effect", Clicked = delegate { Game.SetActiveMenu(4); } }); Entries.Add(new MenuEntry { Text = "environment map effect", Clicked = delegate { Game.SetActiveMenu(5); } }); Entries.Add(new MenuEntry { Text = "particles", Clicked = delegate { Game.SetActiveMenu(6); } }); Entries.Add(new MenuEntry { Text = "quit", Clicked = delegate { game.Exit(); } }); } /// /// Resets the menu state. /// public override void Reset() { floatingXnas.Clear(); time = 0; base.Reset(); } /// /// The main menu wants a shorter attract delay than the other screens. /// override protected TimeSpan AttractDelay { get { return TimeSpan.FromSeconds(3); } } /// /// When the attract mode timeout is reached, we cycle through each other screen in turn. /// override protected void OnAttract() { Entries[attractCycle].OnClicked(); if (++attractCycle >= Entries.Count - 1) attractCycle = 0; } /// /// Updates the floating "xna" background labels. /// public override void Update(GameTime gameTime) { time += (float)gameTime.ElapsedGameTime.TotalSeconds; // Spawn a new label? if (time > XnaSpawnRate) { FloatingXna xna = new FloatingXna(); xna.Size = (float)random.NextDouble() * 2 + 0.5f; xna.Position.X = (float)random.NextDouble() * 320 + 80; xna.Position.Y = (float)random.NextDouble() * 700 + 50; floatingXnas.Add(xna); time -= XnaSpawnRate; } // Animate the existing labels. int i = 0; while (i < floatingXnas.Count) { FloatingXna xna = floatingXnas[i]; xna.Age += (float)gameTime.ElapsedGameTime.TotalSeconds; // Different size labels move at different speeds. float speed = 1.5f - xna.Size; if (Math.Abs(speed) > 0.01f) xna.Position.Y -= xna.Age * xna.Age / speed / 10; // Remove old labels. if (xna.Age >= XnaLifespan) floatingXnas.RemoveAt(i); else i++; } base.Update(gameTime); } /// /// Draws the main menu. /// public override void Draw(GameTime gameTime) { DrawTitle("xna demo", Color.CornflowerBlue, Color.Lerp(Color.Blue, Color.CornflowerBlue, 0.85f)); // Draw the background "xna" labels. SpriteBatch.Begin(); foreach (FloatingXna blob in floatingXnas) { float alpha = Math.Min(blob.Age, 1) * Math.Min((XnaLifespan - blob.Age) / (XnaLifespan - 2), 1); alpha *= alpha; alpha /= 8; SpriteBatch.DrawString(BigFont, "xna", blob.Position, Color.Blue * alpha, MathHelper.PiOver2, Vector2.Zero, blob.Size, 0, 0); } SpriteBatch.End(); // This will draw the various menu items. base.Draw(gameTime); } } }