/// <summary> /// This is called when the game should draw itself. /// </summary> /// <param name="gameTime">Provides a snapshot of timing values.</param> protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); //Fix for the depth state issue while drawing both 3D and 2D objects on screen //Fix found on: http://stackoverflow.com/questions/4996988/z-buffer-issue-by-mixing-2d-sprites-with-3d-model GraphicsDevice.DepthStencilState = DepthStencilState.Default; //Draw ground and walls for each room //Room1 DrawModel(floorModel, world, view, projection, floorTex, 1.5f, Vector3.Zero, new Vector3(0, 35, -10), true); DrawModel(wallModelLeft, world, view, projection, wallTex, 1.5f, new Vector3(0, MathHelper.PiOver2, 0), new Vector3(-85, 36, -15), true); DrawModel(wallModelRight, world, view, projection, wallTex, 1.5f, new Vector3(0, MathHelper.PiOver2, 0), new Vector3(85, 36, -15), true); DrawModel(wallModelVeryBack, world, view, projection, wallTex, 1.55f, new Vector3(MathHelper.PiOver2, 0, 0), new Vector3(0, -55, -15), true); DrawModel(wallModelBackLeft, world, view, projection, wallTex, 1.35f, new Vector3(MathHelper.PiOver2, 0, 0), new Vector3(-105, 120, -10), true); DrawModel(wallModelBackRight, world, view, projection, wallTex, 1.35f, new Vector3(MathHelper.PiOver2, 0, 0), new Vector3(105, 120, -10), true); DrawModel(exitDoorModel, world, view, projection, exitDoorTex, 1.35f, new Vector3(MathHelper.PiOver2, 0, 0), exitDoorPos, false); //Room2 DrawModel(floorModel, world, view, projection, floorTex, 1.5f, Vector3.Zero, new Vector3(0, 210, -10), true); DrawModel(wallModelLeft, world, view, projection, wallTex, 1.6f, new Vector3(0, MathHelper.PiOver2, 0), new Vector3(-85, 200, -15), true); DrawModel(wallModelRight, world, view, projection, wallTex, 1.6f, new Vector3(0, MathHelper.PiOver2, 0), new Vector3(85, 200, -15), true); DrawModel(wallModelBackLeft, world, view, projection, wallTex, 1.35f, new Vector3(MathHelper.PiOver2, 0, 0), new Vector3(-105, 300, -10), true); DrawModel(wallModelBackRight, world, view, projection, wallTex, 1.35f, new Vector3(MathHelper.PiOver2, 0, 0), new Vector3(105, 300, -10), true); DrawModel(exitDoorModel, world, view, projection, exitDoorTex, 1.35f, new Vector3(MathHelper.PiOver2, 0, 0), exitDoor2Pos, false); //Room3 DrawModel(floorModel, world, view, projection, floorTex, 1.5f, Vector3.Zero, new Vector3(0, 380, -10), true); DrawModel(wallModelLeft, world, view, projection, wallTex, 1.65f, new Vector3(0, MathHelper.PiOver2, 0), new Vector3(-85, 365, -15), true); DrawModel(wallModelRight, world, view, projection, wallTex, 1.65f, new Vector3(0, MathHelper.PiOver2, 0), new Vector3(85, 365, -15), true); DrawModel(wallModelVeryBack, world, view, projection, wallTex, 1.6f, new Vector3(MathHelper.PiOver2, 0, 0), new Vector3(0, 465, -10), true); //Draw Models heroCharacter.DrawModel(world, view, projection, mainCam); //Draw each enemy foreach (Enemy en in room1Enemies.Concat(room2Enemies).Concat(room3Enemies)) { if (en != null) { en.DrawModel(world, view, projection, mainCam); } } //Draw each hero attack for (int i = 0; i < heroCharacter.NumAttacks; i++) { foreach (HeroAttack hAttack in heroCharacter.OnScreenAttacks) { if (hAttack != null) { hAttack.DrawModel(world, view, projection, mainCam); } } } //Draw each boss attack if the enemy boss is present on screen if (enemyBoss != null) { foreach (BossAttack bAttack in enemyBoss.OnScreenBossAttacks) { if (bAttack != null) { bAttack.DrawModel(world, view, projection, mainCam); } } } //Draw the title screen if (gameState == 1 || gameState == 3) { spriteBatch.Begin(); //Draw the title screen if (gameState == 1) { spriteBatch.Draw(titleScreen, new Vector2(0, 0), Color.White); } //Draw the game over (win) or the game over (lose) screen if (gameState == 3) { //Game over death if (gameOverDeath) { spriteBatch.Draw(deathScreen, new Vector2(0, 0), Color.White); } else { //Game over win spriteBatch.Draw(winScreen, new Vector2(0, 0), Color.White); spriteBatch.DrawString(gameFont, "FINAL SCORE: " + gameScore, new Vector2(280, 300), Color.White); spriteBatch.DrawString(gameFont, "TIME COMPLETION: " + totalTimePlayed, new Vector2(280, 340), Color.White); } } spriteBatch.End(); } //ONLY DRAW THIS IF WE ARE IN THE GAME STATE if (gameState == 2) { //Draw text on the screen //Also draw the 2D health bars of the hero and the enemies spriteBatch.Begin(); //If the game is paused then draw that string on screen if (gamePaused) { spriteBatch.DrawString(gameFont, "GAME PAUSED", new Vector2(340, 50), Color.White); } //Draw Player Health Vector2 heroHealthPos = new Vector2(90, 15); int heroHealthPercentage = (int)((heroCharacter.Health / GameConstants.heroHealth) * 100); if (heroHealthPercentage >= 75) { healthBarColor = Color.Green; } else if (heroHealthPercentage >= 40) { healthBarColor = Color.Orange; } else { healthBarColor = Color.Red; } spriteBatch.DrawString(gameFont, "Health: ", new Vector2(10, 10), Color.White); spriteBatch.Draw(healthBar, heroHealthPos, new Rectangle((int)heroHealthPos.X, (int)heroHealthPos.Y, heroHealthPercentage, healthBar.Height), healthBarColor); spriteBatch.Draw(healthBarOutline, heroHealthPos, Color.White); //Draw amount of attacks left spriteBatch.DrawString(gameFont, "Attacks Left: " + (GameConstants.heroNumAttacks - heroCharacter.NumAttacks), new Vector2(10, 30), Color.White); //Draw string for turning sound on and off if (soundOff) { spriteBatch.DrawString(gameFont, "Press W to turn the sound ON.", new Vector2(10, 50), Color.White); } else { spriteBatch.DrawString(gameFont, "Press W to turn the sound OFF.", new Vector2(10, 50), Color.White); } //Draw Game Time TimeSpan ts = gameTime.TotalGameTime; string timePlayed = string.Format("{0}:{1}", Math.Floor(ts.TotalMinutes), ts.ToString("ss")); spriteBatch.DrawString(gameFont, "Time Played: " + timePlayed, new Vector2(580, 10), Color.White); //Draw Enemy Health foreach (Enemy en in room1Enemies.Concat(room2Enemies).Concat(room3Enemies)) { if (en != null) { //Convert to screen space. (0,0) in spriteBatch isn't same as the camera's view matrix Vector3 screenSpace = GraphicsDevice.Viewport.Project(Vector3.Zero, mainCam.projectionMatrix, mainCam.viewMatrix, Matrix.CreateTranslation(en.Position)); Vector2 healthPos; if (en.IsBoss) { //Boss health should be placed slightly lower healthPos = new Vector2((int)screenSpace.X - (healthBarOutline.Width / 2), (int)screenSpace.Y + 60); } else { //Regular enemy health position healthPos = new Vector2((int)screenSpace.X - (healthBarOutline.Width / 2), (int)screenSpace.Y + 25); } //Get the health of the enemy as a percentage between 0 and 100 //Assign a color of the health depending on how much is left i.e. Green - most health, Red - near death int enemyHealthPercentage = (int)((en.Health / en.InitHealth) * 100); if (enemyHealthPercentage >= 75) { healthBarColor = Color.Green; } else if (enemyHealthPercentage >= 40) { healthBarColor = Color.Orange; } else { healthBarColor = Color.Red; } spriteBatch.Draw(healthBar, healthPos, new Rectangle((int)healthPos.X, (int)healthPos.Y, enemyHealthPercentage, healthBar.Height), healthBarColor); spriteBatch.Draw(healthBarOutline, healthPos, Color.White); } } //Draw Game Score spriteBatch.DrawString(gameFont, "Total Score: " + gameScore, new Vector2(580, 30), Color.White); spriteBatch.End(); } base.Draw(gameTime); }