Пример #1
0
        /// <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() {
            // We don't want XNA calling this method each time we resume from the menu,
            // unfortunately, it'll call it whatever we try. So the only thing
            // we can do is check if it has been called already and return. Yes, it's ugly.
            if (spriteBatch_ != null) {
                GhostSoundsManager.ResumeLoops();
                return;
            }
            // Otherwise, this is the first time this component is Initialized, so proceed.

            GhostSoundsManager.Init(Game);

            Grid.Reset();
            Constants.Level = 1;
            spriteBatch_ = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));
            graphics_ = (GraphicsDeviceManager)Game.Services.GetService(typeof(GraphicsDeviceManager));
            soundBank_ = (SoundBank)Game.Services.GetService(typeof(SoundBank));

            scoreFont_ = Game.Content.Load<SpriteFont>("Score");
            scoreEventFont_ = Game.Content.Load<SpriteFont>("ScoreEvent");
            xlife_ = Game.Content.Load<Texture2D>("sprites/ExtraLife");
            ppill_ = Game.Content.Load<Texture2D>("sprites/PowerPill");
            crump_ = Game.Content.Load<Texture2D>("sprites/Crump");
            board_ = Game.Content.Load<Texture2D>("sprites/Board");
            boardFlash_ = Game.Content.Load<Texture2D>("sprites/BoardFlash");
            bonusEaten_ = new Dictionary<string, int>();
            bonus_ = new Dictionary<string, Texture2D>(9);
            bonus_.Add("Apple", Game.Content.Load<Texture2D>("bonus/Apple"));
            bonus_.Add("Banana", Game.Content.Load<Texture2D>("bonus/Banana"));
            bonus_.Add("Bell", Game.Content.Load<Texture2D>("bonus/Bell"));
            bonus_.Add("Cherry", Game.Content.Load<Texture2D>("bonus/Cherry"));
            bonus_.Add("Key", Game.Content.Load<Texture2D>("bonus/Key"));
            bonus_.Add("Orange", Game.Content.Load<Texture2D>("bonus/Orange"));
            bonus_.Add("Pear", Game.Content.Load<Texture2D>("bonus/Pear"));
            bonus_.Add("Pretzel", Game.Content.Load<Texture2D>("bonus/Pretzel"));
            bonus_.Add("Strawberry", Game.Content.Load<Texture2D>("bonus/Strawberry"));

            scoreEvents_ = new List<ScoreEvent>(5);
            bonusPresent_ = false;
            bonusSpawned_ = 0;
            eatenGhosts_ = 0;
            Score = 0;
            xlives_ = 2;
            paChomp_ = true;
            playerDied_ = false;
            player_ = new Player(Game);
            ghosts_ = new List<Ghost> { new Ghost(Game, player_, Ghosts.Blinky), new Ghost(Game, player_, Ghosts.Clyde),
                                        new Ghost(Game, player_, Ghosts.Inky), new Ghost(Game, player_, Ghosts.Pinky)};
            ghosts_[2].SetBlinky(ghosts_[0]); // Oh, dirty hack. Inky needs this for his AI.
            soundBank_.PlayCue("Intro");
            LockTimer = TimeSpan.FromMilliseconds(4500);

            base.Initialize();
        }
Пример #2
0
 /// <summary>
 /// Put the ghosts back in their home, ready to begin a new attack
 /// </summary>
 /// <param name="newLevel">True at level start, false otherwise</param>
 /// <param name="player">The pac man. Pac Man is often respawned with the ghosts, so they need to know about the new Pac Man.</param>
 public void Reset(bool newLevel, Player player) {
     State = GhostState.Home; // Ghosts start at home
     previousState_ = GhostState.Home; // Sounds are played when currentState != previousState.
     // So to get them playing at level start, we do this simple hack.
     updateCount_ = 0;
     initialJumps_ = Constants.InitialJumps(identity_, newLevel);
     position_ = Constants.startPosition(identity_);
     scheduleStateEval_ = true;
     lastJunction_ = new Point();
     player_ = player;
     scatterModesLeft_ = 4;
     UpdateSpeed();
 }
Пример #3
0
 /// <summary>
 /// Instantiates a ghost.
 /// </summary>
 /// <param name="game">A reference to the Game object, needed for access to services.</param>
 /// <param name="player">A reference to the Pac Man, needed for AI.</param>
 /// <param name="identity">Which ghost, needed for appearance and behavior.</param>
 public Ghost(Game game, Player player, Ghosts identity) {
     spriteBatch_ = (SpriteBatch)game.Services.GetService(typeof(SpriteBatch));
     ghostBase1_ = game.Content.Load<Texture2D>("sprites/GhostBase");
     ghostBase2_ = game.Content.Load<Texture2D>("sprites/GhostBase2");
     ghostChased_ = game.Content.Load<Texture2D>("sprites/GhostChased");
     eyesBase_ = game.Content.Load<Texture2D>("sprites/GhostEyes");
     eyesCenter_ = game.Content.Load<Texture2D>("sprites/GhostEyesCenter");
     colorBase_ = Constants.colors(identity);
     identity_ = identity;
     previousNumCrumps_ = 0;
     Reset(true, player);
     wiggle_ = true;
     direction_ = new Direction();
     lastJunction_ = new Point();
     scatterTiles_ = Constants.scatterTiles(identity);
 }
Пример #4
0
        /// <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) {

            // Some events (death, new level, etc.) lock the game for a few moments.
            if (DateTime.Now - eventTimer_ < LockTimer) {
                ghosts_.ForEach(i => i.LockTimer(gameTime));
                // Also we need to do the same thing for our own timer concerning bonuses
                bonusSpawnedTime_ += gameTime.ElapsedGameTime;
                return;
            }

            // Remove special events older than 5 seconds
            scoreEvents_.RemoveAll(i => DateTime.Now - i.When > TimeSpan.FromSeconds(5));

            // If the player had died, spawn a new one or end game.
            if (playerDied_) {
                // extra lives are decremented here, at the same time the pac man is spawned; this makes those 
                // events seem linked.
                xlives_--;
                //xlives_++; // Give infinite lives to the evil developer;
                if (xlives_ >= 0) {
                    playerDied_ = false;
                    player_ = new Player(Game);
                    ghosts_.ForEach(i => i.Reset(false, player_));
                    scoreEvents_.Clear();
                }
                else { // The game is over
                    Menu.SaveHighScore(Score);
                    Game.Components.Add(new Menu(Game, null));
                    Game.Components.Remove(this);
                    GhostSoundsManager.StopLoops();
                    return;
                }
            }

            // When all crumps have been eaten, wait a few seconds and then spawn a new level
            if (noCrumpsLeft()) {
                if (Constants.Level < 21) {
                    bonusSpawned_ = 0;
                    Grid.Reset();
                    player_ = new Player(Game);
                    ghosts_.ForEach(i => i.Reset(true, player_));
                    soundBank_.PlayCue("NewLevel");
                    LockTimer = TimeSpan.FromSeconds(2);
                    Constants.Level++;
                    return;
                }
                else { // Game over, you win.
                    Menu.SaveHighScore(Score);
                    Game.Components.Add(new Menu(Game, null));
                    Game.Components.Remove(this);
                    GhostSoundsManager.StopLoops();
                    return;
                }
            }

            Keys[] inputKeys = Keyboard.GetState().GetPressedKeys();
            // The user may escape to the main menu with the escape key
            if (inputKeys.Contains(Keys.Escape)) {
                Game.Components.Add(new Menu(Game, this));
                Game.Components.Remove(this);
                GhostSoundsManager.PauseLoops(); // will be resumed in Initialize(). No need for stopping them
                // if the player subsequently quits the game, since we'll re-initialize GhostSoundManager in
                // Initialize() if the player wants to start a new game.
                return;
            }

            // Eat crumps and power pills.
            if (player_.Position.DeltaPixel == Point.Zero) {
                Point playerTile = player_.Position.Tile;
                if (Grid.TileGrid[playerTile.X, playerTile.Y].HasCrump) {
                    soundBank_.PlayCue(paChomp_ ? "PacMAnEat1" : "PacManEat2");
                    paChomp_ = !paChomp_;
                    Score += 10;
                    Grid.TileGrid[playerTile.X, playerTile.Y].HasCrump = false;
                    if (Grid.TileGrid[playerTile.X, playerTile.Y].HasPowerPill) {
                        Score += 40;
                        eatenGhosts_ = 0;
                        for (int i = 0; i < ghosts_.Count; i++) {
                            if (ghosts_[i].State == GhostState.Attack || ghosts_[i].State == GhostState.Scatter ||
                                ghosts_[i].State == GhostState.Blue) {
                                ghosts_[i].State = GhostState.Blue;
                            }
                        }
                        Grid.TileGrid[playerTile.X, playerTile.Y].HasPowerPill = false;
                    }

                    // If that was the last crump, lock the game for a while
                    if (noCrumpsLeft()) {
                        GhostSoundsManager.StopLoops();
                        LockTimer = TimeSpan.FromSeconds(2);
                        return;
                    }
                }
            }

            // Eat bonuses
            if (bonusPresent_ && player_.Position.Tile.Y == 17 &&
                ((player_.Position.Tile.X == 13 && player_.Position.DeltaPixel.X == 8) ||
                  (player_.Position.Tile.X == 14 && player_.Position.DeltaPixel.X == -8))) {
                LockTimer = TimeSpan.FromSeconds(1.5);
                Score += Constants.BonusScores();
                scoreEvents_.Add(new ScoreEvent(player_.Position, DateTime.Now, Constants.BonusScores()));
                soundBank_.PlayCue("fruiteat");
                bonusPresent_ = false;
                if (bonusEaten_.ContainsKey(Constants.BonusSprite())) {
                    bonusEaten_[Constants.BonusSprite()]++;
                }
                else {
                    bonusEaten_.Add(Constants.BonusSprite(), 1);
                }
            }

            // Remove bonus if time's up
            if (bonusPresent_ && ((DateTime.Now - bonusSpawnedTime_) > TimeSpan.FromSeconds(10))) {
                bonusPresent_ = false;
            }

            // Detect collision between ghosts and the player
            foreach (Ghost ghost in ghosts_) {
                Rectangle playerArea = new Rectangle((player_.Position.Tile.X * 16) + player_.Position.DeltaPixel.X,
                                                     (player_.Position.Tile.Y * 16) + player_.Position.DeltaPixel.Y,
                                                      26,
                                                      26);
                Rectangle ghostArea = new Rectangle((ghost.Position.Tile.X * 16) + ghost.Position.DeltaPixel.X,
                                                    (ghost.Position.Tile.Y * 16) + ghost.Position.DeltaPixel.Y,
                                                    22,
                                                    22);
                if (!Rectangle.Intersect(playerArea, ghostArea).IsEmpty) {
                    // If collision detected, either kill the ghost or kill the pac man, depending on state.

                    if (ghost.State == GhostState.Blue) {
                        GhostSoundsManager.StopLoops();
                        soundBank_.PlayCue("EatGhost");
                        ghost.State = GhostState.Dead;
                        eatenGhosts_++;
                        int bonus = (int)(100 * Math.Pow(2, eatenGhosts_));
                        Score += bonus;
                        scoreEvents_.Add(new ScoreEvent(ghost.Position, DateTime.Now, bonus));
                        LockTimer = TimeSpan.FromMilliseconds(900);
                        return;
                    }
                    else if (ghost.State != GhostState.Dead ) {
                        KillPacMan();
                        return;
                    }
                    // Otherwise ( = the ghost is dead), don't do anything special.
                }
            }

            // Periodically spawn a fruit, when the player isn't on the spawn location
            // otherwise we get an infinite fruit spawning bug
            if ((Grid.NumCrumps == 180 || Grid.NumCrumps == 80) && bonusSpawned_ < 2 &&
                ! (player_.Position.Tile.Y == 17 &&
                    ((player_.Position.Tile.X == 13 && player_.Position.DeltaPixel.X == 8) ||
                    (player_.Position.Tile.X == 14 && player_.Position.DeltaPixel.X == -8)))) {
                bonusPresent_ = true;
                bonusSpawned_++;
                bonusSpawnedTime_ = DateTime.Now;

            }

            // Now is the time to move player based on inputs and ghosts based on AI
            // If we have returned earlier in the method, they stay in place
            player_.Update(gameTime);
            ghosts_.ForEach(i => i.Update(gameTime));

            base.Update(gameTime);
        }