Tiny Game Engine Stuff
trying to write something neat in c#
No matter what I code nowadays, it's always inspired by the simplicity that is NancyFX. Thus, I focus on the end-user code, when ever I write a library.
Here's a tiny Demo of a c#-Engine, written in a way that any platform and any graphics library could render it. In my case, I use SharpDX for the 'rendering' (for the demo, only single-colored screens).
namespace Demo;
using System;
using Game;
class Program
{
public static void Main(string[] args)
{
SharpDXImplementation.Engine.Run(new Configuration
{
Title = "Far Off Wanderer",
Width = 1280,
Height = 720,
FirstScene = new StartupScreen()
});
}
}
class StartupScreen : Scene
{
public override GameState Update(KeyboardState keyboardState, TimeSpan timeSpan) => new GameState
{
NextScene = keyboardState.Space ? new TitleScreen(previous: this) : null,
Active = keyboardState.Escape == false,
View = new View
{
Color = Color.OrangeRed
}
};
}
class TitleScreen : Scene
{
Scene previous;
public TitleScreen(Scene previous)
{
this.previous = previous;
}
public override GameState Update(KeyboardState keyboard, TimeSpan timeSpan) => new GameState
{
NextScene = keyboard.Escape ? previous : null,
Active = true,
View = new View
{
Color = Color.PowderBlue
}
};
}
To make it work, I wrote some useful types inside the namespace Game (simple namings make life simple). All those types should be immutable, but aren't. Because I'm lazy. They will be, though, at some point.
namespace Game;
using System;
class Configuration
{
public string Title { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public Scene FirstScene { get; set; }
}
class GameState
{
public bool Active { get; set; }
public Scene NextScene { get; set; }
public View View { get; set; }
}
class KeyboardState
{
public bool Escape { get; set; }
public bool Left { get; set; }
public bool Right { get; set; }
public bool Up { get; set; }
public bool Down { get; set; }
public bool Space { get; set; }
}
abstract class Scene
{
public abstract GameState Update(KeyboardState keyboardState, TimeSpan timeSpan);
}
class View
{
public Color Color { get; set; }
}
struct Color
{
public float Red;
public float Green;
public float Blue;
static public Color OrangeRed { get; } = new Color { Red = 0.75f, Green = 0.25f, Blue = 0 };
static public Color PowderBlue { get; } = new Color { Red = 0.25f, Green = 0.5f, Blue = .75f };
}
To make the back-end 'engine', I use SharpDX.Toolkit. It's XNA-Like, and allows me to set up everything rather quickly.
namespace SharpDXImplementation;
using Game;
using DX = SharpDX.Toolkit;
class Engine : DX.Game
{
Configuration configuration;
Scene scene;
View view;
DX.Input.KeyboardManager keyboardManager;
private Engine(Configuration configuration)
{
this.configuration = configuration;
this.scene = configuration.FirstScene;
this.keyboardManager = new DX.Input.KeyboardManager(this);
new DX.GraphicsDeviceManager(this)
{
PreferredBackBufferWidth = configuration.Width,
PreferredBackBufferHeight = configuration.Height
};
}
public static void Run(Configuration configuration)
{
var sharpDXEngine = new Engine(configuration);
sharpDXEngine.Run();
}
protected override void Initialize() => Window.Title = configuration.Title;
protected override void Update(DX.GameTime gameTime)
{
keyboardManager.Update(gameTime);
var _keyboardState = keyboardManager.GetState();
var keyboardState = new KeyboardState()
{
Escape = _keyboardState.IsKeyPressed(DX.Input.Keys.Escape),
Space = _keyboardState.IsKeyPressed(DX.Input.Keys.Space),
Left = _keyboardState.IsKeyPressed(DX.Input.Keys.Left),
Right = _keyboardState.IsKeyPressed(DX.Input.Keys.Right),
Up = _keyboardState.IsKeyPressed(DX.Input.Keys.Up),
Down = _keyboardState.IsKeyPressed(DX.Input.Keys.Down)
};
var state = scene.Update(keyboardState, gameTime.TotalGameTime);
scene = state.NextScene ?? scene;
this.view = state.View;
if (state.Active == false)
{
Exit();
}
}
protected override void Draw(DX.GameTime gameTime)
{
if(view != null)
{
GraphicsDevice.Clear(view.Color.AsSharpDX());
}
}
}
static class Helpers
{
public static SharpDX.Color AsSharpDX(this Color color) => new SharpDX.Color(color.Red, color.Green, color.Blue);
}
All in all, not much to see.
So.. any questions? ☺