My avatar...

Dave Henry Blog

Syndication feed icon

A Weekend of Game Development

Published -

It's been a while since I'd even looked at SystemX and I was starting to think I was over doing things, so as a small project over the weekend I thought I'd just play a little.

First I opened a blank MonoGame project and added some code for a SpriteSheetLibrary. Then a quick and dirty FontManager. Next up a SpriteBatchExtender. Just the sort of things to make it easy to put sprites and strings on the screen.

f9591f1b-b7a4-4f50-8d7b-feaa79e690f3.jpg

Next thing I know I poking around in the MonoGame tutorials and I found a really nice DrawLine function so I thought I'd see how fast it was.

I ended up with a 1920x1080 Window drawing 3386 Sprites. Over the top of that I had 150,000 points that were all moving at a random velocities each with collision detection with the sides of the screen. So I paired them up to make 75,000 lines. Which was keeping a steady 60 Fps with Vsync.

Screenshot from 2026-02-22 10-00-34.png

Now what...

Well I can draw lines and boxes, I seem to remember an explanation of the A* algorithm that javidx9 did on his YouTube channel a few years back...

It took a few hours to convert the C++ to C# and make it look tidy. But then I got board of clicking the grid to make obstacles.

Screenshotfrom2026-02-2214-29-04.png

What I need is a maze for it to solve, back to javidx9 for his programming Mazes video. Luckily I'd already converted this code when I was working on Maze Fodder so after some fettling to get the two bits of code to work together, and voilà a working random maze solver.

Screenshotfrom2026-02-2217-19-16.png

Well here are a few code snip-its that came out of this little playtime that I quite liked:-

NextVector2

An extension to the Random class gives you a Vector2 in the given x & y ranges with another extension for NextFloat

public static Vector2 NextVector2(this Random rand, float minX, float maxX,float minY, float maxY)  
{  
    return new Vector2(rand.NextFloat(minX, maxX), rand.NextFloat(minY, maxY));  
}  
  
public static float NextFloat(this Random rand, float minValue, float maxValue)  
{  
    return (float)rand.NextDouble() * (maxValue - minValue) + minValue;  
}

GetRandomColor

Get a random predefined colour from the MonoGame Color class properties.

public static Color GetRandomColor()  
{  
    // Get all static properties of the Color class that return Color  
    var colorProperties = typeof(Color)  
        .GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)  
        .Where(p => p.PropertyType == typeof(Color))  
        .ToArray();  
  
    var randomIndex = Random.Shared.Next(colorProperties.Length);  
    return (Color)colorProperties[randomIndex].GetValue(null)!;  
}

DrawLine

This one came from the MonoGame.Samples NeoShooter. I added it to my SpriteBatchExtended which I inherit from SpriteBatch so Draw is a local method call.

public void DrawLine(Vector2 start, Vector2 end, Color color, float thickness = 2f)  
{
    var delta = end - start;  
    Draw(  
        _blankTexture,   
        start,
        null,   
        color,   
        delta.ToAngle(),
        new Vector2(0, 0.5f),
        new Vector2(delta.Length(), thickness),
        SpriteEffects.None,
        0f);  
}

You will need a _blankTexture which you can make by:-

// class private
private Texture2D _blankTexture;

public void Initialize()  
{  
    // ...
  
    _blankTexture = new Texture2D(game.GraphicsDevice, 1, 1);  
    _blankTexture.SetData([Color.White]);  
    
    // ...
}

DrawBox

Once you have the _blankTexture you might as well have a Draw Box method

public void DrawBox(Rectangle destinationRectangle, Color color)  
{  
    Draw(_blankTexture, destinationRectangle, color);  
}

Drawable Game Component (FPS)

And something everybody needs 😁

using System;  
using Microsoft.Xna.Framework;  
using Microsoft.Xna.Framework.Graphics;  
  
namespace game001.DrawableGameComponents;  
  
public class Fps(Game game, SpriteFont spriteFont, Vector2 position ) : DrawableGameComponent(game)  
{  
    private readonly SpriteBatch _sb = new(game.GraphicsDevice);  
  
    private int _frameRate;  
    private int _frameCounter;  
    private TimeSpan _elapsedTime = TimeSpan.Zero;  
  
    public override void Update(GameTime gameTime)  
    {
        _elapsedTime += gameTime.ElapsedGameTime;  
  
        if (_elapsedTime <= TimeSpan.FromSeconds(1))
            return;
            
        _elapsedTime -= TimeSpan.FromSeconds(1);  
        _frameRate = _frameCounter;  
        _frameCounter = 0;  
    }  
  
    public override void Draw(GameTime gameTime)  
    {
        _frameCounter++;  
  
        _sb.Begin();  
        _sb.DrawString(spriteFont, $"FPS: {_frameRate}", position, Color.Black);  
        _sb.End();  
    }  
}

Well that's it for my productive Game Development weekend. 🤓

Comments

Leave a comment by replying to this post on Mastodon.

Loading comments...