| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | using System;using System.IO;using System.Linq;using System.Collections.Generic;using Microsoft.Xna.Framework;using Microsoft.Xna.Framework.Audio;using Microsoft.Xna.Framework.Content;//using Microsoft.Xna.Framework.GamerServices;using Microsoft.Xna.Framework.Graphics;using Microsoft.Xna.Framework.Input;using Microsoft.Xna.Framework.Media;//using Microsoft.Xna.Framework.Net;//using Microsoft.Xna.Framework.Storage;namespace PacMan {    /// <summary>    /// This is a game component that implements IUpdateable.    /// </summary>    /// Optionally takes a GameLoop argument, when the menu must be able to    /// resume the current GameLoop. Otherwise, the reference would be lost    /// and the gameLoop garbage collected.    public class Menu : Microsoft.Xna.Framework.DrawableGameComponent {        public Menu(Game game, GameLoop gameLoop)            : base(game) {            gameLoop_ = gameLoop;            gameStart_ = (gameLoop == null);        }        /// <summary>        /// Allows the game component to perform any initialization it needs to before starting        /// to run.  This is where it can query for any required services and load content.        /// </summary>        public override void Initialize() {            spriteBatch_ = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));            graphics_ = (GraphicsDeviceManager)Game.Services.GetService(typeof(GraphicsDeviceManager));            soundBank_ = (SoundBank)Game.Services.GetService(typeof(SoundBank));            selection_ = 0;            if (gameLoop_ == null) {                items_ = new string[] { "New Game", "High Scores", "Quit" };            }            else {                items_ = new string[] { "Resume", "Quit Game" };            }            menuItem_ = Game.Content.Load<SpriteFont>("MenuItem");            title_ = Game.Content.Load<Texture2D>("sprites/Title");            selectionArrow_ = Game.Content.Load<Texture2D>("sprites/Selection");            oldState_ = Keyboard.GetState();            base.Initialize();        }        /// <summary>        /// Allows the game component to update itself.        /// </summary>        /// <param name="gameTime">Provides a snapshot of timing values.</param>        public override void Update(GameTime gameTime) {            base.Update(gameTime);            // Wonder why we test for this condition? Just replace gameStart_ by true and            // try running the game. The answer should be instantaneous.            if (gameStart_) {                soundBank_.PlayCue("NewLevel");                gameStart_ = false;            }                        KeyboardState newState = Keyboard.GetState();                        // Get keys pressed now that weren't pressed before            var newPressedKeys = from k in newState.GetPressedKeys()                                 where !(oldState_.GetPressedKeys().Contains(k))                                 select k;                         // Scroll through menu items            if (newPressedKeys.Contains(Keys.Down)) {                selection_++;                selection_ %= items_.Length;                soundBank_.PlayCue("PacMAnEat1");            }            else if (newPressedKeys.Contains(Keys.Up)) {                selection_--;                selection_ = (selection_ < 0? items_.Length -1 : selection_);                soundBank_.PlayCue("PacManEat2");            }            else if (newPressedKeys.Contains(Keys.Enter)) {                menuAction();            }            // Update keyboard state for next update            oldState_ = newState;                    }        /// <summary>        /// This is called when the game should draw itself.        /// </summary>        /// <param name="gameTime">Provides a snapshot of timing values.</param>        public override void Draw(GameTime gameTime) {            base.Draw(gameTime);            // The menu is a main component, so it is responsible for initializing the sprite batch each frame            spriteBatch_.Begin();            // Draw title            spriteBatch_.Draw(title_, new Vector2((graphics_.PreferredBackBufferWidth / 2) - (title_.Width / 2), 75), Color.White);            // Draw items            Vector2 itemPosition;            itemPosition.X = (graphics_.PreferredBackBufferWidth / 2) - 100;            for (int i = 0; i < items_.Length; i++) {                itemPosition.Y = (graphics_.PreferredBackBufferHeight / 2) - 60 + (60 * i);                if (i == selection_) {                    spriteBatch_.Draw(selectionArrow_, new Vector2(itemPosition.X - 50, itemPosition.Y), Color.White);                }                spriteBatch_.DrawString(menuItem_, items_[i], itemPosition, Color.Yellow);            }            spriteBatch_.End();        }        void menuAction() {            Game.Components.Remove(this);            switch (items_[selection_]) {                case ("Resume"):                    Game.Components.Add(gameLoop_);                    break;                case ("New Game") :                    Game.Components.Add(new GameLoop(Game));                    break;                case ("High Scores"):                    Game.Components.Add(new HighScores(Game));                    break;                case ("Quit"):                    Game.Exit();                    break;                case ("Quit Game"):                    Game.Components.Add(new Menu(Game, null));                    SaveHighScore(gameLoop_.Score);                    break;                default:                    throw new ArgumentException("\"" + items_[selection_] + "\" is not a valid case");            }        }        /// <summary>        /// Keep a history of the best 10 scores        /// </summary>        /// <param name="highScore">New score to save, might make it inside the list, might not.</param>        public static void SaveHighScore(int highScore) {            const string fileName = "highscores.txt";            if (!File.Exists(fileName)) {                File.WriteAllLines(fileName, new string[] { highScore.ToString() });            }            else {                List<string> contents = File.ReadAllLines(fileName).ToList<string>();                contents.Add(highScore.ToString());                if (contents.Count >= 10) {                    contents.Sort((a, b) => Convert.ToInt32(a).CompareTo(Convert.ToInt32(b)));                    while (contents.Count > 10) {                        contents.RemoveAt(0);                    }                }                File.WriteAllLines(fileName, contents.ToArray());            }        }        GameLoop gameLoop_;        SoundBank soundBank_;        GraphicsDeviceManager graphics_;        SpriteBatch spriteBatch_;        SpriteFont menuItem_;        string[] items_;        int selection_;        bool gameStart_;        Texture2D title_;        Texture2D selectionArrow_;        KeyboardState oldState_;    }}
 |