From b270b8189b71104ba0933d5b1856dfe1cf4a14c3 Mon Sep 17 00:00:00 2001 From: jme9 Date: Wed, 5 Mar 2025 12:38:51 -0800 Subject: [PATCH] Ultra minor updates. --- .history/CollisionManager_20241226144533.cs | 45 +++++ .history/CollisionManager_20250305121859.cs | 45 +++++ .history/CollisionManager_20250305121906.cs | 45 +++++ .history/CollisionManager_20250305121909.cs | 45 +++++ .history/Enemy_20241226144533.cs | 151 +++++++++++++++ .history/Enemy_20250305121859.cs | 151 +++++++++++++++ .history/Enemy_20250305121906.cs | 151 +++++++++++++++ .history/Player_20241226144533.cs | 193 ++++++++++++++++++++ .history/Player_20250305121709.cs | 193 ++++++++++++++++++++ .history/Player_20250305121859.cs | 193 ++++++++++++++++++++ .history/Player_20250305121906.cs | 193 ++++++++++++++++++++ CollisionManager.cs | 6 +- Enemy.cs | 12 +- Player.cs | 14 +- 14 files changed, 1421 insertions(+), 16 deletions(-) create mode 100644 .history/CollisionManager_20241226144533.cs create mode 100644 .history/CollisionManager_20250305121859.cs create mode 100644 .history/CollisionManager_20250305121906.cs create mode 100644 .history/CollisionManager_20250305121909.cs create mode 100644 .history/Enemy_20241226144533.cs create mode 100644 .history/Enemy_20250305121859.cs create mode 100644 .history/Enemy_20250305121906.cs create mode 100644 .history/Player_20241226144533.cs create mode 100644 .history/Player_20250305121709.cs create mode 100644 .history/Player_20250305121859.cs create mode 100644 .history/Player_20250305121906.cs diff --git a/.history/CollisionManager_20241226144533.cs b/.history/CollisionManager_20241226144533.cs new file mode 100644 index 0000000..a337b72 --- /dev/null +++ b/.history/CollisionManager_20241226144533.cs @@ -0,0 +1,45 @@ +using Microsoft.Xna.Framework; + +namespace LunaLightXMG +{ + public class CollisionManager + { + // Method to check if a position is colliding with any platform + public bool IsColliding(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return true; + } + } + return false; + } + + // Method to check if a position is colliding with any platform and return the colliding platform + public Platform GetCollidingPlatform(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return platform; + } + } + return null; + } + + // Method to check if a position is colliding with any wall + public bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platforms) + { + if (IsColliding(position + new Vector2(1, 0), boundingBox, platforms) || IsColliding(position + new Vector2(-1, 0), boundingBox, platforms)) + { + return true; + } + return false; + } + } +} diff --git a/.history/CollisionManager_20250305121859.cs b/.history/CollisionManager_20250305121859.cs new file mode 100644 index 0000000..2b7f218 --- /dev/null +++ b/.history/CollisionManager_20250305121859.cs @@ -0,0 +1,45 @@ +using Microsoft.Xna.Framework; + +namespace LunaLightXMG +{ + public class CollisionManager + { + // Method to check if a position is colliding with any platform + public static bool IsColliding(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return true; + } + } + return false; + } + + // Method to check if a position is colliding with any platform and return the colliding platform + public static Platform GetCollidingPlatform(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return platform; + } + } + return null; + } + + // Method to check if a position is colliding with any wall + public bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platforms) + { + if (IsColliding(position + new Vector2(1, 0), boundingBox, platforms) || IsColliding(position + new Vector2(-1, 0), boundingBox, platforms)) + { + return true; + } + return false; + } + } +} diff --git a/.history/CollisionManager_20250305121906.cs b/.history/CollisionManager_20250305121906.cs new file mode 100644 index 0000000..820fc57 --- /dev/null +++ b/.history/CollisionManager_20250305121906.cs @@ -0,0 +1,45 @@ +using Microsoft.Xna.Framework; + +namespace LunaLightXMG +{ + public class CollisionManager + { + // Method to check if a position is colliding with any platform + public static bool IsColliding(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return true; + } + } + return false; + } + + // Method to check if a position is colliding with any platform and return the colliding platform + public static Platform GetCollidingPlatform(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return platform; + } + } + return null; + } + + // Method to check if a position is colliding with any wall + public static bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platforms) + { + if (IsColliding(position + new Vector2(1, 0), boundingBox, platforms) || IsColliding(position + new Vector2(-1, 0), boundingBox, platforms)) + { + return true; + } + return false; + } + } +} diff --git a/.history/CollisionManager_20250305121909.cs b/.history/CollisionManager_20250305121909.cs new file mode 100644 index 0000000..820fc57 --- /dev/null +++ b/.history/CollisionManager_20250305121909.cs @@ -0,0 +1,45 @@ +using Microsoft.Xna.Framework; + +namespace LunaLightXMG +{ + public class CollisionManager + { + // Method to check if a position is colliding with any platform + public static bool IsColliding(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return true; + } + } + return false; + } + + // Method to check if a position is colliding with any platform and return the colliding platform + public static Platform GetCollidingPlatform(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + { + Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + foreach (var platform in platforms) + { + if (newBounds.Intersects(platform.BoundingBox.Bounds)) + { + return platform; + } + } + return null; + } + + // Method to check if a position is colliding with any wall + public static bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platforms) + { + if (IsColliding(position + new Vector2(1, 0), boundingBox, platforms) || IsColliding(position + new Vector2(-1, 0), boundingBox, platforms)) + { + return true; + } + return false; + } + } +} diff --git a/.history/Enemy_20241226144533.cs b/.history/Enemy_20241226144533.cs new file mode 100644 index 0000000..64e91e8 --- /dev/null +++ b/.history/Enemy_20241226144533.cs @@ -0,0 +1,151 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using System; + +namespace LunaLightXMG +{ + public class Enemy + { + private float hsp; // Horizontal speed + private float hspPrev; + private float vsp; // Vertical speed + private float hsp_frac; // Horizontal fractional speed + private float vsp_frac; // Vertical fractional speed + private float vspJump; + private bool grounded; + private bool walled; + private float grv; + private Texture2D texture; + public Vector2 position; + public BoundingBox boundingBox { get; private set; } + private CollisionManager collisionManager; + private static Random random; + + public Enemy(Vector2 initPosition, float initHsp) + { + hsp = initHsp; + vsp = 0; + hsp_frac = 0; + vsp_frac = 0; + vspJump = -4f; + grounded = false; + walled = false; + grv = 0.2f; + position = initPosition; + boundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 8)); + collisionManager = new CollisionManager(); + random = new Random(42); + } + + public void LoadContent(ContentManager content) + { + texture = content.Load("enemy"); + } + + public void Update(GameTime gameTime, Player player, Platform[] platforms) + { + Movement(); + boundingBox.Update(position, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + DumpFractions(); + CollisionChecks(platforms, player); + } + + public void Draw(SpriteBatch spriteBatch) + { + if (hsp <= 1 && hsp >= -1) + { + spriteBatch.Draw(texture, position, Color.White); + } + else + { + spriteBatch.Draw(texture, position, Color.Red); + } + } + + // Method Implementation ------------------------------------------------------------------------------- + private void Movement() + { + if (hsp == 0) { hsp = hspPrev; } + if (walled) { hsp = -hsp; } + if (!grounded) { vsp += grv; } + if (RandomJump() && grounded) { vsp = vspJump; } + } + + private void CollisionChecks(Platform[] platforms, Player player) + { + // Remember hsp + hspPrev = hsp; + // 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); + + // Check for collision with player + if (boundingBox.Intersects(player.boundingBox) && player.vsp > 0) + { + // Player jumps on top of the enemy, enemy dies + Die(); + } + } + + // Enemy dies + private void Die() + { + // Logic for enemy death (e.g., remove from game, play animation, etc.) + // Here we just move the enemy off-screen as a simple example + position = new Vector2(-100, -100); + } + + 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; + } + } + public static bool RandomJump() + { + return (1 + 2 * random.NextDouble() > 2) ? true : false; + } + } +} + diff --git a/.history/Enemy_20250305121859.cs b/.history/Enemy_20250305121859.cs new file mode 100644 index 0000000..3137db3 --- /dev/null +++ b/.history/Enemy_20250305121859.cs @@ -0,0 +1,151 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using System; + +namespace LunaLightXMG +{ + public class Enemy + { + private float hsp; // Horizontal speed + private float hspPrev; + private float vsp; // Vertical speed + private float hsp_frac; // Horizontal fractional speed + private float vsp_frac; // Vertical fractional speed + private float vspJump; + private bool grounded; + private bool walled; + private float grv; + private Texture2D texture; + public Vector2 position; + public BoundingBox boundingBox { get; private set; } + private CollisionManager collisionManager; + private static Random random; + + public Enemy(Vector2 initPosition, float initHsp) + { + hsp = initHsp; + vsp = 0; + hsp_frac = 0; + vsp_frac = 0; + vspJump = -4f; + grounded = false; + walled = false; + grv = 0.2f; + position = initPosition; + boundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 8)); + collisionManager = new CollisionManager(); + random = new Random(42); + } + + public void LoadContent(ContentManager content) + { + texture = content.Load("enemy"); + } + + public void Update(GameTime gameTime, Player player, Platform[] platforms) + { + Movement(); + boundingBox.Update(position, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + DumpFractions(); + CollisionChecks(platforms, player); + } + + public void Draw(SpriteBatch spriteBatch) + { + if (hsp <= 1 && hsp >= -1) + { + spriteBatch.Draw(texture, position, Color.White); + } + else + { + spriteBatch.Draw(texture, position, Color.Red); + } + } + + // Method Implementation ------------------------------------------------------------------------------- + private void Movement() + { + if (hsp == 0) { hsp = hspPrev; } + if (walled) { hsp = -hsp; } + if (!grounded) { vsp += grv; } + if (RandomJump() && grounded) { vsp = vspJump; } + } + + private void CollisionChecks(Platform[] platforms, Player player) + { + // Remember hsp + hspPrev = hsp; + // 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); + + // Check for collision with player + if (boundingBox.Intersects(player.boundingBox) && player.vsp > 0) + { + // Player jumps on top of the enemy, enemy dies + Die(); + } + } + + // Enemy dies + private void Die() + { + // Logic for enemy death (e.g., remove from game, play animation, etc.) + // Here we just move the enemy off-screen as a simple example + position = new Vector2(-100, -100); + } + + 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; + } + } + public static bool RandomJump() + { + return (1 + 2 * random.NextDouble() > 2) ? true : false; + } + } +} + diff --git a/.history/Enemy_20250305121906.cs b/.history/Enemy_20250305121906.cs new file mode 100644 index 0000000..92f9169 --- /dev/null +++ b/.history/Enemy_20250305121906.cs @@ -0,0 +1,151 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Content; +using Microsoft.Xna.Framework.Graphics; +using System; + +namespace LunaLightXMG +{ + public class Enemy + { + private float hsp; // Horizontal speed + private float hspPrev; + private float vsp; // Vertical speed + private float hsp_frac; // Horizontal fractional speed + private float vsp_frac; // Vertical fractional speed + private float vspJump; + private bool grounded; + private bool walled; + private float grv; + private Texture2D texture; + public Vector2 position; + public BoundingBox boundingBox { get; private set; } + private CollisionManager collisionManager; + private static Random random; + + public Enemy(Vector2 initPosition, float initHsp) + { + hsp = initHsp; + vsp = 0; + hsp_frac = 0; + vsp_frac = 0; + vspJump = -4f; + grounded = false; + walled = false; + grv = 0.2f; + position = initPosition; + boundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 8)); + collisionManager = new CollisionManager(); + random = new Random(42); + } + + public void LoadContent(ContentManager content) + { + texture = content.Load("enemy"); + } + + public void Update(GameTime gameTime, Player player, Platform[] platforms) + { + Movement(); + boundingBox.Update(position, boundingBox.Bounds.Width, boundingBox.Bounds.Height); + DumpFractions(); + CollisionChecks(platforms, player); + } + + public void Draw(SpriteBatch spriteBatch) + { + if (hsp <= 1 && hsp >= -1) + { + spriteBatch.Draw(texture, position, Color.White); + } + else + { + spriteBatch.Draw(texture, position, Color.Red); + } + } + + // Method Implementation ------------------------------------------------------------------------------- + private void Movement() + { + if (hsp == 0) { hsp = hspPrev; } + if (walled) { hsp = -hsp; } + if (!grounded) { vsp += grv; } + if (RandomJump() && grounded) { vsp = vspJump; } + } + + private void CollisionChecks(Platform[] platforms, Player player) + { + // Remember hsp + hspPrev = hsp; + // 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); + + // Check for collision with player + if (boundingBox.Intersects(player.boundingBox) && player.vsp > 0) + { + // Player jumps on top of the enemy, enemy dies + Die(); + } + } + + // Enemy dies + private void Die() + { + // Logic for enemy death (e.g., remove from game, play animation, etc.) + // Here we just move the enemy off-screen as a simple example + position = new Vector2(-100, -100); + } + + 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; + } + } + public static bool RandomJump() + { + return (1 + 2 * random.NextDouble() > 2) ? true : false; + } + } +} + diff --git a/.history/Player_20241226144533.cs b/.history/Player_20241226144533.cs new file mode 100644 index 0000000..c01fd4c --- /dev/null +++ b/.history/Player_20241226144533.cs @@ -0,0 +1,193 @@ +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("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; + } + } + } +} diff --git a/.history/Player_20250305121709.cs b/.history/Player_20250305121709.cs new file mode 100644 index 0000000..eb2cda2 --- /dev/null +++ b/.history/Player_20250305121709.cs @@ -0,0 +1,193 @@ +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("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; + } + } + } +} diff --git a/.history/Player_20250305121859.cs b/.history/Player_20250305121859.cs new file mode 100644 index 0000000..d1f337c --- /dev/null +++ b/.history/Player_20250305121859.cs @@ -0,0 +1,193 @@ +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("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; + } + } + } +} diff --git a/.history/Player_20250305121906.cs b/.history/Player_20250305121906.cs new file mode 100644 index 0000000..0955fc6 --- /dev/null +++ b/.history/Player_20250305121906.cs @@ -0,0 +1,193 @@ +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("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; + } + } + } +} diff --git a/CollisionManager.cs b/CollisionManager.cs index a337b72..820fc57 100644 --- a/CollisionManager.cs +++ b/CollisionManager.cs @@ -5,7 +5,7 @@ namespace LunaLightXMG public class CollisionManager { // Method to check if a position is colliding with any platform - public bool IsColliding(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + public static bool IsColliding(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) { Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); foreach (var platform in platforms) @@ -19,7 +19,7 @@ namespace LunaLightXMG } // Method to check if a position is colliding with any platform and return the colliding platform - public Platform GetCollidingPlatform(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) + public static Platform GetCollidingPlatform(Vector2 newPosition, BoundingBox boundingBox, Platform[] platforms) { Rectangle newBounds = new Rectangle((int)newPosition.X, (int)newPosition.Y, boundingBox.Bounds.Width, boundingBox.Bounds.Height); foreach (var platform in platforms) @@ -33,7 +33,7 @@ namespace LunaLightXMG } // Method to check if a position is colliding with any wall - public bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platforms) + public static bool WallCheck(Vector2 position, BoundingBox boundingBox, Platform[] platforms) { if (IsColliding(position + new Vector2(1, 0), boundingBox, platforms) || IsColliding(position + new Vector2(-1, 0), boundingBox, platforms)) { diff --git a/Enemy.cs b/Enemy.cs index 64e91e8..92f9169 100644 --- a/Enemy.cs +++ b/Enemy.cs @@ -78,9 +78,9 @@ namespace LunaLightXMG hspPrev = hsp; // Horizontal collision prediction float onePixh = Math.Sign(hsp); - if (collisionManager.IsColliding(position + new Vector2(hsp, 0), boundingBox, platforms)) + if (CollisionManager.IsColliding(position + new Vector2(hsp, 0), boundingBox, platforms)) { - while (!collisionManager.IsColliding(position + new Vector2(onePixh, 0), boundingBox, platforms)) + while (!CollisionManager.IsColliding(position + new Vector2(onePixh, 0), boundingBox, platforms)) { position.X += onePixh; } @@ -90,9 +90,9 @@ namespace LunaLightXMG // Vertical collision prediction float onePixv = Math.Sign(vsp); - if (collisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms)) + if (CollisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms)) { - while (!collisionManager.IsColliding(position + new Vector2(0, onePixv), boundingBox, platforms)) + while (!CollisionManager.IsColliding(position + new Vector2(0, onePixv), boundingBox, platforms)) { position.Y += onePixv; } @@ -101,10 +101,10 @@ namespace LunaLightXMG position.Y += vsp; // Vertical move // Grounded? - grounded = collisionManager.IsColliding(position + new Vector2(0, 1), boundingBox, platforms); + grounded = CollisionManager.IsColliding(position + new Vector2(0, 1), boundingBox, platforms); // Walled? - walled = collisionManager.WallCheck(position, boundingBox, platforms); + walled = CollisionManager.WallCheck(position, boundingBox, platforms); // Check for collision with player if (boundingBox.Intersects(player.boundingBox) && player.vsp > 0) diff --git a/Player.cs b/Player.cs index c01fd4c..0955fc6 100644 --- a/Player.cs +++ b/Player.cs @@ -113,7 +113,7 @@ namespace LunaLightXMG grvFinal = grvWall; vspMaxFinal = vspMaxWall; } - vsp += (vsp == 0 ? grvFinal * 2 : grvFinal); + vsp += vsp == 0 ? grvFinal * 2 : grvFinal; vsp = MathHelper.Clamp(vsp, vspJump, vspMaxFinal); } @@ -121,9 +121,9 @@ namespace LunaLightXMG { // Horizontal collision prediction float onePixh = Math.Sign(hsp); - if (collisionManager.IsColliding(position + new Vector2(hsp, 0), boundingBox, platforms)) + if (CollisionManager.IsColliding(position + new Vector2(hsp, 0), boundingBox, platforms)) { - while (!collisionManager.IsColliding(position + new Vector2(onePixh, 0), boundingBox, platforms)) + while (!CollisionManager.IsColliding(position + new Vector2(onePixh, 0), boundingBox, platforms)) { position.X += onePixh; } @@ -133,9 +133,9 @@ namespace LunaLightXMG // Vertical collision prediction float onePixv = Math.Sign(vsp); - if (collisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms)) + if (CollisionManager.IsColliding(position + new Vector2(0, vsp), boundingBox, platforms)) { - while (!collisionManager.IsColliding(position + new Vector2(0, onePixv), boundingBox, platforms)) + while (!CollisionManager.IsColliding(position + new Vector2(0, onePixv), boundingBox, platforms)) { position.Y += onePixv; } @@ -144,10 +144,10 @@ namespace LunaLightXMG position.Y += vsp; // Vertical move // Grounded? - grounded = collisionManager.IsColliding(position + new Vector2(0, 1), boundingBox, platforms); + grounded = CollisionManager.IsColliding(position + new Vector2(0, 1), boundingBox, platforms); // Walled? - walled = collisionManager.WallCheck(position, boundingBox, platforms); + walled = CollisionManager.WallCheck(position, boundingBox, platforms); if (walled) wasWalled = walled; }