// Project: XnaShooter, File: Player.cs // Namespace: XnaShooter.Game, Class: Player // Path: C:\code\XnaShooter\Game, Author: Abi // Code lines: 182, Size of file: 5,41 KB // Creation date: 02.10.2006 01:33 // Last modified: 27.10.2006 02:40 // Generated with Commenter by abi.exDream.com #region Using directives using System; using System.Collections.Generic; using System.Text; using XnaShooter.GameScreens; using Microsoft.Xna.Framework; using XnaShooter.Helpers; using Microsoft.Xna.Framework.Input; using XnaShooter.Properties; using XnaShooter.Graphics; using XnaShooter.Sounds; #endregion namespace XnaShooter.Game { /// /// Player helper class, holds all the current game properties: /// Health, Weapon and Score. /// Note: This is a static class and holds always all player entries /// for the current game. If we would have more than 1 player (e.g. /// in multiplayer mode) this should not be a static class! /// static class Player { #region Variables /// /// Current game time in ms. Used for time display in game. Also used to /// update the level position. /// public static float gameTimeMs = 0; /// /// Won or lost? /// public static bool victory = false; /// /// Game over? /// private static bool gameOver = false; /// /// Is game over? /// /// Bool public static bool GameOver { get { return gameOver; } // get } // GameOver /// /// Remember if we already uploaded our highscore for this game. /// Don't do this twice (e.g. when pressing esc). /// static bool alreadyUploadedHighscore = false; /// /// Set game over and upload highscore /// public static void SetGameOverAndUploadHighscore() { // Set lifes to 0 and set gameOver to true to mark this game as ended. gameOver = true; // Upload highscore if (alreadyUploadedHighscore == false) { alreadyUploadedHighscore = true; Highscores.SubmitHighscore(score, Highscores.DefaultLevelName); } // if (alreadyUploadedHighscore) } // SetGameOverAndUploadHighscore() #endregion #region Current player values (health, weapon, etc.) /// /// Health, 1 means we have 100% health, everything below means we /// are damaged. If we reach 0, we die! /// public static float health = 1.0f; /// /// Weapon types we can carry with our ship /// public enum WeaponTypes { MG, Plasma, Gattling, Rockets, } // enum WeaponTypes /// /// Weapon we currently have, each weapon is replaced by the /// last collected one. No ammunition is used. /// public static WeaponTypes currentWeapon = WeaponTypes.MG; /// /// Do we have the EMP bomb? Press space to fire them. /// public static int empBombs = 0; /// /// Position where EMP was fired! /// public static Vector3 empPosition = Vector3.Zero; /// /// After firing the EMP bomb will deploy over the screen in about 1 sec. /// public static float empBombTimeout = 0; /// /// Time for an EMP bomb to explode everything on screen. /// const int MaxEmpTimeout = 1000; /// /// Current score. Used as highscore if game is over. /// public static int score = 0; /*unused /// /// Max. value for camera wobbel timeout. /// public const int MaxCameraWobbelTimeoutMs = 700; /*unused /// /// Camera wobbel timeout. /// Used to shake camera after colliding or nearly hitting asteroids. /// public static float cameraWobbelTimeoutMs = 0; /// /// Camera wobbel factor. /// public static float cameraWobbelFactor = 1.0f; /// /// Set camera wobbel /// /// Factor public static void SetCameraWobbel(float wobbelFactor) { cameraWobbelTimeoutMs = (int) //((0.75f + 0.5f * wobbelFactor) * (MaxCameraWobbelTimeoutMs); cameraWobbelFactor = wobbelFactor; } // SetCameraWobbel(wobbelFactor) */ /// /// Movement speed per second, used in SpaceCamera class. /// 500 means we will move up to 5 sectors a second, which is really fast. /// public const float MovementSpeedPerSecond = 88;//111;//1234;//500.0f;// 500.0f; /// /// Max values for x,y position (positive or negative) /// public const float MaxXPosition = 28.25f, MaxYPosition = 26.75f; /// /// Our current ship position. /// public static Vector2 position = new Vector2(0, -MaxYPosition); /// /// Ship rotation in x and y directions to make it look cooler. /// public static Vector2 shipRotation = new Vector2(0, 0); /// /// Ship position in 3d, updated each frame in Mission.RenderLandscapeObjects /// public static Vector3 shipPos = new Vector3(0, 0, 0); /// /// Shoot number, will be increased each time we shoot. /// public static int shootNum = 0; /// /// Remember the last time we shoot to allow instant shooting when clicking. /// private static float lastShootTimeMs = -500; #endregion #region Reset everything for starting a new game /// /// Keys for moving around. Assigned from settings! /// static Keys moveLeftKey, moveRightKey, moveUpKey, moveDownKey; /// /// Default to normal mouse sensibility, can be changed /// from 0.5 to 2.0. /// static float mouseSensibility = 1.0f; /// /// Reset all player entries for restarting a game. /// public static void Reset() { gameOver = false; alreadyUploadedHighscore = false; gameTimeMs = 0; health = 1.0f; score = 0; //unused: cameraWobbelTimeoutMs = 0; lastShootTimeMs = -500; // Assign keys. Warning: This is VERY slow, never use it // inside any render loop (getting Settings, etc.)! moveLeftKey = GameSettings.Default.MoveLeftKey; moveRightKey = GameSettings.Default.MoveRightKey; moveUpKey = GameSettings.Default.MoveForwardKey; moveDownKey = GameSettings.Default.MoveBackwardKey; // Also assign mouse sensibility mouseSensibility = 2.5f - 2.0f * GameSettings.Default.ControllerSensibility; if (mouseSensibility < 0.5f) mouseSensibility = 0.5f; } // Reset(setLevelName) #endregion #region Handle game logic /// /// Handle game logic /// public static void HandleGameLogic(Mission mission) { //tst: if (Input.KeyboardF1JustPressed) // gameOver = true; // Don't handle any more game logic if game is over. if (Player.GameOver) { if (victory) { // Display Victory message TextureFont.WriteTextCentered( BaseGame.Width / 2, BaseGame.Height / 3, "Victory! You won."); TextureFont.WriteTextCentered( BaseGame.Width / 2, BaseGame.Height / 3 + 40, "Your Highscore: " + Player.score + " (#" + Highscores.GetRankFromCurrentScore(Player.score) + ")"); } // if else { // Display game over message TextureFont.WriteTextCentered( BaseGame.Width / 2, BaseGame.Height / 3, "Game Over! You lost."); TextureFont.WriteTextCentered( BaseGame.Width / 2, BaseGame.Height / 3 + 40, "Your Highscore: " + Player.score + " (#" + Highscores.GetRankFromCurrentScore(Player.score) + ")"); } // else return; } // if // Increase game time gameTimeMs += BaseGame.ElapsedTimeThisFrameInMs; // Control our ship position with the keyboard or gamepad. // Use keyboard cursor keys and the left thumb stick. The // right hand is used for fireing (ctrl, space, a, b). Vector2 lastPosition = position; Vector2 lastRotation = shipRotation; float moveFactor = mouseSensibility * MovementSpeedPerSecond * BaseGame.MoveFactorPerSecond; // Left/Right if (Input.Keyboard.IsKeyDown(moveLeftKey) || Input.Keyboard.IsKeyDown(Keys.Left) || Input.Keyboard.IsKeyDown(Keys.NumPad4) || Input.GamePad.DPad.Left == ButtonState.Pressed) { position.X -= moveFactor; } // if if (Input.Keyboard.IsKeyDown(moveRightKey) || Input.Keyboard.IsKeyDown(Keys.Right) || Input.Keyboard.IsKeyDown(Keys.NumPad6) || Input.GamePad.DPad.Right == ButtonState.Pressed) { position.X += moveFactor; } // if if (Input.GamePad.ThumbSticks.Left.X != 0.0f) { position.X += Input.GamePad.ThumbSticks.Left.X;// *0.75f; } // if // Down/Up if (Input.Keyboard.IsKeyDown(moveDownKey) || Input.Keyboard.IsKeyDown(Keys.Down) || Input.Keyboard.IsKeyDown(Keys.NumPad2) || Input.GamePad.DPad.Down == ButtonState.Pressed) { position.Y -= moveFactor; } // if if (Input.Keyboard.IsKeyDown(moveUpKey) || Input.Keyboard.IsKeyDown(Keys.Up) || Input.Keyboard.IsKeyDown(Keys.NumPad8) || Input.GamePad.DPad.Up == ButtonState.Pressed) { position.Y += moveFactor; } // if if (Input.GamePad.ThumbSticks.Left.Y != 0.0f) { position.Y += Input.GamePad.ThumbSticks.Left.Y;// *0.75f; } // if // Keep position in bounds if (position.X < -MaxXPosition) position.X = -MaxXPosition; if (position.X > MaxXPosition) position.X = MaxXPosition; if (position.Y < -MaxYPosition) position.Y = -MaxYPosition; if (position.Y > MaxYPosition) position.Y = MaxYPosition; // Calculate ship rotation based on the current movement if (lastPosition.X > position.X) shipRotation.X = -0.5f; else if (lastPosition.X < position.X) shipRotation.X = +0.5f; else shipRotation.X = 0; if (lastPosition.Y > position.Y) shipRotation.Y = +0.53f; else if (lastPosition.Y < position.Y) shipRotation.Y = -0.33f; else shipRotation.Y = 0; shipRotation = lastRotation * 0.95f + shipRotation * 0.05f; // Fire? if (Input.GamePadAPressed || Input.GamePad.Triggers.Right > 0.5f || Input.Keyboard.IsKeyDown(Keys.LeftControl) || Input.Keyboard.IsKeyDown(Keys.RightControl)) { switch (currentWeapon) { case WeaponTypes.MG: if (gameTimeMs - lastShootTimeMs >= 150) { bool hitUnit = false; Vector3 enemyUnitPos = new Vector3(0, 100000, 0); // Hit enemy units, check all of them for (int num = 0; num < Mission.units.Count; num++) { Unit enemyUnit = Mission.units[num]; // Near enough to enemy ship? if (Math.Abs(enemyUnit.position.X - shipPos.X) < 5.0f && enemyUnit.position.Y > shipPos.Y && (enemyUnit.position.Y - shipPos.Y) < 60) { // Hit and do damage! if (enemyUnit.position.Y < enemyUnitPos.Y) enemyUnitPos = new Vector3(enemyUnit.position, Mission.AllShipsZHeight); hitUnit = true; Player.score += (int)enemyUnit.hitpoints / 10; enemyUnit.hitpoints -= 150; // do about 1000 damage/sec } // if } // for Vector3 shootPos = shipPos + new Vector3(-1.2f, 0, 0); EffectManager.AddMgEffect(shootPos, hitUnit ? enemyUnitPos : shootPos + new Vector3(0, 100, 0), 0, 2, hitUnit, true);//shootNum % 2 == 0); shootPos = shipPos + new Vector3(+1.2f, 0, 0); EffectManager.AddMgEffect(shootPos, hitUnit ? enemyUnitPos : shootPos + new Vector3(0, 100, 0), 1, 3, hitUnit, false); shootNum++; lastShootTimeMs = gameTimeMs; Input.GamePadRumble(0.015f, 0.125f); Player.score += 1; } // if else { Vector3 shootPos = shipPos + new Vector3(-1.2f, 0, 0); EffectManager.UpdateMgEffect(shootPos, 0); shootPos = shipPos + new Vector3(+1.2f, 0, 0); EffectManager.UpdateMgEffect(shootPos, 1); } // else break; case WeaponTypes.Plasma: if (gameTimeMs - lastShootTimeMs >= 250) { Vector3 shootPos = shipPos + new Vector3(shootNum % 2 == 0 ? -2.4f : +2.4f, 0, 0); Mission.AddWeaponProjectile( Projectile.WeaponTypes.Plasma, shootPos, true); EffectManager.AddFireFlash(shootPos); EffectManager.PlaySoundEffect( EffectManager.EffectSoundType.PlasmaShoot); shootNum++; lastShootTimeMs = gameTimeMs; Input.GamePadRumble(0.05f, 0.175f); Player.score += 5; } // if break; case WeaponTypes.Gattling: if (gameTimeMs - lastShootTimeMs >= 100) { bool hitUnit = false; Vector3 enemyUnitPos = new Vector3(0, 100000, 0); // Hit enemy units, check all of them for (int num = 0; num < Mission.units.Count; num++) { Unit enemyUnit = Mission.units[num]; // Near enough to enemy ship? if (Math.Abs(enemyUnit.position.X - shipPos.X) < 5.0f && enemyUnit.position.Y > shipPos.Y && (enemyUnit.position.Y - shipPos.Y) < 60) { // Hit and do damage! if (enemyUnit.position.Y < enemyUnitPos.Y) enemyUnitPos = new Vector3(enemyUnit.position, Mission.AllShipsZHeight); hitUnit = true; Player.score += (int)enemyUnit.hitpoints / 10; enemyUnit.hitpoints -= 175; // do about 1750 damage/sec } // if } // for Vector3 shootPos = shipPos + new Vector3(-1.2f, 0, 0); EffectManager.AddGattlingEffect(shootPos, hitUnit ? enemyUnitPos : shootPos + new Vector3(0, 100, 0), 0, 2, hitUnit, shootNum % 2 == 0); shootPos = shipPos + new Vector3(+1.2f, 0, 0); EffectManager.AddGattlingEffect(shootPos, hitUnit ? enemyUnitPos : shootPos + new Vector3(0, 100, 0), 1, 3, hitUnit, false); if (RandomHelper.GetRandomInt(2) == 0) { shootPos = shipPos + new Vector3(-2.54f, 0, 0); EffectManager.AddGattlingEffect(shootPos, hitUnit ? enemyUnitPos : shootPos + new Vector3(0, 100, 0), 4, 2, hitUnit, false); shootPos = shipPos + new Vector3(+2.54f, 0, 0); EffectManager.AddGattlingEffect(shootPos, hitUnit ? enemyUnitPos : shootPos + new Vector3(0, 100, 0), 5, 2, hitUnit, false); } // if shootNum++; lastShootTimeMs = gameTimeMs; Input.GamePadRumble(0.05f, 0.225f); Player.score += 1; } // if break; case WeaponTypes.Rockets: if (gameTimeMs - lastShootTimeMs >= 500) { Vector3 shootPos = shipPos + new Vector3(shootNum % 2 == 0 ? -2.64f : +2.64f, 0, 0); Mission.AddWeaponProjectile( Projectile.WeaponTypes.Rocket, shootPos, true); EffectManager.AddFireFlash(shootPos); EffectManager.PlaySoundEffect( EffectManager.EffectSoundType.RocketShoot); shootNum++; lastShootTimeMs = gameTimeMs; Input.GamePadRumble(0.10f, 0.15f); Player.score += 10; } // if break; } // switch } // if // Fire EMP? if (empBombs > 0 && empBombTimeout <= 0 && (Input.GamePadBJustPressed || Input.KeyboardSpaceJustPressed)) { empBombs--; empBombTimeout = MaxEmpTimeout; empPosition = shipPos + new Vector3(0, 10, 0); // Give some extra points to player Player.score += 1000; // Big badda boom //tst: EffectManager.AddExplosion(empPosition, 10); for (int num=0; num<5; num++) EffectManager.AddEffect(shipPos+ new Vector3(0, 5, 0), EffectManager.EffectType.ExplosionRing, 2+2.5f*num, 0); Sound.Play(Sound.Sounds.EMP); } // if if (empBombTimeout > 0) { empBombTimeout -= BaseGame.ElapsedTimeThisFrameInMs; if (empBombTimeout <= 0) empBombTimeout = 0; // EMP Distance float distance = 64 * (MaxEmpTimeout - empBombTimeout) / MaxEmpTimeout; // Show effect BaseGame.DrawLine( empPosition +new Vector3(-100, distance, 0), empPosition +new Vector3(+100, distance, 0)); BaseGame.DrawLine( empPosition +new Vector3(-100, -distance, 0), empPosition +new Vector3(+100, -distance, 0)); BaseGame.DrawLine( empPosition +new Vector3(distance, -100, 0), empPosition +new Vector3(distance, +100, 0)); BaseGame.DrawLine( empPosition +new Vector3(-distance, -100, 0), empPosition +new Vector3(-distance, +100, 0)); // Kill all units on screen that are in range! for (int num = 0; num < Mission.units.Count; num++) { // Only include units on the screen and don't kill asteroids. // Projectiles and effects stay active too. if ((Mission.units[num].position - new Vector2(empPosition.X, empPosition.Y)).Length() < distance + 10)// && //Mission.units[num].position.Y - Mission.LookAtPosition.Y < 15 && //looks cooler with: Mission.units[num].unitType != Unit.UnitTypes.Asteroid) { Player.score += (int)Mission.units[num].hitpoints / 10; Mission.units[num].hitpoints = 0; } // if } // for } // if (emp bomb active) if (Player.health <= 0) { victory = false; EffectManager.AddExplosion(shipPos, 20); for (int num = 0; num<8; num++) EffectManager.AddFlameExplosion(shipPos+ RandomHelper.GetRandomVector3(-12, +12), false); Sound.PlayDefeatSound(); Player.SetGameOverAndUploadHighscore(); } // if } // HandleGameLogic(asteroidManager) #endregion } // class Player } // namespace XnaShooter