Ultra minor updates.

This commit is contained in:
jme9
2025-03-05 12:38:51 -08:00
parent bab017e1a3
commit b270b8189b
14 changed files with 1421 additions and 16 deletions
@@ -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;
}
}
}
@@ -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;
}
}
}
@@ -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;
}
}
}
@@ -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;
}
}
}
+151
View File
@@ -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<Texture2D>("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;
}
}
}
+151
View File
@@ -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<Texture2D>("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;
}
}
}
+151
View File
@@ -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<Texture2D>("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;
}
}
}
+193
View File
@@ -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<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;
}
}
}
}
+193
View File
@@ -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<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;
}
}
}
}
+193
View File
@@ -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<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;
}
}
}
}
+193
View File
@@ -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<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;
}
}
}
}
+3 -3
View File
@@ -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))
{
+6 -6
View File
@@ -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)
+7 -7
View File
@@ -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;
}