Skip to content

Latest commit

 

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EscapeGame

A 2D platformer / parkour game built from scratch with Python and Pygame, featuring responsive movement, double jumping, dashing, hazards, collectibles, animated environments, persistent progression, and a modular game architecture.

The objective is simple:

Navigate each level, survive the obstacles, collect items, and reach the exit.

Behind the gameplay, EscapeGame is also an exploration of practical game-engine concepts such as collision broad-phase optimization, entity management, camera systems, state-driven menus, persistent configuration, animation, and executable packaging.


Overview

EscapeGame is a custom 2D platformer implemented without a full game engine.

The project handles its own:

  • Player physics and movement
  • Collision detection
  • Spatial partitioning
  • Level parsing
  • Entity lifecycle
  • Camera tracking
  • Animation states
  • Audio management
  • Menu navigation
  • Player progression
  • Runtime configuration
  • HUD rendering
  • Game-over / victory states
  • Standalone application builds

The game currently contains 2 playable levels stored as text-based map definitions.


Gameplay

Your goal is to make your way through each level and reach the exit while dealing with environmental hazards and enemy abilities.

Player Abilities

Movement

Move horizontally through the level while the camera follows the player.

Jump

Perform a standard jump from the ground.

Double Jump

Jump once more while airborne to recover from mistakes or reach higher platforms.

Dash

Perform a high-speed horizontal dash.

Dash uses a cooldown system and is displayed directly on the HUD.

Health

The player has a health system and can take damage from hazards.

Falling outside the playable world or losing all HP results in death.


Controls

Key Action
← Move left
→ Move right
↑ Jump / Double Jump
G Dash
Esc Return to previous menu

Development builds also contain internal debug controls for testing status effects.


Entities & Hazards

Collectibles

Coin

Collectible currency scattered throughout the levels.

Diamond

A separate collectible tracked by the gameplay HUD.

Heart

Restores a randomized amount of HP, up to the player's maximum health.

Hazards

GrassCutter

A moving/spinning environmental hazard that damages the player on contact.

SnowEater

A passive enemy with an area-based ability. Getting too close allows it to temporarily freeze the player, preventing movement.

Moving Platforms

Dynamic platforms that participate in the game's collision system and level traversal.


Game Systems

Player Physics

The player controller implements:

  • Horizontal movement
  • Gravity
  • Ground detection
  • Jumping
  • Air jumping
  • Dash movement
  • Dash cooldowns
  • Direction tracking
  • Character animation states
  • Collision resolution
  • HP and death state
  • Collectible interaction
  • Enemy interaction
  • Win-condition detection

Movement parameters are centralized in the runtime configuration, making gameplay behavior easy to tune.


Collision Optimization

Instead of testing the player against every object in the level every frame, EscapeGame implements a spatial hash grid.

The world is divided into spatial cells, allowing the collision system to retrieve only nearby collision candidates.

Conceptually:

World
 ├── Cell (0, 0)
 │    ├── Wall
 │    └── Platform
 │
 ├── Cell (1, 0)
 │    └── Wall
 │
 └── Cell (2, 0)
      ├── Hazard
      └── Platform

The collision layer supports both:

Static geometry
        +
Dynamic obstacles
        ↓
CollisionSpace
        ↓
Nearby collision candidates
        ↓
Player collision resolution

This keeps the architecture scalable as map complexity increases.


Level System

Levels are stored under:

assets/levels/

Current maps:

level_1.txt
level_2.txt

MapManager parses these text maps and converts symbols into game objects such as:

Tiles
Walls
Terrain
Player spawn
Exit
Coins
Diamonds
Hearts
Enemies
Moving platforms

This separates level design from gameplay logic, allowing maps to be modified without rewriting the game loop.


Entity Architecture

Game objects are separated into dedicated entity modules.

src/entities/
├── entity.py
├── player.py
├── coin.py
├── diamond.py
├── heart.py
├── grass_cutter.py
├── snow_eater.py
└── moving_platform.py

