DASH is a Geometry Dash inspired 2D platformer built in C++ with SplashKit. You guide a block through scrolling levels, timing jumps over spikes and blocks across three difficulties — each loaded from its own custom level file. Choose from five hand-drawn block styles, watch your progress along a live bar as you go, and save your best run to a local leaderboard. Built as the final project of my first year of Computer Science.
I grew up playing Geometry Dash, so building my own version was the first time my skills caught up to something I actually love as a player. Every part of it is mine — the level file format, the five block styles (hand-drawn on my iPad, then redrawn in code), the leaderboard. Partway through, I stopped and rewrote a working 500-line single file into a proper multi-file architecture, because I could tell "it works" wasn't the same as "it's built right." That rewrite taught me more than any single feature did.
- The game opens to a menu showing the live date and time; you pick a difficulty — Easy, Medium, or Hard.
- Press S to open the style selector and choose one of five block styles before you play.
- In a level, your block holds a fixed position on the left while the world scrolls past; space makes it jump, and gravity pulls it back down.
- A progress bar tracks how far through the level you are. Touch an obstacle and it's game over; clear every obstacle and you win.
- On a win, you enter your name and your score is saved. Press L any time to view the leaderboard — the top three scores for each difficulty.
| Input | Action |
|---|---|
| 1 / 2 / 3 | Start Easy / Medium / Hard |
| S | Open the block style selector |
| L | View the leaderboard |
| Space | Jump |
| Enter | Save your score (win) or play again (game over) |
| Q | Quit, or go back from a screen |
| Close window | Quit |
- Abstract base class and polymorphism —
playeris an abstract class with a pure virtualdraw(); the five styles are derived classes that each override it. The game holds aplayer*and swaps the concrete block at runtime withnew/deleteand a virtual destructor. - A custom level format with file I/O — levels are plain-text files parsed line by line with
<fstream>, in a format I designed from scratch (SPEED,BG_COLOR,OBSTACLE). - SplashKit Interface — buttons, a text box, and scaled bitmaps drive the style selector, the leaderboard's difficulty switch, and the name-entry screen.
- Local leaderboard with persistence — reads and writes a scores file per difficulty, keeps each player's highest score, and timestamps entries using
<ctime>. - A state machine — seven states (menu, style select, playing, dead, win, leaderboard, quit) keep every screen and transition clean.
Each difficulty is a plain-text file in Resources/levels/, read line by line as
the level loads. The format is my own design — three kinds of line:
| Line | Meaning |
|---|---|
SPEED <n> |
The scroll speed the level starts at |
BG_COLOR <name> |
The background colour |
OBSTACLE <TYPE> <x> <y> |
Place an obstacle of <TYPE> at position (x, y) |
A short example:
SPEED 4
BG_COLOR DARK_BLUE
OBSTACLE SPIKE 1300 550
OBSTACLE BLOCK 1800 540
Obstacle types: SPIKE, DOUBLE_SPIKE, BLOCK, TALL_BLOCK, CEILING_SPIKE.
Background colours: DARK_BLUE, DARK_GREEN, DARK_VIOLET, BLACK, PURPLE,
DARK_RED. Anything the loader doesn't recognise falls back to a sensible default,
so a malformed line won't crash the game.
The menu, with the live date and time:
The block style selector — five styles to choose from:
The leaderboard, top three per difficulty:
I planned DASH before writing it. The final build follows this class structure:
And the very first idea — my hand-drawn sketch of the blocks, obstacles, and game window, beside how it actually shipped:
| My original sketch | The shipped game |
|---|---|
![]() |
![]() |
The game is split across multiple files, each class in its own header and source pair, following a driver → manager → objects design:
| File | Responsibility |
|---|---|
dash_driver.cpp |
Entry point — launches the game manager |
dash_manager.cpp / .h |
Master controller — owns every object, runs the state machine and every screen |
player.cpp / .h |
Abstract base block — gravity, jump, collision, and a pure virtual draw() |
classic_dash, ghost_dash, robot_dash, ufo_dash, puzzle_dash |
The five block styles, each a derived class overriding draw() |
obstacle.cpp / .h |
A single obstacle — shape, position, collision box |
level.cpp / .h |
A level — its obstacles, scrolling, and win detection |
level_loader.cpp / .h |
Reads a level file and builds a level |
leaderboard.cpp / .h |
Reads, writes, and displays per-difficulty scores |
constants.h |
Shared constants and includes |
utilities.cpp / .h |
Small terminal-input helpers |
Resources/ |
Level files, block style images, and leaderboard scores |
screenshots/ |
Screen captures used in this README |
design/ |
The UML class diagram and original design sketch |
The game was built as a series of commits, each adding one idea on top of the last:
- First working build — a cube that jumps with gravity, with the first obstacles drawn on screen.
- Scrolling and collision — obstacles rush in and scroll past, hitting one ends the run, and the pace ramps up the longer you last.
- Levels from files — three difficulties load from custom text files, each with its own layout, speed, and colour, and clearing a level wins the run.
- Multi-file refactor and in-game menu — the whole game restructured from one file into a class-per-file architecture with a driver, a game manager, and a state machine, and difficulty selection moved into an in-window menu.
- Styles, leaderboard, and polish — an abstract player with five selectable styles and true polymorphism, a SplashKit Interface style selector, a live progress bar and menu clock, and a local leaderboard that saves your best runs.
- C++
- SplashKit — used for the window, drawing, keyboard input, the interface widgets, and bitmaps
You'll need SplashKit installed. From inside this folder, compile the game:
skm clang++ dash_driver.cpp dash_manager.cpp player.cpp classic_dash.cpp ghost_dash.cpp robot_dash.cpp ufo_dash.cpp puzzle_dash.cpp obstacle.cpp level.cpp level_loader.cpp leaderboard.cpp utilities.cpp -o dashThen run it:
./dashOn Windows or Linux you may use
skm g++instead ofskm clang++.






