mirror of
https://github.com/TheRavenwoodArts/LunaLightXMG.git
synced 2026-07-31 00:15:02 -07:00
Super happy jumping pickle man (#3)
* Added enemy class * Added enemy class and fixed DumpFraction bug. * Update README.md * Fixed enemy movement bug, added game music. * Fixed bug: Background music looping. * Fixed enemey getting stuck on wall. Code reorganization * Minor updates
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,30 @@
|
|||||||
/processorParam:TextureFormat=Color
|
/processorParam:TextureFormat=Color
|
||||||
/build:CastleWall TS16.png
|
/build:CastleWall TS16.png
|
||||||
|
|
||||||
|
#begin debugGrid.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:debugGrid.PNG
|
||||||
|
|
||||||
|
#begin enemy.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:enemy.png
|
||||||
|
|
||||||
#begin fonts/debugFont.spritefont
|
#begin fonts/debugFont.spritefont
|
||||||
/importer:FontDescriptionImporter
|
/importer:FontDescriptionImporter
|
||||||
/processor:FontDescriptionProcessor
|
/processor:FontDescriptionProcessor
|
||||||
@@ -32,6 +56,24 @@
|
|||||||
/processorParam:TextureFormat=Compressed
|
/processorParam:TextureFormat=Compressed
|
||||||
/build:fonts/debugFont.spritefont
|
/build:fonts/debugFont.spritefont
|
||||||
|
|
||||||
|
#begin grid.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:grid.PNG
|
||||||
|
|
||||||
|
#begin music/sinkBeats.wav
|
||||||
|
/importer:WavImporter
|
||||||
|
/processor:SoundEffectProcessor
|
||||||
|
/processorParam:Quality=Best
|
||||||
|
/build:music/sinkBeats.wav
|
||||||
|
|
||||||
#begin platform.png
|
#begin platform.png
|
||||||
/importer:TextureImporter
|
/importer:TextureImporter
|
||||||
/processor:TextureProcessor
|
/processor:TextureProcessor
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 180 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
@@ -0,0 +1,141 @@
|
|||||||
|
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 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)
|
||||||
|
{
|
||||||
|
spriteBatch.Draw(texture, position, Color.White);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Implementation -------------------------------------------------------------------------------
|
||||||
|
private void Movement()
|
||||||
|
{
|
||||||
|
if (hsp == 0) { hsp = 1; }
|
||||||
|
if (walled) { hsp = -hsp; }
|
||||||
|
if (!grounded) { vsp += grv; }
|
||||||
|
if (RandomJump() && grounded) { vsp = vspJump; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CollisionChecks(Platform[] platforms, Player player)
|
||||||
|
{
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
using Microsoft.Xna.Framework;
|
using Microsoft.Xna.Framework;
|
||||||
using Microsoft.Xna.Framework.Graphics;
|
using Microsoft.Xna.Framework.Graphics;
|
||||||
using Microsoft.Xna.Framework.Input;
|
using Microsoft.Xna.Framework.Input;
|
||||||
|
using Microsoft.Xna.Framework.Audio;
|
||||||
|
using Microsoft.Xna.Framework.Media;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace LunaLightXMG
|
namespace LunaLightXMG
|
||||||
{
|
{
|
||||||
@@ -10,6 +13,7 @@ namespace LunaLightXMG
|
|||||||
// Class Objects
|
// Class Objects
|
||||||
private Player player;
|
private Player player;
|
||||||
private PlayerInput playerInput;
|
private PlayerInput playerInput;
|
||||||
|
private List<Enemy> enemies;
|
||||||
private GraphicsDeviceManager graphics;
|
private GraphicsDeviceManager graphics;
|
||||||
private SpriteBatch spriteBatch;
|
private SpriteBatch spriteBatch;
|
||||||
|
|
||||||
@@ -23,16 +27,21 @@ namespace LunaLightXMG
|
|||||||
bool resizing;
|
bool resizing;
|
||||||
|
|
||||||
// Test sprites - eventually handle in a sprite manager?
|
// Test sprites - eventually handle in a sprite manager?
|
||||||
//Texture2D sprCave1Background;
|
private Texture2D platformTexture;
|
||||||
//Texture2D sprCave1Foreground;
|
|
||||||
//Texture2D sprCave1Walls;
|
|
||||||
Texture2D platformTexture;
|
|
||||||
|
|
||||||
// Test platforms
|
// Test platforms
|
||||||
Platform[] platforms;
|
private Platform[] platforms;
|
||||||
|
|
||||||
|
// Music
|
||||||
|
private SoundEffect sinkBeats;
|
||||||
|
private SoundEffectInstance backgroundMusicInstance;
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
SpriteFont debugFont;
|
private SpriteFont debugFont;
|
||||||
|
private Texture2D debugGrid;
|
||||||
|
|
||||||
|
// Utility
|
||||||
|
private static Random random;
|
||||||
|
|
||||||
public Game1()
|
public Game1()
|
||||||
{
|
{
|
||||||
@@ -46,8 +55,12 @@ namespace LunaLightXMG
|
|||||||
|
|
||||||
// Test player input and movement with abstracted player class
|
// Test player input and movement with abstracted player class
|
||||||
Vector2 initPlayerPosition = new Vector2(163, 63);
|
Vector2 initPlayerPosition = new Vector2(163, 63);
|
||||||
|
Vector2 initEnemyPosition = new Vector2(16, 16);
|
||||||
player = new Player(initPlayerPosition);
|
player = new Player(initPlayerPosition);
|
||||||
playerInput = new PlayerInput();
|
playerInput = new PlayerInput();
|
||||||
|
enemies = new List<Enemy>();
|
||||||
|
|
||||||
|
random = new Random(42);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClientSizeChanged(object sender, EventArgs eventArgs)
|
private void OnClientSizeChanged(object sender, EventArgs eventArgs)
|
||||||
@@ -71,6 +84,8 @@ namespace LunaLightXMG
|
|||||||
|
|
||||||
base.Initialize();
|
base.Initialize();
|
||||||
CalculateRenderDestination();
|
CalculateRenderDestination();
|
||||||
|
// Play music
|
||||||
|
PlayBackgroundMusic(sinkBeats);
|
||||||
|
|
||||||
// Test initialize platforms -- this should be abstracted to a class
|
// Test initialize platforms -- this should be abstracted to a class
|
||||||
// Also, I'm assuming using a tool like tiled will prevent having to
|
// Also, I'm assuming using a tool like tiled will prevent having to
|
||||||
@@ -139,6 +154,109 @@ namespace LunaLightXMG
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void LoadContent()
|
||||||
|
{
|
||||||
|
spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||||
|
|
||||||
|
// Test platform
|
||||||
|
platformTexture = Content.Load<Texture2D>("platform");
|
||||||
|
// Music
|
||||||
|
sinkBeats = Content.Load<SoundEffect>("music/sinkBeats");
|
||||||
|
// load player sprite
|
||||||
|
player.LoadContent(Content); // player sprite is now handled in player.cs
|
||||||
|
|
||||||
|
// Spawn 10 enemies at the start of the level
|
||||||
|
for (int i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
Vector2 spawnPosition = new Vector2(16 + i*3,16);
|
||||||
|
Enemy enemy = new Enemy(spawnPosition, GetRandomValueBetween1And3());
|
||||||
|
enemy.LoadContent(Content);
|
||||||
|
enemies.Add(enemy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test Render Target
|
||||||
|
renderTarget = new RenderTarget2D(GraphicsDevice, retroWidth, retroHeight);
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
debugFont = Content.Load<SpriteFont>("fonts/debugFont");
|
||||||
|
debugGrid = Content.Load<Texture2D>("debugGrid");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update(GameTime gameTime)
|
||||||
|
{
|
||||||
|
// Temporary quit game - eventually handle in a pause menu class
|
||||||
|
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
||||||
|
Exit();
|
||||||
|
|
||||||
|
// Test player input and movement with abstracted player class
|
||||||
|
playerInput.Update();
|
||||||
|
player.Update(gameTime, playerInput, platforms);
|
||||||
|
|
||||||
|
foreach (var enemy in enemies) {
|
||||||
|
enemy.Update(gameTime, player, platforms);
|
||||||
|
}
|
||||||
|
|
||||||
|
base.Update(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Draw(GameTime gameTime)
|
||||||
|
{
|
||||||
|
GraphicsDevice.Clear(Color.CornflowerBlue);
|
||||||
|
|
||||||
|
// Test Render Target - Draw sprites to the render target
|
||||||
|
GraphicsDevice.SetRenderTarget(renderTarget);
|
||||||
|
|
||||||
|
// Test Sprite
|
||||||
|
spriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
||||||
|
// Debug Grid
|
||||||
|
spriteBatch.Draw(debugGrid, new Vector2(0, 0), Color.Blue);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
foreach (var enemy in enemies)
|
||||||
|
{
|
||||||
|
enemy.Draw(spriteBatch);
|
||||||
|
}
|
||||||
|
|
||||||
|
spriteBatch.End();
|
||||||
|
|
||||||
|
|
||||||
|
// Test Render Target - Draw render target to the screen
|
||||||
|
GraphicsDevice.SetRenderTarget(null);
|
||||||
|
spriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
||||||
|
spriteBatch.Draw(renderTarget, renderDestination, Color.White);
|
||||||
|
spriteBatch.End();
|
||||||
|
|
||||||
|
// Debugging
|
||||||
|
DrawDebugInfo();
|
||||||
|
|
||||||
|
base.Draw(gameTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Method Implementation -------------------------------------------------------------------------------
|
||||||
|
private void PlayBackgroundMusic(SoundEffect backgroundMusic)
|
||||||
|
{
|
||||||
|
if (backgroundMusicInstance == null || backgroundMusicInstance.State != SoundState.Playing)
|
||||||
|
{
|
||||||
|
if (backgroundMusicInstance != null)
|
||||||
|
{
|
||||||
|
backgroundMusicInstance.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
backgroundMusicInstance = backgroundMusic.CreateInstance();
|
||||||
|
backgroundMusicInstance.IsLooped = true;
|
||||||
|
backgroundMusicInstance.Play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CalculateRenderDestination()
|
private void CalculateRenderDestination()
|
||||||
{
|
{
|
||||||
Point size = GraphicsDevice.Viewport.Bounds.Size;
|
Point size = GraphicsDevice.Viewport.Bounds.Size;
|
||||||
@@ -158,77 +276,7 @@ namespace LunaLightXMG
|
|||||||
renderDestination.X = (size.X - renderDestination.Width) / 2;
|
renderDestination.X = (size.X - renderDestination.Width) / 2;
|
||||||
renderDestination.Y = (size.Y - renderDestination.Height) / 2;
|
renderDestination.Y = (size.Y - renderDestination.Height) / 2;
|
||||||
}
|
}
|
||||||
protected override void LoadContent()
|
|
||||||
{
|
|
||||||
spriteBatch = new SpriteBatch(GraphicsDevice);
|
|
||||||
//sprCave1Background = Content.Load<Texture2D>("spr_cave1_background");
|
|
||||||
//sprCave1Foreground = Content.Load<Texture2D>("spr_Cave1_foreground");
|
|
||||||
//sprCave1Walls = Content.Load<Texture2D>("spr_Cave1_walls");
|
|
||||||
// Test platform
|
|
||||||
platformTexture = Content.Load<Texture2D>("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<SpriteFont>("fonts/debugFont");
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update(GameTime gameTime)
|
|
||||||
{
|
|
||||||
// Temporary quit game - eventually handle in a pause menu class
|
|
||||||
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
|
|
||||||
Exit();
|
|
||||||
|
|
||||||
// Test player input and movement with abstracted player class
|
|
||||||
playerInput.Update();
|
|
||||||
player.Update(gameTime, playerInput, platforms);
|
|
||||||
|
|
||||||
base.Update(gameTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Draw(GameTime gameTime)
|
|
||||||
{
|
|
||||||
GraphicsDevice.Clear(Color.CornflowerBlue);
|
|
||||||
|
|
||||||
// Test Render Target - Draw sprites to the render target
|
|
||||||
GraphicsDevice.SetRenderTarget(renderTarget);
|
|
||||||
|
|
||||||
// Test Sprite
|
|
||||||
spriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
|
||||||
// Draw sprites here
|
|
||||||
//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);
|
|
||||||
|
|
||||||
//spriteBatch.Draw(sprCave1Walls, new Vector2(0, 0), Color.White);
|
|
||||||
//spriteBatch.Draw(sprCave1Foreground, new Vector2(0, 0), Color.White);
|
|
||||||
spriteBatch.End();
|
|
||||||
|
|
||||||
|
|
||||||
// Test Render Target - Draw render target to the screen
|
|
||||||
GraphicsDevice.SetRenderTarget(null);
|
|
||||||
spriteBatch.Begin(samplerState: SamplerState.PointClamp);
|
|
||||||
spriteBatch.Draw(renderTarget, renderDestination, Color.White);
|
|
||||||
spriteBatch.End();
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
DrawDebugInfo();
|
|
||||||
|
|
||||||
base.Draw(gameTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debugging
|
|
||||||
private void DrawDebugInfo()
|
private void DrawDebugInfo()
|
||||||
{
|
{
|
||||||
spriteBatch.Begin();
|
spriteBatch.Begin();
|
||||||
@@ -241,5 +289,10 @@ namespace LunaLightXMG
|
|||||||
|
|
||||||
spriteBatch.End();
|
spriteBatch.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float GetRandomValueBetween1And3()
|
||||||
|
{
|
||||||
|
return (float)(1 + 2 * random.NextDouble());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,9 @@
|
|||||||
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
<PackageReference Include="MonoGame.Framework.DesktopGL" Version="3.8.1.303" />
|
||||||
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
<PackageReference Include="MonoGame.Content.Builder.Task" Version="3.8.1.303" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Content\music\" />
|
||||||
|
</ItemGroup>
|
||||||
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">
|
||||||
<Message Text="Restoring dotnet tools" Importance="High" />
|
<Message Text="Restoring dotnet tools" Importance="High" />
|
||||||
<Exec Command="dotnet tool restore" />
|
<Exec Command="dotnet tool restore" />
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ using Microsoft.Xna.Framework.Graphics;
|
|||||||
|
|
||||||
namespace LunaLightXMG
|
namespace LunaLightXMG
|
||||||
{
|
{
|
||||||
internal class Player
|
public class Player
|
||||||
{
|
{
|
||||||
// Declare variables
|
|
||||||
private float hsp; // Horizontal speed
|
private float hsp; // Horizontal speed
|
||||||
public float vsp; // Vertical speed
|
public float vsp; // Vertical speed
|
||||||
private float hsp_frac; // Hold fractional position data
|
private float hsp_frac; // Hold fractional position data
|
||||||
@@ -25,16 +24,13 @@ namespace LunaLightXMG
|
|||||||
private float grvWall; // Gravity when wall sliding
|
private float grvWall; // Gravity when wall sliding
|
||||||
private float vspMaxWall; // Maximum vertical speed when wall sliding
|
private float vspMaxWall; // Maximum vertical speed when wall sliding
|
||||||
private float vspJump; // Jump speed
|
private float vspJump; // Jump speed
|
||||||
|
|
||||||
// Player initilization
|
|
||||||
private Texture2D texture;
|
private Texture2D texture;
|
||||||
public Vector2 position;
|
public Vector2 position;
|
||||||
public BoundingBox BoundingBox { get; private set; }
|
public BoundingBox boundingBox { get; private set; }
|
||||||
|
private CollisionManager collisionManager;
|
||||||
|
|
||||||
// Constructor to initialize variables
|
|
||||||
public Player(Vector2 initPosition)
|
public Player(Vector2 initPosition)
|
||||||
{
|
{
|
||||||
// Initialize your variables here
|
|
||||||
hsp = 0;
|
hsp = 0;
|
||||||
vsp = 0;
|
vsp = 0;
|
||||||
hsp_frac = 0;
|
hsp_frac = 0;
|
||||||
@@ -52,34 +48,36 @@ namespace LunaLightXMG
|
|||||||
grvWall = 0.1f;
|
grvWall = 0.1f;
|
||||||
vspMaxWall = 5f;
|
vspMaxWall = 5f;
|
||||||
vspJump = -4f;
|
vspJump = -4f;
|
||||||
|
|
||||||
position = initPosition;
|
position = initPosition;
|
||||||
BoundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 16));
|
boundingBox = new BoundingBox(new Rectangle((int)position.X, (int)position.Y, 8, 16));
|
||||||
|
collisionManager = new CollisionManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LoadContent(ContentManager content)
|
public void LoadContent(ContentManager content)
|
||||||
{
|
{
|
||||||
texture = content.Load<Texture2D>("player");
|
texture = content.Load<Texture2D>("player");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update method to handle movement logic
|
|
||||||
public void Update(GameTime gameTime, PlayerInput input, Platform[] platforms)
|
public void Update(GameTime gameTime, PlayerInput input, Platform[] platforms)
|
||||||
{
|
{
|
||||||
// Update player position
|
|
||||||
Movement(input);
|
Movement(input);
|
||||||
// Dump fractional position data.
|
boundingBox.Update(position, boundingBox.Bounds.Width, boundingBox.Bounds.Height);
|
||||||
DumpFractions();
|
DumpFractions();
|
||||||
// Update the player's bounding box
|
|
||||||
BoundingBox.Update(position, 8, 16);
|
|
||||||
|
|
||||||
CollisionChecks(platforms);
|
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 -------------------------------------------------------------------------------
|
||||||
private void Movement(PlayerInput input)
|
private void Movement(PlayerInput input)
|
||||||
{
|
{
|
||||||
// Handle jumping
|
|
||||||
if (input.KeyJump && grounded)
|
if (input.KeyJump && grounded)
|
||||||
{
|
{
|
||||||
grounded = false;
|
|
||||||
vsp = vspJump;
|
vsp = vspJump;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +111,41 @@ namespace LunaLightXMG
|
|||||||
vsp = MathHelper.Clamp(vsp, vspJump, vspMaxFinal);
|
vsp = MathHelper.Clamp(vsp, vspJump, vspMaxFinal);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper method to smoothly approach a target value
|
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)
|
private float Approach(float start, float end, float shift)
|
||||||
{
|
{
|
||||||
if (start < end)
|
if (start < end)
|
||||||
@@ -133,92 +165,23 @@ namespace LunaLightXMG
|
|||||||
|
|
||||||
private void DumpFractions()
|
private void DumpFractions()
|
||||||
{
|
{
|
||||||
// Movement Speeds
|
if (grounded)
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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))
|
float adjustedPosX = (float)Math.Round(position.X);
|
||||||
{
|
float adjustedPosY = (float)Math.Round(position.Y);
|
||||||
position.X += onePixh;
|
position.X = adjustedPosX;
|
||||||
}
|
position.Y = adjustedPosY;
|
||||||
hsp = 0;
|
|
||||||
}
|
}
|
||||||
position.X += hsp; // Horizontal move
|
|
||||||
|
|
||||||
// Vertical collision prediction
|
if (vsp >= 0)
|
||||||
float onePixv = Math.Sign(vsp);
|
|
||||||
if (IsColliding(position + new Vector2(0, vsp), platforms))
|
|
||||||
{
|
{
|
||||||
while (!IsColliding(position + new Vector2(0, onePixv), platforms))
|
hsp += hsp_frac;
|
||||||
{
|
vsp += vsp_frac;
|
||||||
position.Y += onePixv;
|
hsp_frac = hsp - (float)Math.Floor(hsp);
|
||||||
}
|
vsp_frac = vsp - (float)Math.Floor(vsp);
|
||||||
vsp = 0;
|
hsp -= hsp_frac;
|
||||||
|
vsp -= vsp_frac;
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -67,7 +67,7 @@ namespace LunaLightXMG
|
|||||||
GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
|
GamePadState gamepadState = GamePad.GetState(PlayerIndex.One);
|
||||||
if (gamepadState.IsConnected && gamepadState.Buttons.Start == ButtonState.Pressed)
|
if (gamepadState.IsConnected && gamepadState.Buttons.Start == ButtonState.Pressed)
|
||||||
{
|
{
|
||||||
// TODO: Insert logic to destroy the objMouseJoyStick instance
|
// TODO: Insert logic to destroy the objMouseJoyStick instance
|
||||||
Controller = true;
|
Controller = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# LunaLightXMG
|
# LunaLightXMG
|
||||||
|
|
||||||
A Sci-fi fantaasy retro style platformer. Play as Ro and Ama, questing through the magical and treacherous realms of Uluna. An evil sorcerer has been harvesting the spirits of the forest for their own mechanisms of tyrrany! You must save the spirits of the forest and stop the evil sorcerer!!! Your adventures take you through dark woods and long forgotten temples to the highest castle towers atop the the tallest peaks of Uluna.
|
A Sci-fi fantasy retro style platformer. Play as Ro and Ama, questing through the magical and treacherous realms of Uluna. An evil sorcerer has been harvesting the spirits of the forest for their own mechanisms of tyrrany! You must save the spirits of the forest and stop the evil sorcerer!!! Your adventures take you through dark woods and long forgotten temples to the highest castle towers atop the the tallest peaks of Uluna.
|
||||||
|
|
||||||
[](https://www.youtube.com/watch?v=J_KjVaEGNk4)
|
[](https://www.youtube.com/watch?v=J_KjVaEGNk4)
|
||||||
|
|||||||
Reference in New Issue
Block a user