Files
LunaLightXMG/.history/Player_20250305121906.cs
T
2025-03-05 12:38:51 -08:00

194 lines
6.8 KiB
C#

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace LunaLightXMG
{
public class Player
{
private float hsp; // Horizontal speed
public float vsp; // Vertical speed
private float hsp_frac; // Hold fractional position data
private float vsp_frac; // Hold fractional position data
private float wallJumpDelay; // Delay for wall jumping
public bool grounded; // Is the player grounded?
public bool walled; // Is the player wall sliding?
private bool wasWalled; // Remember is the player was on a wall or ground.
private float hspAcc; // Horizontal acceleration
private float hspFrictionGround; // Ground friction
private float hspFrictionAir; // Air friction
private float hspWalk; // Maximum horizontal speed
private float grv; // Gravity
private float vspMax; // Maximum vertical speed
private float grvWall; // Gravity when wall sliding
private float vspMaxWall; // Maximum vertical speed when wall sliding
private float vspJump; // Jump speed
private Texture2D texture;
public Vector2 position;
public BoundingBox boundingBox { get; private set; }
private CollisionManager collisionManager;
public Player(Vector2 initPosition)
{
hsp = 0;
vsp = 0;
hsp_frac = 0;
vsp_frac = 0;
wallJumpDelay = 0;
grounded = false;
walled = false;
wasWalled = false;
hspAcc = 0.2f;
hspFrictionGround = 0.3f;
hspFrictionAir = 0.3f;
hspWalk = 3f;
grv = 0.2f;
vspMax = 10f;
grvWall = 0.1f;
vspMaxWall = 5f;
vspJump = -4f;
position = initPosition;
boundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 16));
collisionManager = new CollisionManager();
}
public void LoadContent(ContentManager content)
{
texture = content.Load<Texture2D>("player");
}
public void Update(GameTime gameTime, PlayerInput input, Platform[] platforms)
{
Movement(input);
boundingBox.Update(position, boundingBox.Bounds.Width, boundingBox.Bounds.Height);
DumpFractions();
CollisionChecks(platforms);
}
public void Draw(SpriteBatch spriteBatch)
{
// Snap position to integer values
Vector2 drawPosition = new Vector2((int)position.X, (int)position.Y);
spriteBatch.Draw(texture, drawPosition, Color.White);
}
// Method Implementation -------------------------------------------------------------------------------
public void Reset(Vector2 initialPosition)
{
position = initialPosition;
// Reset other player-specific states later
}
private void Movement(PlayerInput input)
{
if (input.KeyJump && grounded)
{
vsp = vspJump;
}
// Horizontal movement with acceleration + wall jump delay
wallJumpDelay = Math.Max(wallJumpDelay - 1, 0); // counts down every frame
if (wallJumpDelay == 0) // no left-right control until delay is 0, prevents rapid wall climb
{
float moveH = input.KeyRight - input.KeyLeft;
hsp += moveH * hspAcc;
if (moveH == 0)
{
float hspFrictionFinal = grounded ? hspFrictionGround : hspFrictionAir;
hsp = Approach(hsp, 0, hspFrictionFinal);
}
hsp = MathHelper.Clamp(hsp, -hspWalk, hspWalk);
}
// Calculate vertical movement
float grvFinal = grv;
float vspMaxFinal = vspMax;
if (walled && vsp > 0)
{
grvFinal = grvWall;
vspMaxFinal = vspMaxWall;
}
vsp += vsp == 0 ? grvFinal * 2 : grvFinal;
vsp = MathHelper.Clamp(vsp, vspJump, vspMaxFinal);
}
private void CollisionChecks(Platform[] platforms)
{
// Horizontal collision prediction
float onePixh = Math.Sign(hsp);
if (CollisionManager.IsColliding(position + new Vector2(hsp, 0), boundingBox, platforms))
{
while (!CollisionManager.IsColliding(position + new Vector2(onePixh, 0), boundingBox, platforms))
{
position.X += onePixh;
}
hsp = 0;
}
position.X += hsp; // Horizontal move
// Vertical collision prediction
float onePixv = Math.Sign(vsp);
if (CollisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms))
{
while (!CollisionManager.IsColliding(position + new Vector2(0, onePixv), boundingBox, platforms))
{
position.Y += onePixv;
}
vsp = 0;
}
position.Y += vsp; // Vertical move
// Grounded?
grounded = CollisionManager.IsColliding(position + new Vector2(0, 1), boundingBox, platforms);
// Walled?
walled = CollisionManager.WallCheck(position, boundingBox, platforms);
if (walled)
wasWalled = walled;
}
private float Approach(float start, float end, float shift)
{
if (start < end)
{
start += shift;
if (start > end)
return end;
}
else
{
start -= shift;
if (start < end)
return end;
}
return start;
}
private void DumpFractions()
{
if (grounded)
{
float adjustedPosX = (float)Math.Round(position.X);
float adjustedPosY = (float)Math.Round(position.Y);
position.X = adjustedPosX;
position.Y = adjustedPosY;
}
if (vsp >= 0)
{
hsp += hsp_frac;
vsp += vsp_frac;
hsp_frac = hsp - (float)Math.Floor(hsp);
vsp_frac = vsp - (float)Math.Floor(vsp);
hsp -= hsp_frac;
vsp -= vsp_frac;
}
}
}
}