415 lines
11 KiB
C#
415 lines
11 KiB
C#
using AlienAttack.MonoGame.Things.Bullets;
|
|
using AlienAttack.MonoGame.Things.Enemies;
|
|
using AlienAttack.MonoGame.Things.Items;
|
|
using AlienAttack.MonoGame.Things.Muzzles;
|
|
using AlienAttack.MonoGame.Things.Weapons;
|
|
using Microsoft.Xna.Framework;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
using Microsoft.Xna.Framework.Input;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace AlienAttack.MonoGame.Things;
|
|
|
|
public enum PlayerHorizontalMoveState
|
|
{
|
|
None,
|
|
Left,
|
|
Right
|
|
}
|
|
|
|
[Flags]
|
|
public enum MoveFlag
|
|
{
|
|
None = 0,
|
|
Left = 1,
|
|
Right = 2,
|
|
Up = 4,
|
|
Down = 8,
|
|
Boost = 16
|
|
}
|
|
|
|
public class DrwaState
|
|
{
|
|
|
|
}
|
|
|
|
public class Player : MoveableSprite
|
|
{
|
|
protected PlayerHorizontalMoveState MoveState = PlayerHorizontalMoveState.None;
|
|
protected MoveFlag MoveFlags;
|
|
protected ulong MoveThreshold = 0;
|
|
protected ICollection<IWeapon> 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 IReadOnlyList<Muzzle> Muzzles { get; } =
|
|
[
|
|
new Muzzle(MuzzleId.Center, new Vector2(31.5f, 1f)),
|
|
new Muzzle(MuzzleId.Left, new Vector2(15f, 27f)),
|
|
new Muzzle(MuzzleId.Right, new Vector2(47f, 27f)),
|
|
];
|
|
|
|
public Player(int x, int y) : base(x, y)
|
|
{
|
|
BoundBox = new Rectangle(0, 0, 64, 64);
|
|
//ActiveWeapons.Add(new Minigun());
|
|
//ActiveWeapons.Add(new MinigunTripleSpreadFast());
|
|
//ActiveWeapons.Add(new MinigunSpread());
|
|
Health = 100;
|
|
Shield = 100;
|
|
|
|
// Weapon 1
|
|
WeaponDef weaponDef = new()
|
|
{
|
|
Name = "Weapon 1",
|
|
Bullet = BulletDefinitions.ProtonLarge,
|
|
Pattern = ShotPatterns.TripleSpread,
|
|
FireSfxKey = ""
|
|
};
|
|
|
|
WeaponState weasponState = new()
|
|
{
|
|
FireThreshold = 15,
|
|
SpeedMultiplier = 1f,
|
|
DamageBonus = 0
|
|
};
|
|
|
|
ConfigurableWeapon configurableWeapon = new(weaponDef, weasponState);
|
|
|
|
// Weapon 2
|
|
//WeaponDef weaponDef2 = new()
|
|
//{
|
|
// Name = "Weapon 2",
|
|
// Bullet = BulletDefinitions.MinigunSmall,
|
|
// Pattern = ShotPatterns.Single,
|
|
// FireSfxKey = ""
|
|
//};
|
|
|
|
//WeaponState weasponState2 = new()
|
|
//{
|
|
// FireThreshold = 20,
|
|
// SpeedMultiplier = 2f,
|
|
// DamageBonus = 0
|
|
//};
|
|
|
|
//ConfigurableWeapon configurableWeapon2 = new(weaponDef2, weasponState2);
|
|
|
|
ActiveWeapons.Add(configurableWeapon);
|
|
//ActiveWeapons.Add(configurableWeapon2);
|
|
}
|
|
|
|
public Vector2 GetMuzzleLocal(MuzzleId muzzle)
|
|
{
|
|
switch (muzzle)
|
|
{
|
|
case MuzzleId.Center:
|
|
return Muzzles[0].LocalPx;
|
|
case MuzzleId.Left:
|
|
return Muzzles[1].LocalPx;
|
|
case MuzzleId.Right:
|
|
return Muzzles[2].LocalPx;
|
|
}
|
|
|
|
return new();
|
|
}
|
|
|
|
//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<Texture2D>(@$"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<Texture2D>(@$"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<SoundEffect>(@$"Sfx\Shield\SCIEnrg_Shield Activate_0{number}_SFRMS_SCIWPNS");
|
|
//soundEffect.Play(0.85f, (float)(context.Random.NextDouble() * 0.1 - 0.05), 0);
|
|
|
|
//context.AudioManager.PlayPickup(PickupKind.Shield);
|
|
|
|
GiveShield(20);
|
|
}
|
|
|
|
if (context.Sprite is Health)
|
|
{
|
|
GiveHealth(10);
|
|
}
|
|
}
|
|
} |