Each entity is responsible for its own behavior while shared functionality is handled through the base entity architecture.


Status Effects

The game contains a reusable effect system.

Currently implemented:

FreezeEffect
BlindEffect

For example, SnowEater can trigger FreezeEffect, temporarily preventing player input.

Effect logic is isolated under:

src/effect/

which makes additional status effects easier to introduce.


Camera System

The game uses a dedicated camera module rather than coupling world coordinates directly to screen coordinates.

The camera tracks the player's world position and converts game-world coordinates into screen-space coordinates during rendering.

This allows maps to extend beyond the visible 1280 × 720 viewport.


Menu State System

Game screens are managed by a reusable MenuManager.

Current states include:

MENU
├── PLAYING
│   ├── DIE
│   └── WIN
│
├── SETTINGS
│
└── HELP
    ├── ITEMS
    └── MOBS

This keeps state transitions separate from the main game loop.


HUD

The gameplay HUD displays important runtime information including:

  • Player HP
  • Dash cooldown
  • Coin count
  • Diamond count
  • FPS

The dash meter visually communicates when the player's dash becomes available again.


Persistent Configuration

EscapeGame includes a configuration manager for saving runtime settings and player progress.

Configuration values include areas such as:

Display
World
Player
Dash
Entities
Audio
Progress

The default game configuration is defined centrally in:

src/config.py

while persistent player data is stored under:

assets/player/

Audio

The game contains separate audio handling for music and sound effects.

Examples include:

Menu music
Level music
Jump sound
Dash sound
Coin collection sound

Audio volume can be controlled through the game configuration/settings system.


Project Structure

EscapeGame/
│
├── assets/
│   ├── entities/
│   ├── images/
│   ├── levels/
│   │   ├── level_1.txt
│   │   └── level_2.txt
│   ├── player/
│   ├── skills/
│   ├── sound/
│   └── texture/
│
├── src/
│   ├── effect/
│   │   ├── blind_effect.py
│   │   └── freeze_effect.py
│   │
│   ├── entities/
│   │   ├── coin.py
│   │   ├── diamond.py
│   │   ├── entity.py
│   │   ├── grass_cutter.py
│   │   ├── heart.py
│   │   ├── moving_platform.py
│   │   ├── player.py
│   │   └── snow_eater.py
│   │
│   ├── menu/
│   │   ├── encyclopedia_menu.py
│   │   ├── game_over_menu.py
│   │   ├── help_menu.py
│   │   ├── main_menu.py
│   │   ├── menu_manager.py
│   │   ├── play_menu.py
│   │   ├── settings_menu.py
│   │   └── win_menu.py
│   │
│   ├── world/
│   │   ├── camera.py
│   │   ├── map_manager.py
│   │   └── spatial_hash_grid.py
│   │
│   ├── audio.py
│   ├── config.py
│   ├── game_types.py
│   ├── hash_table.py
│   ├── texture_loader.py
│   └── utils.py
│
├── main.py
├── Makefile
├── build_windows.bat
├── requirements.txt
└── README.md

Tech Stack

Technology Purpose
Python Core game logic
Pygame Rendering, input, audio and game loop
NumPy Numerical utilities
PyTMX TMX-related map tooling dependency
PyInstaller Standalone executable packaging
Pytest Testing infrastructure
Make Development/build automation

Getting Started

1. Clone the Repository

git clone https://github.com/RyouLegacy/EscapeGame.git
cd EscapeGame

2. Run with Make

The Makefile automatically creates an isolated virtual environment and installs the required dependencies.

make run

That will:

Create ./venv if necessary
        ↓
Install requirements.txt
        ↓
Validate the environment
        ↓
Launch main.py

Manual Installation

If you prefer not to use make:

Create a virtual environment

python -m venv venv

Activate it

Windows:

venv\Scripts\activate

Linux/macOS:

source venv/bin/activate

Install dependencies

pip install -r requirements.txt

Run the game

python main.py

Dependencies

The project currently uses:

