Cosmic Candy Pinball: procedural 8-bit pinball game
Native pygame-ce game with fully procedural pixel art and chiptune audio (no asset files). Pure-logic physics module with flipper angular momentum, plus headless autoplay/screenshot/probe dev tools.
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# 🍬 Cosmic Candy Pinball
|
||||
|
||||
A cute, 8-bit, pixel-art **pinball** game, written from scratch in Python with
|
||||
[pygame-ce](https://pygame.org). 100% procedural — there are **no image or
|
||||
audio asset files**: every sprite, texture, particle, chiptune and sound
|
||||
effect is generated by code at runtime.
|
||||
|
||||
Not web-based: it opens its own native window and renders on a low-res
|
||||
`480×360` virtual canvas, upscaled with crisp nearest-neighbour scaling for an
|
||||
authentic retro look.
|
||||
|
||||

|
||||
|
||||
## Running it
|
||||
|
||||
Fastest (uv, already used in this project):
|
||||
|
||||
```bash
|
||||
uv venv .venv --python 3.12 # once
|
||||
uv pip install --python .venv/bin/python -r requirements.txt # once
|
||||
.venv/bin/python main.py
|
||||
```
|
||||
|
||||
Or with plain venv + pip (Python 3.10+):
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
.venv/bin/pip install -r requirements.txt
|
||||
.venv/bin/python main.py
|
||||
```
|
||||
|
||||
> Note: the dependency is **`pygame-ce`**, not `pygame` (the community edition
|
||||
> supports newer Python versions and is what this was built against).
|
||||
|
||||
## Controls
|
||||
|
||||
| Key | Action |
|
||||
| --- | --- |
|
||||
| `←` `→` (or `Z` / `/`) | Flippers |
|
||||
| hold `Space` / `↑` | Charge the **Candy Cannon** — release to fire |
|
||||
| `M` | Mute |
|
||||
| `P` | Pause |
|
||||
| `R` | Restart game |
|
||||
| `Esc` | Quit |
|
||||
| `Enter` | Start / play again |
|
||||
|
||||
## How to play
|
||||
|
||||
- Light the **3 star lanes** up top → **CANDY FEVER!** (double points for
|
||||
20s — keep hitting stars to extend it).
|
||||
- Bounce off the three kawaii candy bumpers and the two slingshots. Every hit
|
||||
inside 2.5s builds your **combo multiplier** (up to ×9).
|
||||
- Watch the bottom-centre drain and the two outlanes… or lose the ball.
|
||||
- Every **50,000 points** earns an extra ball.
|
||||
- Squirrel says encouraging things. Blush at the cat in the corner.
|
||||
|
||||
## Project layout
|
||||
|
||||
| file | purpose |
|
||||
| --- | --- |
|
||||
| `main.py` | entry point / main loop |
|
||||
| `game.py` | game states, scoring, juice, all rendering (pixel art) |
|
||||
| `physics.py` | pure pinball physics (flippers, bumpers, slingshots, drains) — no rendering |
|
||||
| `font.py` | hand-made 5×5 pixel bitmap font |
|
||||
| `sfx.py` | procedural chiptune + music synthesis (pure code, no samples) |
|
||||
| `highscore.json` | best score (written at game over) |
|
||||
|
||||
Dev / test tools (run headless, no window needed):
|
||||
|
||||
```bash
|
||||
.venv/bin/python autotest.py 40000 # auto-playing bot, prints game-health stats
|
||||
.venv/bin/python runtest.py 900 # simulated session incl. rendering
|
||||
.venv/bin/python shots.py shots # dumps screenshots of every state
|
||||
.venv/bin/python probe.py # pixel-probes the rendered layout
|
||||
```
|
||||
|
||||
## Design notes
|
||||
|
||||
- **Physics**: fixed 60 Hz logic with up to 6 collision substeps so the ball
|
||||
never tunnels; kinematic flippers whose angular velocity is transferred to
|
||||
the ball (real "scoop" feel); inward-tilting floor funnels; centre drain +
|
||||
guarded outlanes; a softlock rescue nudge if a ball ever parks too long.
|
||||
- **Fun tuning was data-driven**: an `autotest.py` bot plays thousands of
|
||||
frames and reports hit/drain rates per table element, so bumper, slingshot
|
||||
and flipper geometry was tuned against measured behaviour, not guesswork.
|
||||
- **Audio**: square/triangle/noise oscillators -> PCM at startup; distinct
|
||||
pitched bump sounds that climb with your combo, plus two generative music
|
||||
loops (menu + play).
|
||||
|
||||
Licence: MIT — go wild.
|
||||
Reference in New Issue
Block a user