Files
LunaLightXMG/Game1.cs
T
J. M. Ellis 0e8ac75cef 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
2024-06-02 15:47:52 -07:00

299 lines
11 KiB
C#

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Media;
using System;
using System.Collections.Generic;
namespace LunaLightXMG
{
public class Game1 : Game
{
// Class Objects
private Player player;
private PlayerInput playerInput;
private List<Enemy> enemies;
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 - eventually handle in a sprite manager?
private Texture2D platformTexture;
// Test platforms
private Platform[] platforms;
// Music
private SoundEffect sinkBeats;
private SoundEffectInstance backgroundMusicInstance;
// Debugging
private SpriteFont debugFont;
private Texture2D debugGrid;
// Utility
private static Random random;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
IsMouseVisible = true;
Window.ClientSizeChanged += OnClientSizeChanged;
Window.AllowUserResizing = true;
IsMouseVisible = true;
// Test player input and movement with abstracted player class
Vector2 initPlayerPosition = new Vector2(163, 63);
Vector2 initEnemyPosition = new Vector2(16, 16);
player = new Player(initPlayerPosition);
playerInput = new PlayerInput();
enemies = new List<Enemy>();
random = new Random(42);
}
private void OnClientSizeChanged(object sender, EventArgs eventArgs)
{
if (!resizing && Window.ClientBounds.Width > 0 && Window.ClientBounds.Height > 0)
{
resizing = true;
CalculateRenderDestination();
resizing = false;
}
}
protected override void Initialize()
{
// Set initial window size
graphics.PreferredBackBufferWidth = 1920;
graphics.PreferredBackBufferHeight = 1080;
graphics.ApplyChanges();
playerInput.HasControl = true; // May need to find a new home for this
base.Initialize();
CalculateRenderDestination();
// Play music
PlayBackgroundMusic(sinkBeats);
// 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)
};
}
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()
{
Point size = GraphicsDevice.Viewport.Bounds.Size;
// Calculate the integer scale factor
int scaleX = size.X / renderTarget.Width;
int scaleY = size.Y / renderTarget.Height;
int scale = Math.Min(scaleX, scaleY);
// Ensure the scale is at least 1
scale = Math.Max(scale, 1);
// Set renderDestination
renderDestination.Width = (int)(renderTarget.Width * scale);
renderDestination.Height = (int)(renderTarget.Height * scale);
renderDestination.X = (size.X - renderDestination.Width) / 2;
renderDestination.Y = (size.Y - renderDestination.Height) / 2;
}
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();
}
public static float GetRandomValueBetween1And3()
{
return (float)(1 + 2 * random.NextDouble());
}
}
}