using AlienAttack.MonoGame.Things.Bullets; using AlienAttack.MonoGame.Things.Enemies; using AlienAttack.MonoGame.Things.Items; using AlienAttack.MonoGame.Things.Weapons; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Audio; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using System; using System.Collections.Generic; using System.IO; using static System.Net.Mime.MediaTypeNames; namespace AlienAttack.MonoGame.Things; internal enum PlayerHorizontalMoveState { None, Left, Right } [Flags] internal enum MoveFlag { None = 0, Left = 1, Right = 2, Up = 4, Down = 8, Boost = 16 } public class DrwaState { } internal class Player : MoveableSprite { protected PlayerHorizontalMoveState MoveState = PlayerHorizontalMoveState.None; protected MoveFlag MoveFlags; protected ulong MoveThreshold = 0; protected ICollection ActiveWeapons = []; protected int CurrentExhaustFrame = 1; protected int MaxExhaustFrames = 6; protected int ExhaustAnimationThreshold = 30; protected int CurrentExhaustAnimationThreshold = 10; protected int CurrentExhaustDirection = 1; public int Health { get; protected set; } public int Shield { get; protected set; } public Player(int x, int y) : base(x, y) { BoundBox = new Rectangle(0, 0, 64, 64); ActiveWeapons.Add(new Minigun()); //ActiveWeapons.Add(new FastMinigun()); Health = 100; Shield = 100; } //Texture2D texture = Game public override void Draw(SpriteDrawArgs args) { //DrawExhaust(args); string frameNumber = MoveState == PlayerHorizontalMoveState.None ? "01" : MoveThreshold < 30 ? "02" : "03"; SpriteEffects spriteEffects = MoveState == PlayerHorizontalMoveState.Right ? SpriteEffects.FlipHorizontally : SpriteEffects.None; Texture2D texture = args.Content.Load(@$"Sprites\PlayerRed_Frame_{frameNumber}"); //args.SpriteBatch.Draw(texture, Position, DrawColor); args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, new Vector2(0, 0), 1, spriteEffects, 1); } private void DrawExhaust(SpriteDrawArgs args) { Texture2D texture = args.Content.Load(@$"Sprites\Exhaust_Frame_0{CurrentExhaustFrame}_png_processed"); args.SpriteBatch.Draw(texture, Position, null, DrawColor, 0, new Vector2(0, 0), 1, SpriteEffects.None, 1); } private string GetPlayerTextureName() { switch (MoveState) { case PlayerHorizontalMoveState.Left: return "PlayerRed_Frame_02"; case PlayerHorizontalMoveState.Right: return "PlayerRed_Frame_03"; case PlayerHorizontalMoveState.None: default: return "PlayerRed_Frame_01"; } } public override void Update(SpriteUpdateContext context) { base.Update(context); //UpdateExhaustAnimationThreshold(); CheckMove(context); CheckFire(context); //base.Update(context); } private void UpdateExhaustAnimationThreshold() { if (CurrentExhaustAnimationThreshold > 0) { CurrentExhaustAnimationThreshold--; } else { if (CurrentExhaustFrame == MaxExhaustFrames) { CurrentExhaustDirection = -1; } else if (CurrentExhaustFrame == 1) { CurrentExhaustDirection = 1; } CurrentExhaustFrame += CurrentExhaustDirection; CurrentExhaustAnimationThreshold = ExhaustAnimationThreshold; } } private void CheckMove(SpriteUpdateContext context) { UpdateMoveFlag(); if (MoveFlags.HasFlag(MoveFlag.Up)) { //YPosition -= 4; YVelocity = -4; } else if (MoveFlags.HasFlag(MoveFlag.Down)) { //YPosition += 4; YVelocity = 4; } else { YVelocity = 0; } if (MoveFlags.HasFlag(MoveFlag.Left)) { //XPosition -= 4; XVelocity = -4; if (MoveState != PlayerHorizontalMoveState.Left) { MoveThreshold = 0; } else { MoveThreshold++; if (MoveThreshold > 30) { MoveThreshold = 30; } } MoveState = PlayerHorizontalMoveState.Left; } else if (MoveFlags.HasFlag(MoveFlag.Right)) { //XPosition += 4; XVelocity = 4; if (MoveState != PlayerHorizontalMoveState.Right) { MoveThreshold = 0; } else { MoveThreshold++; if (MoveThreshold > 30) { MoveThreshold = 30; } } MoveState = PlayerHorizontalMoveState.Right; } else { XVelocity = 0; MoveState = PlayerHorizontalMoveState.None; MoveThreshold = 0; } if (MoveFlags.HasFlag(MoveFlag.Boost)) { XVelocity *= 1.5f; } if (XPosition < 0) { XPosition = 0; } if (XPosition + BoundBox.Width > context.ViewTransform.ScreenWidth) { XPosition = context.ViewTransform.ScreenWidth - BoundBox.Width; } if (YPosition < 0) { YPosition = 0; } if (YPosition + BoundBox.Height > context.ViewTransform.ScreenHeight) { YPosition = context.ViewTransform.ScreenHeight - BoundBox.Height; } } private void UpdateMoveFlag() { MoveFlags = MoveFlag.None; KeyboardState keyState = Keyboard.GetState(); GamePadState gamepadState = GamePad.GetState(0); if (keyState.IsKeyDown(Keys.Up) || keyState.IsKeyDown(Keys.W) || gamepadState.ThumbSticks.Left.Y > 0) { MoveFlags |= MoveFlag.Up; } else if (keyState.IsKeyDown(Keys.Down) || keyState.IsKeyDown(Keys.S) || gamepadState.ThumbSticks.Left.Y < 0) { MoveFlags |= MoveFlag.Down; } if (keyState.IsKeyDown(Keys.Left) || keyState.IsKeyDown(Keys.A) || gamepadState.ThumbSticks.Left.X < 0) { MoveFlags |= MoveFlag.Left; } else if (keyState.IsKeyDown(Keys.Right) || keyState.IsKeyDown(Keys.D) || gamepadState.ThumbSticks.Left.X > 0) { MoveFlags |= MoveFlag.Right; } if (gamepadState.Buttons.RightShoulder == ButtonState.Pressed) { MoveFlags |= MoveFlag.Boost; } } private void CheckFire(SpriteUpdateContext context) { foreach (IWeapon weapon in ActiveWeapons) { weapon.UpdateFireThreshold(); } if (IsFireButtonPressed() == false) return; foreach (IWeapon weapon in ActiveWeapons) { weapon.TryFire(this, context); } } private static bool IsFireButtonPressed() { KeyboardState keyState = Keyboard.GetState(); MouseState mouseState = Mouse.GetState(); GamePadState gamePadState = GamePad.GetState(0); return keyState.IsKeyDown(Keys.Space) || mouseState.LeftButton == ButtonState.Pressed || gamePadState.Buttons.A == ButtonState.Pressed; } private void TakeDamage(int amount) { if (Shield >= amount) { TakeShieldDamage(amount); return; } if (Shield > 0) { int remainder = amount - Shield; TakeShieldDamage(Shield); TakeHealthDamage(remainder); return; } TakeHealthDamage(amount); } private void GiveShield(int amount) { Shield = Math.Clamp(Shield + amount, 0, 100); } private void TakeShieldDamage(int amount) { Shield = Math.Clamp(Shield - amount, 0, 100); } private void GiveHealth(int amount) { Health = Math.Clamp(Health + amount, 0, 100); } private void TakeHealthDamage(int amount) { Health = Math.Clamp(Health - amount, 0, 100); } public override void OnCollision(SpriteCollisionContext context) { if (context.Sprite is Bullet bullet && bullet.Owner is not Player) { TakeDamage(bullet.Damage); } if (context.Sprite is EnemyShip enemyShip) { TakeDamage(enemyShip.CrashDamage); } if (context.Sprite is Shields) { //SCIEnrg_Shield Activate_01_SFRMS_SCIWPNS int number = context.Random.Next(1, 6); SoundEffect soundEffect = context.Content.Load(@$"Sfx\Shield\SCIEnrg_Shield Activate_0{number}_SFRMS_SCIWPNS"); soundEffect.Play(0.85f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0); GiveShield(20); } if (context.Sprite is Health) { GiveHealth(10); } } }