pygame >= 2.5.2
numpy >= 1.26.0
pytmx >= 3.32
pytest >= 8.0.0
pyinstaller >= 6.4.0

Building a Standalone Executable

Using Make

make build

The Makefile uses PyInstaller and packages the game into:

dist/

Windows Build Script

Windows users can also run:

build_windows.bat

The script:

Checks Python
    ↓
Uses the virtual environment when available
    ↓
Updates PyInstaller
    ↓
Removes previous build output
    ↓
Builds EscapeGame.exe
    ↓
Copies game assets
    ↓
Outputs the distributable build

Result:

dist/
├── EscapeGame.exe
└── assets/

Development Commands

make help

Show available development commands.

make run

Create the environment if necessary, install dependencies, and start the game.

make build

Package the game using PyInstaller.

make clean

Remove generated environments, build artifacts, caches, compiled Python files, and PyInstaller output.


Architecture

At a high level:

main.py
   │
   ▼
MenuManager
   │
   ├───────────────┐
   ▼               ▼
Main Menu      PlayMenu
                   │
          ┌────────┼────────┐
          ▼        ▼        ▼
       Player   MapManager  Camera
          │        │
          │        ├── Level Parser
          │        ├── Tiles
          │        ├── Entities
          │        └── Collision Grid
          │
          ├── Movement
          ├── Physics
          ├── Dash
          ├── Effects
          ├── Items
          └── Hazards

The main loop remains relatively small because gameplay responsibilities are delegated to dedicated components.


Design Decisions

Why text-based levels?

Text-based maps make level layouts:

  • Easy to inspect
  • Easy to modify
  • Version-control friendly
  • Independent from Python gameplay code

Why spatial hashing?

Naive collision detection can approach:

Player × every collider

for every update.

Spatial hashing reduces the candidate set to objects occupying nearby world cells before precise rectangle collision checks are performed.

Why separate menu states?

Keeping menu screens isolated avoids turning main.py into a large conditional state machine and makes additional screens easier to add.

Why central configuration?

Physics values such as:

PLAYER_SPEED
PLAYER_JUMP_POWER
DASH_SPEED
DASH_COOLDOWN_MS
GRAVITY

can be tuned without modifying the underlying movement algorithms.


Current Gameplay Notes

Double Jump

The second jump is treated as an air jump and becomes available again after the player lands.

Dash

Dash behavior depends on:

DASH_SPEED
DASH_DURATION_MS
DASH_COOLDOWN_MS

The HUD shows dash recharge progress so the player can see when the ability becomes available.


Possible Future Improvements

Potential extensions to the project include:

More handcrafted levels
Level-selection screen
Checkpoint system
Additional enemies
Additional player abilities
Boss encounters
Controller support
Save slots
Improved automated testing
External level editor
Particle system
Performance profiling
CI build pipeline
Release packages

What This Project Demonstrates

EscapeGame is not only a gameplay project. It demonstrates several software-engineering concepts applied to game development:

Object-oriented game architecture
State management
Real-time update loops
Collision broad-phase optimization
Custom spatial data structures
2D physics
Camera transforms
Persistent configuration
Asset management
Entity lifecycle management
Modular UI architecture
Executable packaging

Contributing

Contributions and experimentation are welcome.

A typical workflow:

git clone https://github.com/RyouLegacy/EscapeGame.git
cd EscapeGame

git checkout -b feature/my-feature

# Make your changes

git add .
git commit -m "Add my feature"
git push origin feature/my-feature

Then open a pull request describing:

What changed
Why it changed
How it was tested
Any gameplay/configuration impact

Author

RyouLegacy

GitHub: @RyouLegacy


License

No license is currently specified in this repository.

Unless a license is added, the source code should not be assumed to grant permission for redistribution, modification, or commercial use.


Acknowledgements

Built with Python, Pygame, and a lot of platforming experiments.

If you find the project interesting, consider leaving a ⭐ on the repository.

About

My first every game which is built by PyGame engine in Python

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages