Beispiel #1
0
        Texture2D[] skyboxTextures; // textures to display around the skybox

        #endregion Fields

        #region Methods

        /// <summary>
        /// Draw the skybox to the screen.
        /// </summary>
        /// <param name="device"></param>
        /// <param name="gameCamera">Used to get the view and projection matrices</param>
        /// <param name="player">The player's position governs where the skybox is drawn</param>
        public void Draw(ref GraphicsDevice device, Camera gameCamera, Player player)
        {
            device.SamplerStates[0] = clampTextureAddressMode;

            DepthStencilState dss = new DepthStencilState();
            dss.DepthBufferEnable = false;
            device.DepthStencilState = dss;

            Matrix[] skyboxTransforms = new Matrix[skyboxModel.Bones.Count];
            skyboxModel.CopyAbsoluteBoneTransformsTo(skyboxTransforms);
            int i = 0;
            foreach (ModelMesh mesh in skyboxModel.Meshes)
            {
                foreach (Effect currentEffect in mesh.Effects)
                {
                    Matrix worldMatrix = skyboxTransforms[mesh.ParentBone.Index] * Matrix.CreateTranslation(player.Position);
                    currentEffect.CurrentTechnique = currentEffect.Techniques["Textured"];
                    currentEffect.Parameters["xWorld"].SetValue(worldMatrix);
                    currentEffect.Parameters["xView"].SetValue(gameCamera.ViewMatrix);
                    currentEffect.Parameters["xProjection"].SetValue(gameCamera.ProjectionMatrix);
                    currentEffect.Parameters["xTexture"].SetValue(skyboxTextures[i++]);
                }
                mesh.Draw();
            }

            dss = new DepthStencilState();
            dss.DepthBufferEnable = true;
            device.DepthStencilState = dss;
        }
        /// <summary>
        /// Update the positions of the missile and, if applicable, updates the player's
        /// health if the player has been hit by a missile
        /// </summary>
        /// <param name="player">To update the player's health, if applicable</param>
        /// <param name="floorPlan">To determine if a missile is no longer in the map</param>
        /// <param name="gameState">The current state of the game</param>
        /// <remarks>
        /// If the player has lost all health, the game will transition to the end state
        /// </remarks>
        public void Update(Player player, int[,] floorPlan, ref GameConstants.GameState gameState)
        {
            // update each missile
            for (int i = 0; i < missileList.Count; i++)
            {
                missileList[i].Update();

                if (missileList[i].Position.Y < 0.0f ||
                    floorPlan[(int)missileList[i].Position.X, (int)-missileList[i].Position.Z] != 0)
                {
                    // this missile is off of the map (either ran into a building or under the map)
                    missileList.Remove(missileList[i]);
                    continue;
                }

                if (player.BoundingSphere.Contains(missileList[i].Position) != ContainmentType.Disjoint)
                {
                    // the player was hit
                    missileList.Remove(missileList[i]);
                    player.HitByMissile(ref gameState);
                    explosionEffect.Play();
                }
            }
        }
Beispiel #3
0
        private Texture2D whiteRect; // holds a white rectangle texture

        #endregion Fields

        #region Methods

        /// <summary>
        /// Draw the minimap to the screen
        /// </summary>
        /// <param name="gameTime">Gives information on elapsed time for flashing enemies</param>
        /// <param name="player">The position of player is needed for minimap</param>
        /// <param name="enemies">The position of enemies is needed for minimap</param>
        /// <param name="map">The position of the fuel barrels and building is needed for minimap</param>
        public void Draw(GameTime gameTime, Player player, Enemies enemies, Map map)
        {
            // this rectangle describes the position on screen where an object will be drawn
            Rectangle rect = new Rectangle();
            rect.Width = (int) Math.Round((rectWidth * GameConstants.ViewportWidth));
            rect.Height = (int) Math.Round((rectHeight * GameConstants.ViewportHeight));

            // get items to display
            int[,] floorPlan = map.FloorPlan;
            Fuel[] fuelBarrels = map.FuelBarrels;
            Bonuses bonuses = map.Bonuses;

            spriteBatch.Begin();

            // draw floor plan
            for (int x = 0; x < floorPlan.GetLength(0); x++)
            {
                for (int z = 0; z < floorPlan.GetLength(1); z++)
                {
                    if (floorPlan[x, z] != 0)
                    {
                        // move the rectangle into the correct position of the screen
                        rect.X = (int)(xOffset * GameConstants.ViewportWidth) + rect.Width * z;
                        rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * x;

                        spriteBatch.Draw(whiteRect, rect, Color.Orange);
                    }
                }
            }

            // draw fuel barrels
            for (int i = 0; i < fuelBarrels.Length; i++)
            {
                rect.X = (int) (xOffset * GameConstants.ViewportWidth) - rect.Width * (int)fuelBarrels[i].Position.Z;
                rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * (int)fuelBarrels[i].Position.X;
                spriteBatch.Draw(whiteCircle, rect, Color.White);
            }

            // draw bonuses
            foreach (Bonus b in bonuses)
            {
                rect.X = (int)(xOffset * GameConstants.ViewportWidth) - rect.Width * (int)b.Position.Z;
                rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * (int)b.Position.X;
                spriteBatch.Draw(whiteCircle, rect, Color.Purple);
            }

            // draw player
            rect.X = (int)(xOffset * GameConstants.ViewportWidth) - rect.Width * (int)player.Position.Z;
            rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * (int)player.Position.X;
            spriteBatch.Draw(whiteRect, rect, Color.Green);

            // draw enemies
            foreach (Enemy e in enemies)
            {
                if (e.Chasing == true)
                {
                    // flash twice per second if chasing
                    if (gameTime.TotalGameTime.TotalMilliseconds % 500 < 250)
                    {
                        rect.X = (int)(xOffset * GameConstants.ViewportWidth) - rect.Width * (int)e.Position.Z;
                        rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * (int)e.Position.X;
                        spriteBatch.Draw(whiteRect, rect, Color.Red);
                    }
                }
                else
                {
                    rect.X = (int)(xOffset * GameConstants.ViewportWidth) - rect.Width * (int)e.Position.Z;
                    rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * (int)e.Position.X;
                    spriteBatch.Draw(whiteRect, rect, Color.Red);
                }
            }

            //draw enemies next positions (for debugging)
            //foreach (Enemy e in enemies)
            //{
            //    rect.X = (int)(xOffset * GameConstants.ViewportWidth) - rect.Width * (int)e.nextPosition.Z;
            //    rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * (int)e.nextPosition.X;
            //    spriteBatch.Draw(whiteRect, rect, Color.Purple);
            //}

            //draw the enemies A* path (for debugging)
            //if (Helpers.AStarDebugList != null)
            //{
            //    for (int i = 1; i < Helpers.AStarDebugList.Count - 1; i++)
            //    {
            //        rect.X = (int)(xOffset * GameConstants.ViewportWidth) + rect.Width * (int)Helpers.AStarDebugList[i].Y;
            //        rect.Y = (int)(yOffset * GameConstants.ViewportHeight) + rect.Height * (int)Helpers.AStarDebugList[i].X;
            //        spriteBatch.Draw(whiteRect, rect, Color.Pink);
            //    }
            //}

            spriteBatch.End();
        }
Beispiel #4
0
        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // set up the display window
            graphics.PreferredBackBufferWidth = 500;
            graphics.PreferredBackBufferHeight = 500;
            graphics.ApplyChanges();

            // update the ViewportHeight and ViewportWidth constants so the screens know
            // how to draw themselves
            GameConstants.ViewportHeight = graphics.GraphicsDevice.Viewport.Height;
            GameConstants.ViewportWidth = graphics.GraphicsDevice.Viewport.Width;

            // display title in the window
            Window.Title = "Alien Attack";

            // setup the state of the game
            currentGameState = GameConstants.GameState.Title;
            currentKeyboardState = Keyboard.GetState();
            prevKeyBoardState = currentKeyboardState;

            // set up the screens
            titleScreen = new TitleScreen();
            instructionScreen = new InstructionScreen();
            highScoreScreen = new HighScoreScreen();
            creditsScreen = new CreditsScreen();
            introScreen = new IntroScreen();
            readyScreen = new GetReadyScreen();
            gameOverScreen = new GameOverScreen();

            // set up the game objects
            gameCamera = new Camera();
            player = new Player();
            enemies = new Enemies();
            map = new Map();
            miniMap = new MiniMap();
            skybox = new Skybox();

            // set up the ingame displays
            score = new Score();
            highScore = new HighScore();

            // set up the soundtrack
            gameSongs = new GameSongs();

            base.Initialize();
        }
Beispiel #5
0
        /// <summary>
        /// Returns true if this enemy is the closest enemy to the player in terms
        /// of linear distance and no other enemy is chasing, false otherwise
        /// </summary>
        /// <param name="player">For the player's position</param>
        /// <param name="enemies">For the position of the enemies</param>
        private bool ShouldMoveTowardPlayer(Player player, Enemies enemies)
        {
            float distanceToPlayer = Helpers.LinearDistance2D(Position, player.Position);

            foreach (Enemy e in enemies)
            {
                if (e != this)
                {
                    if (distanceToPlayer > Helpers.LinearDistance2D(e.Position, player.Position) ||
                        e.chasing == true)
                        return false;
                }
            }

            return true;
        }
Beispiel #6
0
        /// <summary>
        /// Sets the foward direction of the enemy to point toward the player
        /// </summary>
        /// <param name="player">For the player's position</param>
        private void SetDirectionTowardPlayer(Player player)
        {
            int xOffsetPToE = (int)player.Position.X - (int)Position.X; // x displacement from player to enemy
            int zOffsetPToE = (int)-player.Position.Z + (int)Position.Z;// z displacement from player to enemy

            if (zOffsetPToE != 0)
            {
                // Must move left or right
                if (zOffsetPToE > 0)
                {
                    // Move right
                    ForwardDirection = 0;
                }
                else
                {
                    // Move left
                    ForwardDirection = MathHelper.Pi;
                }
            }
            else
            {
                // Must move up or down
                if (xOffsetPToE > 0)
                {
                    // Move down, player below
                    ForwardDirection = 3 * MathHelper.PiOver2;
                }
                else
                {
                    // Move up, player above
                    ForwardDirection = MathHelper.PiOver2;
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// This method implements dead reckoning.  Based on the position of the player, the velocity
        /// of the player, and the velocity of the missile, the target position
        /// where the missile should be fired to strike the enemy is calculated.
        /// </summary>
        /// <param name="player">For the player position</param>
        /// <returns>
        /// A vector representing the target position the enemy should fire
        /// a missile.
        /// </returns>
        private Vector3 FindTargetPosition(Player player)
        {
            Vector3 target = new Vector3(0.0f, player.Position.Y, 0.0f);

            // Uses an approximation to determine where to fire the misile
            // 1) Calculate the distance between user and the missile
            // 2) Calculate the time (t) for the missile to travel to the user given the speed of the missile
            // 3) Calculate the position of the player at time (t)

            float d_enemyToPlayer = Helpers.LinearDistance2D(player.Position, this.Position); // 1
            float t_missiletoplayer = d_enemyToPlayer / Missile.MissileSpeed; // 2
            target.X = player.Position.X - player.Velocity * (float)Math.Sin(player.ForwardDirection) * t_missiletoplayer; // 3
            target.Z = player.Position.Z - player.Velocity * (float)Math.Cos(player.ForwardDirection) * t_missiletoplayer; // 3
            return target;
        }
Beispiel #8
0
        /// <summary>
        /// Checks if the player is in the line of sight of the enemy, that is, there are no building
        /// or other enemies between the player and the enemy craft
        /// </summary>
        /// <param name="player">For the player's position</param>
        /// <param name="floorPlan">For the layout of the building</param>
        /// <returns>True if the enemy can see the player, false otherwise</returns>
        private bool CheckIfInLineOfSight(Player player, int[,] floorPlan)
        {
            int xOffsetToPlayer = (int)player.Position.X - (int)Position.X; // x displacement from player to enemy
            int zOffsetToPlayer = (int)-player.Position.Z + (int)Position.Z;// z displacement from player to enemy
            bool inLineOfSight = false; // can we see the player?

            if (zOffsetToPlayer == 0)
            {
                inLineOfSight = true;   // assume that we can see the player

                // move up the map to the player position and check for obstacles in the way
                // if there are obstacles, mark inLineOfSight false and break
                for (int i = (int)Position.X; i < (int)player.Position.X; i++)
                {
                    if (floorPlan[i, (int)-Position.Z] != 0)
                    {
                        inLineOfSight = false;
                        break;
                    }
                }

                // move down the map to the player position and check for obstacles in the way
                // if there are obstacles, mark inLineOfSight false and break
                for (int i = (int)Position.X; i > (int)player.Position.X; i--)
                {
                    if (floorPlan[i, (int)-Position.Z] != 0)
                    {
                        inLineOfSight = false;
                        break;
                    }
                }
            }
            else if (xOffsetToPlayer == 0)
            {
                inLineOfSight = true;

                // move right on the map to the player position and check for obstacles in the way
                // if there are obstacles, mark inLineOfSight false and break
                for (int i = (int)-Position.Z; i < (int)-player.Position.Z; i++)
                {
                    if (floorPlan[(int)Position.X, i] != 0)
                    {
                        inLineOfSight = false;
                        break;
                    }
                }

                // move left on the map to the player position and check for obstacles in the way
                // if there are obstacles, mark inLineOfSight false and break
                for (int i = (int)-Position.Z; i > (int)-player.Position.Z; i--)
                {
                    if (floorPlan[(int)Position.X, i] != 0)
                    {
                        inLineOfSight = false;
                        break;
                    }
                }
            }

            return inLineOfSight;
        }
Beispiel #9
0
        /// <summary>
        /// Allows the client to move the enemy craft
        /// </summary>
        /// <param name="enemies">For positions of all of the other enemies in the game</param>
        /// <param name="player">Allows queries for attributes of the player</param>
        /// <param name="floorPlan">Gives the arrangement of the building in the city</param>
        ///<param name="gameTime">Information on the time since last update for missiles</param>
        /// <param name="gameState">Gives the current state of the game</param>
        /// <remarks>
        /// If the player is caught or the player is hit by a missile and runs
        /// out of health, the gamestate will transition to end
        /// </remarks>
        public void Update(Enemies enemies, Player player, int[,] floorPlan, GameTime gameTime, 
                           ref GameConstants.GameState gameState)
        {
            bool canMakeMovement = false;   // boolean for status if the player was able to make a move on this update
            Vector3 movement;               // the movement to be applied to the enemy

            // check if the player has been caught, that is the enemy craft and player are in the same
            // grid unit, and if so transition to game ending state
            if (((int)Position.X - (int)player.Position.X) == 0 && ((int)Position.Z - (int)player.Position.Z) == 0)
            {
                gameState = GameConstants.GameState.End;
                return;
            }

            // Update the missiles and time during chase
            missiles.Update(player, floorPlan, ref gameState);
            if (chasing)
            {
                // Update the timeOfChase with the elapsed time since the last update
                timeOfChase += gameTime.ElapsedGameTime.TotalSeconds;
            }

            if (ReadyForNextMove())
            {
                // mark the spots on the grid where the enemies are and where they are headed in the next move
                MarkEnemySquares(enemies, floorPlan);

                // the player is in the center of a grid square, and can decide on the next direction to face
                // now, check if the player is in the enemy's line of sight (no buildings or enemies obstructing view
                // from enemy to player), and, if so, set the chasing property
                // to true
                chasing = CheckIfInLineOfSight(player, floorPlan);

                if (chasing)
                {
                    // we are chasing the player, set direction toward the player
                    SetDirectionTowardPlayer(player);

                    // we can make a movement since nothing is obstructing between player and this enemy
                    canMakeMovement = true;

                    // Check if we are locked on to the player, and if so, attempt to fire
                    if (this.LockedOn)
                    {
                        missiles.FireAt(this.Position, FindTargetPosition(player), gameTime);
                    }
                }
                else
                {
                    // reset the time of chase to zero since we are not chasing
                    timeOfChase = 0.0;

                    // check to see if no other enemyies are chasing and this is the closest enemy
                    // in terms of linear distance
                    // If so, find an A* path to the player if possible.
                    // This makes the game more challenging since the player will always be under pressure
                    // from some enemy
                    if (ShouldMoveTowardPlayer(player, enemies))
                    {
                        List<Vector2> aStarPath = AStar.FindPath(floorPlan, Position, player.Position);
                        //Helpers.AStarDebugList = aStarPath;

                        if (aStarPath == null)
                        {
                            // We could not find an A* path to the player, move randomly
                            canMakeMovement = MoveRandomly(floorPlan); // returns true if a move was able to be made
                        }
                        else
                        {
                            // set the enemy direction to follow the A* path
                            UpdateDirectionFromPath(aStarPath);
                            canMakeMovement = true;
                        }
                    }
                    else
                    {
                        // we are not chasing or the closest enemy
                        // move randomly around the grid until we spot the player next
                        canMakeMovement = MoveRandomly(floorPlan); // returns true if a move was able to be made
                    }
                }

                // unmark the spots on the grid where the enemies are and where they are headed in the next move
                UnmarkEnemySquares(enemies, floorPlan);

                if (!canMakeMovement)
                {
                    // the enemy is surrounded and cannot make a move
                    // set velocity to zero and stay put for this move
                    speed = 0.0f;
                }
                else
                {
                    // update positionOfLastMove with grid square of current position
                    positionOfLastMove = new Rectangle((int)Position.X, (int)-Position.Z, 1, 1);

                    // update nextPosition with next grid space in the direction
                    // we are headed
                    nextPosition = new Rectangle(
                        (int)(Position.X - Math.Sin(ForwardDirection)),
                        (int)(Position.Z - Math.Cos(ForwardDirection)), 1, 1);

                    speed = EnemySpeed;
                }
            }

            // Make the movement
            movement = Vector3.Transform(new Vector3(0.0f, 0.0f, -1.0f), Matrix.CreateRotationY(ForwardDirection));
            movement *= speed;
            UpdatePositionAndBoundingSphere(Position + movement);
        }
Beispiel #10
0
        /// <summary>
        /// Moves the enemy towards the player when the game is over or during the introduction
        /// </summary>
        /// <param name="player">For the position of the player</param>
        /// <remarks>
        /// This method is called when the game is over or during the intrdocution.  
        /// It is known that this enemy and the player are in valid positions.  Thus, no checks are
        /// made to ensure the location is valid.
        /// </remarks>
        public void MoveTowardPlayer(Player player)
        {
            Vector3 movement;
            float distancePlayerToEnemy = Helpers.LinearDistance2D(this.Position, player.Position);

            if (distancePlayerToEnemy > speed)
            {
                // we are atleast one timestep away from the player, move toward the player

                // find direction from this enemy's position to the player
                ForwardDirection = (float) Math.Atan2(Position.X - player.Position.X, -player.Position.Z + Position.Z);

                // Make the movement
                movement = Vector3.Transform(new Vector3(0.0f, 0.0f, -1.0f), Matrix.CreateRotationY(ForwardDirection));
                movement *= speed;
                UpdatePositionAndBoundingSphere(Position + movement);
            }
        }