Welcome to PACMAN written in C# and running on Blazor WebAssembly.
This is a project I started in order to expirement with Blazor/WebAssembly. I wanted to see it was feasible to use Blazor to write a game in C# that runs at 60FPS.
The answer is mostly YES.
Although care was needed with heap allocations in the main game-loop (which has to take less than 16 milliseconds)
The game basically manipulates the HTML 5 canvas from C# code via the interop provided by Blazor.
How does it interactive with the canvas?
It uses the .NET NuGet package
What are the dimensions of the canvas?
All drawing is done as on 224x314 canvas. This is upscaled by 3x3 (672/944) 672/944 is a 0.711 aspect ratio
How does sound work?
It uses Howler.
sound.js is loaded and exposes
SoundPlayer. In the C# code,
GameSoundPlayer loads the sound effects via
SoundLounder which interact with Howler via
Each sound in C# is represented by
SoundEffect which again uses
IJSRuntime to call methods on the JS
When a sound has stopped playing, our
end event on Howler calls back into the C# code.
This is needed to loop things like the sirens and other long playing effects.
How does touch / swipe / pan work?
It uses Hammer.js.
What happens when the game first starts?
First, we override
index.blazor (which is the Blazor class that derives from
In this method, we initialise the C# world and then call
setDrawCallback in the JS code.
setDrawCallback does these things:
- initialises Hammer for input
- registers for
window; the events are fed through to the C# code
window; every frame it then calls the C# code
Then, bacl in Blazor, we override
OnAfterRenderAsync and initialise the canvases. There are 3 canvases used, one is the output canvas that we draw on, and the other two are canvases for each player's maze (it's a one or two player game).
What happens when the game runs
In JS, at startup, we called
requestAnimationFrame. This means that every frame (60 per second), a JS method is called and that method calls the C# code. The C# code