diff --git a/BoundingBox.cs b/BoundingBox.cs
new file mode 100644
index 0000000..3c2afb7
--- /dev/null
+++ b/BoundingBox.cs
@@ -0,0 +1,24 @@
+using Microsoft.Xna.Framework;
+
+namespace LunaLightXMG
+{
+ public class BoundingBox
+ {
+ public Rectangle Bounds { get; private set; }
+
+ public BoundingBox(Rectangle bounds)
+ {
+ Bounds = bounds;
+ }
+
+ public bool Intersects(BoundingBox other)
+ {
+ return Bounds.Intersects(other.Bounds);
+ }
+
+ public void Update(Vector2 position, int width, int height)
+ {
+ Bounds = new Rectangle((int)position.X, (int)position.Y, width, height);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ClassDiagram1.cd b/ClassDiagram1.cd
new file mode 100644
index 0000000..7b89419
--- /dev/null
+++ b/ClassDiagram1.cd
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/Content/CastleWall TS16.png b/Content/CastleWall TS16.png
new file mode 100644
index 0000000..e95bbd0
Binary files /dev/null and b/Content/CastleWall TS16.png differ
diff --git a/Content/Content.mgcb b/Content/Content.mgcb
index 5e70b96..0ff1bfd 100644
--- a/Content/Content.mgcb
+++ b/Content/Content.mgcb
@@ -13,6 +13,49 @@
#---------------------------------- Content ---------------------------------#
+#begin CastleWall TS16.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:CastleWall TS16.png
+
+#begin fonts/debugFont.spritefont
+/importer:FontDescriptionImporter
+/processor:FontDescriptionProcessor
+/processorParam:PremultiplyAlpha=True
+/processorParam:TextureFormat=Compressed
+/build:fonts/debugFont.spritefont
+
+#begin platform.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:platform.png
+
+#begin player.png
+/importer:TextureImporter
+/processor:TextureProcessor
+/processorParam:ColorKeyColor=255,0,255,255
+/processorParam:ColorKeyEnabled=True
+/processorParam:GenerateMipmaps=False
+/processorParam:PremultiplyAlpha=True
+/processorParam:ResizeToPowerOfTwo=False
+/processorParam:MakeSquare=False
+/processorParam:TextureFormat=Color
+/build:player.png
+
#begin spr_cave1_background.png
/importer:TextureImporter
/processor:TextureProcessor
diff --git a/Content/fonts/debugFont.spritefont b/Content/fonts/debugFont.spritefont
new file mode 100644
index 0000000..bd33ecf
--- /dev/null
+++ b/Content/fonts/debugFont.spritefont
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+ Arial
+
+
+ 12
+
+
+ 0
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+ ~
+
+
+
+
diff --git a/Content/platform.png b/Content/platform.png
new file mode 100644
index 0000000..34c5c3e
Binary files /dev/null and b/Content/platform.png differ
diff --git a/Content/player.png b/Content/player.png
new file mode 100644
index 0000000..550dc69
Binary files /dev/null and b/Content/player.png differ
diff --git a/Game1.cs b/Game1.cs
index c8b3576..e30bb02 100644
--- a/Game1.cs
+++ b/Game1.cs
@@ -7,27 +7,32 @@ namespace LunaLightXMG
{
public class Game1 : Game
{
+ // Class Objects
+ private Player player;
+ private PlayerInput playerInput;
private GraphicsDeviceManager graphics;
private SpriteBatch spriteBatch;
+ // Native retro scale
+ private int retroWidth = 320;
+ private int retroHeight = 180;
+
// Test Render Target
private RenderTarget2D renderTarget;
private Rectangle renderDestination;
bool resizing;
- // Test sprites
- Texture2D sprRo;
- Texture2D sprCave1Background;
- Texture2D sprCave1Foreground;
- Texture2D sprCave1Walls;
+ // Test sprites - eventually handle in a sprite manager?
+ //Texture2D sprCave1Background;
+ //Texture2D sprCave1Foreground;
+ //Texture2D sprCave1Walls;
+ Texture2D platformTexture;
- // Test player input and movement with abstracted player class
- private Player player;
- // Player input
- private PlayerInput playerInput;
- // Native retro scale
- private int retroWidth = 320;
- private int retroHeight = 180;
+ // Test platforms
+ Platform[] platforms;
+
+ // Debugging
+ SpriteFont debugFont;
public Game1()
{
@@ -37,10 +42,11 @@ namespace LunaLightXMG
Window.ClientSizeChanged += OnClientSizeChanged;
Window.AllowUserResizing = true;
- IsMouseVisible = true;
+ IsMouseVisible = true;
// Test player input and movement with abstracted player class
- player = new Player();
+ Vector2 initPlayerPosition = new Vector2(163, 63);
+ player = new Player(initPlayerPosition);
playerInput = new PlayerInput();
}
@@ -65,6 +71,72 @@ namespace LunaLightXMG
base.Initialize();
CalculateRenderDestination();
+
+ // Test initialize platforms -- this should be abstracted to a class
+ // Also, I'm assuming using a tool like tiled will prevent having to
+ // manually input platforms like below...
+ platforms = new Platform[]
+ {
+ // platforms
+ new Platform(new Vector2(48, 128), 16, 16),
+ new Platform(new Vector2(64, 128), 16, 16),
+ new Platform(new Vector2(96, 96), 16, 16),
+ new Platform(new Vector2(112, 96), 16, 16),
+ new Platform(new Vector2(192, 128), 16, 16),
+ new Platform(new Vector2(208, 128), 16, 16),
+ new Platform(new Vector2(240, 96), 16, 16),
+ new Platform(new Vector2(256, 96), 16, 16),
+ new Platform(new Vector2(192, 64), 16, 16),
+ new Platform(new Vector2(208, 64), 16, 16),
+ new Platform(new Vector2(144, 32), 16, 16),
+ new Platform(new Vector2(160, 32), 16, 16),
+ new Platform(new Vector2(288, 128), 16, 16),
+ new Platform(new Vector2(16, 96), 16, 16),
+
+ // bottom
+ new Platform(new Vector2(16, 160), 16, 16),
+ new Platform(new Vector2(32, 160), 16, 16),
+ new Platform(new Vector2(48, 160), 16, 16),
+ new Platform(new Vector2(64, 160), 16, 16),
+ new Platform(new Vector2(80, 160), 16, 16),
+ new Platform(new Vector2(96, 160), 16, 16),
+ new Platform(new Vector2(112, 160), 16, 16),
+ new Platform(new Vector2(128, 160), 16, 16),
+ new Platform(new Vector2(144, 160), 16, 16),
+ new Platform(new Vector2(160, 160), 16, 16),
+ new Platform(new Vector2(176, 160), 16, 16),
+ new Platform(new Vector2(192, 160), 16, 16),
+ new Platform(new Vector2(208, 160), 16, 16),
+ new Platform(new Vector2(224, 160), 16, 16),
+ new Platform(new Vector2(240, 160), 16, 16),
+ new Platform(new Vector2(256, 160), 16, 16),
+ new Platform(new Vector2(272, 160), 16, 16),
+ new Platform(new Vector2(288, 160), 16, 16),
+
+ // left side
+ new Platform(new Vector2(0, 0), 16, 16),
+ new Platform(new Vector2(0, 16), 16, 16),
+ new Platform(new Vector2(0, 32), 16, 16),
+ new Platform(new Vector2(0, 48), 16, 16),
+ new Platform(new Vector2(0, 64), 16, 16),
+ new Platform(new Vector2(0, 80), 16, 16),
+ new Platform(new Vector2(0, 96), 16, 16),
+ new Platform(new Vector2(0, 112), 16, 16),
+ new Platform(new Vector2(0, 128), 16, 16),
+ new Platform(new Vector2(0, 144), 16, 16),
+
+ // right side
+ new Platform(new Vector2(304, 0), 16, 16),
+ new Platform(new Vector2(304, 16), 16, 16),
+ new Platform(new Vector2(304, 32), 16, 16),
+ new Platform(new Vector2(304, 48), 16, 16),
+ new Platform(new Vector2(304, 64), 16, 16),
+ new Platform(new Vector2(304, 80), 16, 16),
+ new Platform(new Vector2(304, 96), 16, 16),
+ new Platform(new Vector2(304, 112), 16, 16),
+ new Platform(new Vector2(304, 128), 16, 16),
+ new Platform(new Vector2(304, 144), 16, 16)
+ };
}
private void CalculateRenderDestination()
@@ -89,13 +161,20 @@ namespace LunaLightXMG
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
- sprRo = Content.Load("sprRo_Wall");
- sprCave1Background = Content.Load("spr_cave1_background");
- sprCave1Foreground = Content.Load("spr_Cave1_foreground");
- sprCave1Walls = Content.Load("spr_Cave1_walls");
+ //sprCave1Background = Content.Load("spr_cave1_background");
+ //sprCave1Foreground = Content.Load("spr_Cave1_foreground");
+ //sprCave1Walls = Content.Load("spr_Cave1_walls");
+ // Test platform
+ platformTexture = Content.Load("platform");
+
+ // load player sprite
+ player.LoadContent(Content); // player sprite is now handled in player.cs
// Test Render Target
renderTarget = new RenderTarget2D(GraphicsDevice, retroWidth, retroHeight);
+
+ // Debugging
+ debugFont = Content.Load("fonts/debugFont");
}
protected override void Update(GameTime gameTime)
@@ -106,7 +185,7 @@ namespace LunaLightXMG
// Test player input and movement with abstracted player class
playerInput.Update();
- player.Update(gameTime, playerInput);
+ player.Update(gameTime, playerInput, platforms);
base.Update(gameTime);
}
@@ -121,13 +200,19 @@ namespace LunaLightXMG
// Test Sprite
spriteBatch.Begin(samplerState: SamplerState.PointClamp);
// Draw sprites here
- spriteBatch.Draw(sprCave1Background,new Vector2(0,0),Color.White);
+ //spriteBatch.Draw(sprCave1Background,new Vector2(0,0),Color.White);
+
+ // Test draw tiles
+ foreach (var platform in platforms)
+ {
+ platform.Draw(spriteBatch, platformTexture); // Assuming all tiles use the same texture for now
+ }
// Test player input and movement with abstracted player class
- player.Draw(spriteBatch, sprRo);
+ player.Draw(spriteBatch);
- spriteBatch.Draw(sprCave1Walls, new Vector2(0, 0), Color.White);
- spriteBatch.Draw(sprCave1Foreground, new Vector2(0, 0), Color.White);
+ //spriteBatch.Draw(sprCave1Walls, new Vector2(0, 0), Color.White);
+ //spriteBatch.Draw(sprCave1Foreground, new Vector2(0, 0), Color.White);
spriteBatch.End();
@@ -137,7 +222,24 @@ namespace LunaLightXMG
spriteBatch.Draw(renderTarget, renderDestination, Color.White);
spriteBatch.End();
+ // Debugging
+ DrawDebugInfo();
+
base.Draw(gameTime);
}
+
+ // Debugging
+ private void DrawDebugInfo()
+ {
+ spriteBatch.Begin();
+
+ // Draw debug messages
+ spriteBatch.DrawString(debugFont, $"VSP: {player.vsp}", new Vector2(10, 10), Color.White);
+ spriteBatch.DrawString(debugFont, $"Grounded: {player.grounded}", new Vector2(10, 30), Color.White);
+ spriteBatch.DrawString(debugFont, $"Walled: {player.walled}", new Vector2(10, 50), Color.White);
+ spriteBatch.DrawString(debugFont, $"Position: {player.position}", new Vector2(10, 70), Color.White);
+
+ spriteBatch.End();
+ }
}
}
diff --git a/Platform.cs b/Platform.cs
new file mode 100644
index 0000000..9f1b657
--- /dev/null
+++ b/Platform.cs
@@ -0,0 +1,23 @@
+using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Graphics;
+
+namespace LunaLightXMG
+{
+ public class Platform
+ {
+ public Vector2 Position { get; private set; }
+ public BoundingBox BoundingBox { get; private set; }
+
+ public Platform(Vector2 position, int width, int height)
+ {
+ Position = position;
+ BoundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, width, height));
+ }
+
+ public void Draw(SpriteBatch spriteBatch, Texture2D texture)
+ {
+ spriteBatch.Draw(texture, Position, Color.White);
+ }
+ }
+}
+
diff --git a/Player.cs b/Player.cs
index ac2f26d..e5e83ed 100644
--- a/Player.cs
+++ b/Player.cs
@@ -1,5 +1,6 @@
using System;
using Microsoft.Xna.Framework;
+using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace LunaLightXMG
@@ -8,25 +9,28 @@ namespace LunaLightXMG
{
// Declare variables
private float hsp; // Horizontal speed
- private float vsp; // Vertical speed
+ public float vsp; // Vertical speed
private float wallJumpDelay; // Delay for wall jumping
- private bool grounded; // Is the player grounded?
- private bool walled; // Is the player wall sliding?
- private float hspAcc; // Horizontal acceleration
- private float hspFrictionGround; // Ground friction
- private float hspFrictionAir; // Air friction
- private float hspWalk; // Maximum horizontal speed
+ 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 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
- // Player position
+ // Player initilization
+ private Texture2D texture;
public Vector2 position;
-
+ public BoundingBox BoundingBox { get; private set; }
+
// Constructor to initialize variables
- public Player()
+ public Player(Vector2 initPosition)
{
// Initialize your variables here
hsp = 0;
@@ -34,32 +38,46 @@ namespace LunaLightXMG
wallJumpDelay = 0;
grounded = false;
walled = false;
- hspAcc = 0.5f;
- hspFrictionGround = 0.2f;
- hspFrictionAir = 0.1f;
- hspWalk = 4f;
- //grv = 0.5f;
- grv = 0.0f; // No grav until we have walls, bounding boxes, etc..
+ wasWalled = false;
+ hspAcc = 0.2f;
+ hspFrictionGround = 0.3f;
+ hspFrictionAir = 0.3f;
+ hspWalk = 3f;
+ grv = 0.2f;
vspMax = 10f;
grvWall = 0.1f;
vspMaxWall = 5f;
- vspJump = -10f;
+ vspJump = -4f;
- position = new Vector2(163, 63); // Initialize player position
+ position = initPosition;
+ BoundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 16));
+ }
+ public void LoadContent(ContentManager content)
+ {
+ texture = content.Load("player");
}
// Update method to handle movement logic
- public void Update(GameTime gameTime, PlayerInput input)
+ public void Update(GameTime gameTime, PlayerInput input, Platform[] platforms)
{
+ // Update player position
Movement(input);
- // Update player position based on speed
- position.X += hsp;
- position.Y += vsp;
+ // Update the player's bounding box
+ BoundingBox.Update(position, 8, 16);
+
+ CollisionChecks(platforms);
}
private void Movement(PlayerInput input)
{
+ // Handle jumping
+ if (input.KeyJump && grounded)
+ {
+ grounded = false;
+ vsp = vspJump;
+ }
+
// Horizontal movement with acceleration + wall jump delay
wallJumpDelay = Math.Max(wallJumpDelay - 1, 0); // counts down every frame
@@ -86,7 +104,6 @@ namespace LunaLightXMG
grvFinal = grvWall;
vspMaxFinal = vspMaxWall;
}
-
vsp += (vsp == 0 ? grvFinal * 2 : grvFinal);
vsp = MathHelper.Clamp(vsp, vspJump, vspMaxFinal);
}
@@ -109,12 +126,83 @@ namespace LunaLightXMG
return start;
}
- public void Draw(SpriteBatch spriteBatch, Texture2D texture)
+ // Collision Checks - maybe abstract to a class ---------------------------------------------------------------
+ private void CollisionChecks(Platform[] platforms)
+ {
+ // Horizontal collision prediction
+ float onePixh = Math.Sign(hsp);
+ if (IsColliding(position + new Vector2(hsp, 0), platforms))
+ {
+ while (!IsColliding(position + new Vector2(onePixh, 0), platforms))
+ {
+ position.X += onePixh;
+ }
+ hsp = 0;
+ }
+ position.X += hsp; // Horizontal move
+
+ // Vertical collision prediction
+ float onePixv = Math.Sign(vsp);
+ if (IsColliding(position + new Vector2(0, vsp), platforms))
+ {
+ while (!IsColliding(position + new Vector2(0, onePixv), platforms))
+ {
+ position.Y += onePixv;
+ }
+ vsp = 0;
+ }
+ position.Y += vsp; // Vertical move
+
+ // Grounded?
+ grounded = IsColliding(position + new Vector2(0, 1), platforms);
+
+ // Walled?
+ walled = WallCheck(platforms);
+ if (walled)
+ wasWalled = walled;
+ }
+
+ private bool IsColliding(Vector2 newPosition, 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;
+ }
+
+ private Platform GetCollidingPlatform(Vector2 newPosition, 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;
+ }
+
+ private bool WallCheck(Platform[] platforms)
+ {
+ if (IsColliding(position + new Vector2(1, 0), platforms) || IsColliding(position + new Vector2(-1, 0), platforms))
+ {
+ return true;
+ }
+ return false;
+ }
+ // Collision checks end ---------------------------------------------------------------------------------------------------------
+
+ 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);
}
}
-
}
diff --git a/PlayerInput.cs b/PlayerInput.cs
index f853ab9..6e3169e 100644
--- a/PlayerInput.cs
+++ b/PlayerInput.cs
@@ -27,7 +27,7 @@ namespace LunaLightXMG
// If using controller, switch to keyboard by pressing any key
if (Keyboard.GetState().GetPressedKeys().Length > 0)
{
- // Insert your logic to create the objMouseJoyStick instance
+ // TODO: Insert logic to create the objMouseJoyStick instance
Controller = false;
}
@@ -67,7 +67,7 @@ namespace LunaLightXMG
GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
if (gamepadState.IsConnected && gamepadState.Buttons.Start == ButtonState.Pressed)
{
- // Insert your logic to destroy the objMouseJoyStick instance
+ // TODO: Insert logic to destroy the objMouseJoyStick instance
Controller = true;
}
@@ -111,5 +111,4 @@ namespace LunaLightXMG
}
}
}
-
}