Skip to content

Repository files navigation

Joystick.NET logo

Joystick.NET

Pong, Breakout and Space Invaders on a shared C#/MonoGame core.

One solution, three games, no game assets: sprites are pixel patterns in source, text comes from a 5x7 glyph table, and every sound is a square wave or noise burst synthesized at load. .NET 8, MonoGame DesktopGL, runs on Windows, Linux and macOS.

Pong Breakout Space Invaders
Pong Breakout Space Invaders

Build and run

dotnet build
dotnet run --project src/AtariClassics.Pong
dotnet run --project src/AtariClassics.Breakout
dotnet run --project src/AtariClassics.SpaceInvaders
dotnet test

Controls

Menus: up/down select, enter confirms, esc backs out. P or esc pauses in game.

Game Move Action
Pong W/S or up/down
Breakout A/D or left/right space launches
Space Invaders A/D or left/right space fires

The games

Pong: first to 11 against the machine. The ball leaves the paddle at an angle picked by where you catch it and gains speed with every return. The cpu paddle is capped slower than yours and only rethinks its target a few times a second, so it can be beaten.

Breakout: 8x5 wall, top rows pay 9 down to 1. The ball speeds up as the wall thins. Three balls, clear everything to win.

Space Invaders: the 5x11 flock steps as one and drops at the edges, faster as it shrinks. One shell in the air at a time, three shields that shots and aliens both chew away, a mystery ufo now and then, and every cleared wave restarts one row lower.

Architecture

AtariClassics.Core
|- Collision    RectF, swept aabb cast (tunneling-proof), paddle bounce math
|- Scenes       IGameScene, SceneManager stack, shared menu/pause/game over
|- Input        GameKey behind IInputProvider, keyboard impl
|- Graphics     5x7 pixel font, pattern grids -> textures
|- Audio        square/noise synth, manager that goes mute without a device
|- Entities     Paddle, Ball, IUpdatable/IRenderable
`- Persistence  per-game high score json

AtariClassics.Pong ----------+
AtariClassics.Breakout ------+--- scenes and rules only, the rest lives in Core
AtariClassics.SpaceInvaders -+

tests/AtariClassics.Tests    xunit over the logic above
build/AppBundler             publishes and wraps the games into mac .app bundles

Games run a fixed 60 Hz step with dt-based movement. Collision is swept aabb (slab method), so a fast ball hits the first surface on its path instead of teleporting through it. Every game accepts --smoke [frames] and exits by itself after that many steps, which is how CI boots all three under xvfb.

macOS bundles

The macos-app workflow (Actions tab, run it manually) publishes all three games self-contained for arm64 and x64 and wraps them into ad-hoc-signed .app bundles; grab the zips from the run artifacts. First launch needs right-click and Open since the apps are not notarized. The same run starts each packaged app with --screenshot to regenerate the captures above.

The same tool runs locally:

dotnet run --project build/AppBundler -- --game pong --rid osx-arm64

High scores

Breakout and Space Invaders keep one number each under ~/.config/JoystickNET (%APPDATA%\JoystickNET on Windows), written async on game over and shown in the menus.

About

Pong, Breakout and Space Invaders on a shared C#/MonoGame core

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages