Super Happy Jumping Pickle Man!

This commit is contained in:
J. M. Ellis
2024-05-27 21:50:09 -07:00
parent 1bfddab1b5
commit 02907cb4b6
11 changed files with 396 additions and 55 deletions
+24
View File
@@ -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);
}
}
}
+2
View File
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram />
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

+43
View File
@@ -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
+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains an xml description of a font, and will be read by the XNA
Framework Content Pipeline. Follow the comments to customize the appearance
of the font in your game, and to change the characters which are available to draw
with.
-->
<XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">
<Asset Type="Graphics:FontDescription">
<!--
Modify this string to change the font that will be imported.
-->
<FontName>Arial</FontName>
<!--
Size is a float value, measured in points. Modify this value to change
the size of the font.
-->
<Size>12</Size>
<!--
Spacing is a float value, measured in pixels. Modify this value to change
the amount of spacing in between characters.
-->
<Spacing>0</Spacing>
<!--
UseKerning controls the layout of the font. If this value is true, kerning information
will be used when placing characters.
-->
<UseKerning>true</UseKerning>
<!--
Style controls the style of the font. Valid entries are "Regular", "Bold", "Italic",
and "Bold, Italic", and are case sensitive.
-->
<Style>Regular</Style>
<!--
If you uncomment this line, the default character will be substituted if you draw
or measure text that contains characters which were not included in the font.
-->
<!-- <DefaultCharacter>*</DefaultCharacter> -->
<!--
CharacterRegions control what letters are available in the font. Every
character from Start to End will be built and made available for drawing. The
default range is from 32, (ASCII space), to 126, ('~'), covering the basic Latin
character set. The characters are ordered according to the Unicode standard.
See the documentation for more information.
-->
<CharacterRegions>
<CharacterRegion>
<Start>&#32;</Start>
<End>&#126;</End>
</CharacterRegion>
</CharacterRegions>
</Asset>
</XnaContent>
Binary file not shown.

After

Width:  |  Height:  |  Size: 192 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B

+124 -22
View File
@@ -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()
{
@@ -40,7 +45,8 @@ namespace LunaLightXMG
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<Texture2D>("sprRo_Wall");
sprCave1Background = Content.Load<Texture2D>("spr_cave1_background");
sprCave1Foreground = Content.Load<Texture2D>("spr_Cave1_foreground");
sprCave1Walls = Content.Load<Texture2D>("spr_Cave1_walls");
//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)
@@ -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();
}
}
}
+23
View File
@@ -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);
}
}
}
+108 -20
View File
@@ -1,5 +1,6 @@
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace LunaLightXMG
@@ -8,10 +9,11 @@ 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?
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
@@ -22,11 +24,13 @@ namespace LunaLightXMG
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<Texture2D>("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);
}
}
}
+2 -3
View File
@@ -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
}
}
}
}