Pewnego dnia postanowiłem napisać grę. Nie w Unity, nie w Godot, nie w Unreal — w czystym C#. Dlaczego? Bo jestem masochistą z dyplomem i chciałem wiedzieć, co tak naprawdę kryje się pod spodem każdego „przeciągnij sprite’a tutaj”.
Efekt? MathNerd — platformówka w stylu Mario, gdzie nerdziak w okularach i muszce musi pokonywać dresiarzy, rozwiązując zadania matematyczne. Tak, to gra edukacyjna. Nie, nie jestem z tego dumny. Tak, jest śmieszna.
Czym jest MonoGame?
MonoGame to open-source’owy framework do gier 2D/3D dla .NET — de facto następca XNA Microsoftu. Daje ci:
- SpriteBatch do rysowania
- Content Pipeline do zarządzania assetami (fonty, tekstury, dźwięki)
- GameWindow, wejście z klawiatury/pada, zarządzanie pętlą gry
Czego nie daje: scen, komponentów, edytorów, asystentu AI, ani ręki do trzymania. To ty i Update(GameTime).
Jak to działa — architektura w 5 minutach
Cała gra żyje w kilku plikach .cs:
scripts/ ├── Player.cs — nerd z okularami (pixel art z prostokątów) ├── Enemy.cs — dresiak ze snapbackiem (też pixel art) ├── Level.cs — platformy, bloki, wrogowie ├── Physics.cs — AABB, grawitacja ├── MathPopup.cs — popup z pytaniem matematycznym + timer ├── MathChallengeManager.cs — generator pytań ├── HUD.cs — życia (serduszka), wynik, prowokacje └── Camera.cs — scrolling poziomy
Nie ma tutaj żadnej magii. Jeden Texture2D o wymiarach 1×1 piksel, biały, i SpriteBatch.Draw(pixel, rect, color) — cała grafika to kolorowe prostokąty. Poważnie.
Pixel art bez obrazków
void D(int dx, int dy, int w, int h, Color c) =>
sb.Draw(pixel, new Rectangle(bx + dx, by + dy, w, h), c);
// Twarz nerdziaka
D( 5, 4, 22, 18, skin); // twarz
D( 3, 12, 12, 9, frm); // lewa oprawka okularów
D( 4, 13, 10, 7, lens); // lewy obiektyw
D( 6, 15, 4, 3, pup); // źrenica
Wynik: postać z okularami, muszką i niebieskimi ogrodniczkami. Nie jest to Ori and the Blind Forest, ale ma swój urok.
Fizykalność bez silnika
// Oś X pos.X += vel.X * dt; // Rozwiąż kolizje... // Oś Y pos.Y += vel.Y * dt; // Rozwiąż kolizje... (tutaj ustawiamy onGround = true)
Separacja osi X i Y to klasyczna technika AABB. Bez niej postać zacinałaby się w narożnikach platform jak twój kuzyn na rodzinnym obiedzie.
Pytania matematyczne
Kiedy gracz doskakuje na dresiarza, pojawia się popup:
=== MATH CHALLENGE === [ Algebra - face your destiny, mortal ] ALGEBRA! The final boss of elementary school! 3x + 5 = 23 What is x? [ _______________________ ] Brain cells: [###] ████████████░░░ 12s
Masz 15 sekund i 3 próby. Jak nie zdążysz, dresiak wygrywa i tracisz życie. Matematyka boli podwójnie.
Coyote time i jump buffer
Dwa narzędzia każdego szanującego się platformera:
- Coyote time (0.10s) — możesz skakać chwilę po tym, jak zejdziesz z platformy. Bo gracze są ludźmi, nie robotami.
- Jump buffer (0.12s) — przytrzymanie skoku przed lądowaniem rejestruje skok. Eliminuje frustrację „przyszedłem za wcześnie”.
if (_jumpBufferTimer > 0 && _coyoteTimer > 0)
{
Velocity.Y = JumpVel;
_jumpBufferTimer = 0;
_coyoteTimer = 0;
}
Wynik i jak go uruchomić
Repozytorium: github.com/letyshub/MathNerd
git clone https://github.com/letyshub/MathNerd cd MathNerd dotnet tool restore # instaluje dotnet-mgcb dotnet run
Wymagania: .NET 8 SDK. Brak Unity Hub, brak launcharów, brak 40 GB pobierania. Przyjemna odmiana.
Wnioski
MonoGame to nie silnik — to framework. Nie zrobi za ciebie nic, ale nie ograniczy cię też w niczym. Idealny jeśli:
- Chcesz zrozumieć jak gry działają od środka
- Lubisz C# i nie chcesz uczyć się nowego języka skryptowania
- Tworzysz małą grę 2D bez potrzeby edytora poziomów
- Masz zbyt dużo czasu i za mało snu
Jeśli oczekujesz klikania myszką i gotowych shaderów — wróć do Unity. Jeśli lubisz ref Vector2 i debugowanie kolizji o 2 w nocy — MonoGame czeka.


