diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..b2e4c11
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,19 @@
+root = true
+
+[*]
+charset = utf-8
+end_of_line = lf
+insert_final_newline = true
+trim_trailing_whitespace = true
+indent_style = space
+indent_size = 4
+
+[*.{yml,yaml,toml,json}]
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
+
+[*.dat]
+end_of_line = lf
+trim_trailing_whitespace = false
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..c046c8f
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,26 @@
+# Normalize line endings: treat everything as text with LF in the repo, but let
+# Git auto-detect binary files so it never mangles them.
+* text=auto eol=lf
+
+# Source and data files are always LF.
+*.py text eol=lf
+*.dat text eol=lf
+*.cfg text eol=lf
+*.toml text eol=lf
+*.md text eol=lf
+*.yml text eol=lf
+*.yaml text eol=lf
+
+# Binary assets — never touch these.
+*.png binary
+*.jpg binary
+*.jpeg binary
+*.bmp binary
+*.gif binary
+*.svg text eol=lf
+*.ogg binary
+*.mp3 binary
+*.wav binary
+*.ttf binary
+*.otf binary
+*.zip binary
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..88d74a4
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,60 @@
+name: CI
+
+on:
+ push:
+ branches: [master, main]
+ pull_request:
+
+concurrency:
+ group: ci-${{ github.ref }}
+ cancel-in-progress: true
+
+jobs:
+ test:
+ name: ${{ matrix.os }} / py${{ matrix.python }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest, windows-latest]
+ python: ["3.12", "3.13", "3.14"]
+ env:
+ # Run pygame without a real display or audio device.
+ SDL_VIDEODRIVER: dummy
+ SDL_AUDIODRIVER: dummy
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Install SDL2 runtime libraries (Linux)
+ if: runner.os == 'Linux'
+ run: |
+ sudo apt-get update
+ sudo apt-get install -y \
+ libsdl2-2.0-0 libsdl2-image-2.0-0 libsdl2-mixer-2.0-0 libsdl2-ttf-2.0-0 \
+ libfreetype6 libportmidi0
+
+ - name: Install uv
+ uses: astral-sh/setup-uv@v5
+ with:
+ enable-cache: true
+
+ - name: Set up Python ${{ matrix.python }}
+ run: uv python install ${{ matrix.python }}
+
+ - name: Install project
+ run: uv sync --all-extras --python ${{ matrix.python }}
+
+ - name: Lint
+ run: uv run --python ${{ matrix.python }} ruff check .
+
+ - name: Format check
+ run: uv run --python ${{ matrix.python }} ruff format --check .
+
+ - name: Type check
+ run: uv run --python ${{ matrix.python }} mypy src
+
+ - name: Tests
+ run: uv run --python ${{ matrix.python }} pytest
+
+ - name: Headless smoke run
+ run: uv run --python ${{ matrix.python }} exit-dash-hyperion --headless --frames 120
diff --git a/.gitignore b/.gitignore
index 7bbc71c..e842176 100644
--- a/.gitignore
+++ b/.gitignore
@@ -99,3 +99,21 @@ ENV/
# mypy
.mypy_cache/
+
+# Ruff
+.ruff_cache/
+
+# pytest
+.pytest_cache/
+
+# uv
+# (uv.lock IS committed for reproducible installs)
+
+# IDEs / editors
+.idea/
+.vscode/
+*.swp
+*~
+
+# macOS
+.DS_Store
diff --git a/.idea/.name b/.idea/.name
deleted file mode 100644
index da33c87..0000000
--- a/.idea/.name
+++ /dev/null
@@ -1 +0,0 @@
-ExitDashHyperion
\ No newline at end of file
diff --git a/.idea/ExitDashHyperion.iml b/.idea/ExitDashHyperion.iml
deleted file mode 100644
index 88be381..0000000
--- a/.idea/ExitDashHyperion.iml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index 7c62b52..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/.idea/inspectionProfiles/CustomProf.xml b/.idea/inspectionProfiles/CustomProf.xml
deleted file mode 100644
index 6f6b9ba..0000000
--- a/.idea/inspectionProfiles/CustomProf.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
deleted file mode 100644
index 244ff31..0000000
--- a/.idea/inspectionProfiles/Project_Default.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
deleted file mode 100644
index 6933c1e..0000000
--- a/.idea/inspectionProfiles/profiles_settings.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
deleted file mode 100644
index 0e219b1..0000000
--- a/.idea/misc.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 86752c3..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/.idea/scopes/scope_settings.xml b/.idea/scopes/scope_settings.xml
deleted file mode 100644
index 0d5175c..0000000
--- a/.idea/scopes/scope_settings.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index d2d96f2..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
deleted file mode 100644
index 51abc83..0000000
--- a/.idea/workspace.xml
+++ /dev/null
@@ -1,981 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- HTML
-
-
- Python
-
-
- XML
-
-
-
-
- PyTypeCheckerInspection
-
-
-
-
-
-
-
-
-
-
-
- Buildout
-
-
- General
-
-
- HTML
-
-
- Internationalization issues
-
-
-
-
- RELAX NG
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1390428928208
- 1390428928208
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..b30ddb6
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,20 @@
+# Run `uv run pre-commit install` once to enable these on every commit.
+repos:
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.15.17
+ hooks:
+ - id: ruff
+ args: [--fix]
+ - id: ruff-format
+
+ - repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v6.0.0
+ hooks:
+ - id: check-toml
+ - id: check-yaml
+ - id: end-of-file-fixer
+ - id: trailing-whitespace
+ exclude: '\.dat$'
+ - id: mixed-line-ending
+ args: [--fix=lf]
+ exclude: '\.dat$'
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..f9b1db6
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,13 @@
+# AGENTS.md
+
+This project's agent/contributor guidance lives in **[CLAUDE.md](CLAUDE.md)** — it covers
+the project layout, how to develop/run/test, coding conventions (fixed-timestep loop,
+asset paths, typing/lint, DRY), and the modernization status. Please read it first.
+
+Quick start:
+
+```sh
+uv sync --all-extras
+uv run pytest
+uv run ruff check . && uv run ruff format --check . && uv run mypy src
+```
diff --git a/CLAUDE.md b/CLAUDE.md
new file mode 100644
index 0000000..0a7cebb
--- /dev/null
+++ b/CLAUDE.md
@@ -0,0 +1,80 @@
+# CLAUDE.md
+
+Guidance for Claude Code (and other agents — see `AGENTS.md`) working in this repo.
+
+## What this is
+
+`exit-dash-hyperion` is a 2D platformer first written in 2014 in **Python 2 + pygame
+1.9.3**. It is being modernized to **Python 3.12+ + pygame-ce**, cross-platform
+(macOS/Linux/Windows), with a modern architecture and tooling.
+
+## Project layout
+
+```
+src/exit_dash/ # the game (single source of truth)
+ core/ # engine: app loop, scene stack, input, settings, resources, paths
+ scenes/ # screens: title, level, game-over (options + editor: see below)
+ entities/ # player, enemy, platform, block, pool, spike, door, key, ...
+ world/ # LevelData + World, .dat loader, procedural generator, hints
+ assets/ # bundled images, audio, fonts, level data (.dat)
+tests/ # pytest suite (headless via SDL dummy drivers)
+```
+
+Note: entities are plain typed classes (not `pygame.sprite.Sprite`) — the move-the-world
+camera + bespoke per-entity rendering don't use sprite groups, so the base only added
+friction. The camera lives on `PlayableCharacter` (the "move the world" methods).
+
+## Develop / run / test
+
+This project uses **uv**. Common commands:
+
+```sh
+uv sync --all-extras # install deps + dev tools
+uv run exit-dash-hyperion # play (use --windowed / --headless / --frames N)
+uv run pytest # tests
+uv run ruff check . && uv run ruff format .
+uv run mypy src
+```
+
+CI matrix: {ubuntu, macos, windows} × Python {3.12, 3.13, 3.14}.
+
+## Conventions
+
+- **Fixed-timestep simulation.** The loop in `core/app.py` advances scenes in fixed
+ `FIXED_DT` (1/60 s) steps, decoupled from render rate. Physics constants are *not*
+ scaled by `dt` inside a step — they are tuned per-step, exactly as the original
+ per-frame code was. Do **not** introduce `pos += vel * dt`; it would change feel and
+ cause collision tunnelling.
+- **Assets via `core/paths.py`.** Never load assets relative to the CWD. Use
+ `paths.asset_path(...)`; user-writable state (settings, custom levels) goes in
+ `paths.user_config_dir()` / `paths.user_data_dir()`.
+- **Typing + lint.** Full type hints; keep `ruff` and `mypy src` clean. Prefer
+ `pathlib` over `os.path`, dataclasses for records, `pygame.math.Vector2` for positions.
+- **DRY.** Reuse engine/core helpers; don't reintroduce the legacy god-class patterns.
+- **Tests.** Add/extend tests in `tests/` for new behavior. Everything runs headless via
+ `SDL_VIDEODRIVER=dummy` / `SDL_AUDIODRIVER=dummy` (set in `tests/conftest.py`).
+
+## Status & not-yet-ported
+
+The Python-2 → 3 + pygame-ce modernization is complete: the legacy `data/` tree has been
+removed and `src/exit_dash/` is the only implementation. Behavior that had to be preserved
+(collision feel, `.dat` level semantics, per-character stats, move-the-world camera,
+autoscroll, torch/darkness, generator RNG order) is locked in by the tests.
+
+**Not yet ported from the original** (the game is fully playable without them — good
+next tasks):
+
+- **Options menu** — settings exist (`core/settings.py`) and persist, but there's no
+ in-game UI to change them yet. A `scenes/options.py` + `ui/widgets.py` (button/slider/
+ toggle) would wire it up.
+- **In-game level editor** — the original let you build/save custom levels to
+ `lvl_custom.dat`; `world/loader.py` can already read/write the format, so this is an
+ editor `Scene` on top of it.
+
+## Gotchas
+
+- Never load assets relative to the CWD (the original's biggest portability bug); use
+ `core/paths.py` / `core/resources.py`.
+- Level `.dat` files historically had mixed CRLF/LF line endings — the loader normalizes
+ on read; `.gitattributes` keeps them LF.
+- Audio/display may be unavailable in CI; guard with the patterns in `core/app.py`.
diff --git a/CREDITS.md b/CREDITS.md
new file mode 100644
index 0000000..21a1d39
--- /dev/null
+++ b/CREDITS.md
@@ -0,0 +1,31 @@
+# Credits
+
+The game **code** is © Kenneth Sinder and released under the MIT License (see `LICENSE`).
+
+The bundled **assets** are third-party works under open licenses. The per-pack license
+files shipped with the original art are preserved alongside the assets.
+
+## Graphics
+
+- **UI pack** — Kenney Vleugels ([kenney.nl](https://kenney.nl)) — CC0.
+- **Platformer Art (Xeno Diversity)** — Arsonide — CC0. (character sprites)
+- **Platformer Art Deluxe (Pixel Redux)** — Kenney Vleugels ([kenney.nl](https://kenney.nl)) — CC0. (environment/terrain tiles)
+
+CC0 (public domain): https://creativecommons.org/publicdomain/zero/1.0/ — credit is
+appreciated but not required.
+
+## Music
+
+- **Alexander Ehlers** — "Twists", "Waking the Devil", "Great Mission", "Flags",
+ "Doomed", "Spacetime", "Warped".
+- Additional tracks credited to their original creators by handle in the filenames:
+ `jan125` (artblock), `jukeri12` (disconnected), `megalover` (radiops_megalover),
+ and "Recall of the Shadows".
+
+Music tracks are used under their respective original licenses. If you are a rights
+holder and want a credit corrected or a track removed, please open an issue.
+
+## Sound effects
+
+Short SFX in `assets/sounds/` (clicks, steps, explosion, etc.) originate from open
+sound-effect libraries (Kenney / OpenGameArt-style CC0 packs).
diff --git a/MainGame.py b/MainGame.py
deleted file mode 100644
index b780487..0000000
--- a/MainGame.py
+++ /dev/null
@@ -1,1721 +0,0 @@
-# Kenneth Sinder
-# Exit Dash: Hyperion (2D Platform Game)
-# Last Modified: February 2, 2014
-
-# 30% complete
-# BUGS: none so far
-# TODO: implement fall damage, improve AI, add ending, add bosses, add checkpoints,
-# TODO: add autoscrolling levels, select final theme, add rocket for final level, add file I/O for pregenerated levels,
-# TODO: implement level editor, redesign title screen, add additional powerups, optimize display updates,
-# TODO: add precipitation particles, add torches, add more mobs
-
-# Import statements for pygame and related modules
-import sys
-import os
-import math
-import pygame
-from random import *
-from pygame.locals import *
-
-# Initialize pygame module
-pygame.init()
-
-# Initialize control variables for the game at the module level
-DeveloperMode = True
-Antialiasing = True
-StableFPS = True
-Decorations = True
-FPSClock = pygame.time.Clock()
-DesiredFPS = 75
-FPS, MeasuredFPS = DesiredFPS, DesiredFPS
-ScreenWidth = pygame.display.list_modes()[0][0]
-ScreenHeight = pygame.display.list_modes()[0][1]
-Caption = 'Exit Dash - Hyperion'
-ScreenSurface = pygame.display.set_mode((ScreenWidth, ScreenHeight), pygame.FULLSCREEN | pygame.HWACCEL |
- pygame.ASYNCBLIT | pygame.HWSURFACE | pygame.DOUBLEBUF)
-pygame.display.set_caption(Caption)
-ShouldDisplayOptions = False
-AllMovableObjects, Enemies = [], []
-DefaultValue = -999
-TimeBetweenLevels = 50
-DevX = ScreenWidth - 350
-DevY = 50
-DevSpacing = 32
-MouseX, MouseY, MouseX_Hover, MouseY_Hover = 0, 0, 0, 0
-Level = 0
-
-# Colours
-white = (255, 255, 255)
-grey = (185, 185, 185)
-black = (0, 0, 0)
-red = (155, 0, 0)
-brightred = (175, 20, 20)
-green = (0, 155, 0)
-brightgreen = ( 20, 175, 20)
-blue = (0, 0, 155)
-brightblue = (20, 20, 175)
-yellow = (255, 255, 0)
-
-# Fonts
-genericFont = pygame.font.Font('fonts' + os.sep + 'gamecuben.ttf', 32)
-mediumFont = pygame.font.Font('fonts' + os.sep + 'jetset.ttf', 24)
-smallFont = pygame.font.Font('fonts' + os.sep + 'atari.ttf', 16)
-
-# Backgrounds
-origin = (0, 0)
-bgrdTitle = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'aquatiled_jordan_irwin.png').convert()
-bgrdGloomy = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'red_sky.jpg').convert()
-bgrdGloomyInv = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'red_sky_inverted.jpg').convert()
-bgrdYellowSky = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'yellow-sky.jpg').convert()
-bgrdYellowSkyInv = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'yellow-sky-inverted.jpg').convert()
-bgrdCastle = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'bg_castle.png').convert()
-bgrdCastleInv = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'bg_castle_inv.png').convert()
-bgrdCastle = pygame.transform.smoothscale(bgrdCastle, (3 * pygame.Surface.get_width(bgrdCastle),
- 3 * pygame.Surface.get_height(bgrdCastle)))
-bgrdCastleInv = pygame.transform.smoothscale(bgrdCastleInv, (pygame.Surface.get_width(bgrdCastle),
- pygame.Surface.get_height(bgrdCastle)))
-bgrdDesert = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'bg_desert.png').convert()
-bgrdDesertInv = pygame.image.load('backgrounds' + os.sep + 'main' + os.sep + 'bg_desert_inv.png').convert()
-initialBgrdSetup = True
-bgrdX, bgrdY, bgrdInvX = 0, 0, 0
-
-# =====================================================================================================================
-class Character:
- def __init__(self, x, y, Vx=0, Vy=0, whichChar=1):
- # Initialize motion variables
- self.x = x
- self.y = y
- self.Vx = Vx
- self.Vy = Vy
-
- # Hard-code the gravity acceleration, jumping speed, and run speed
- self.gravity = 1.5
- self.jumpSpeed = 22
- self.runSpeed = 4
-
- # Initialize variables related to drawing and motion to zero/false
- self.walkFrame = 0
- self.mobJumping = False
- self.underwater = False
- self.movingLaterally = False
- self.jumping = False
- self.canJump = False
- self.onGround = False
- self.hasKey = False
- self.direction = 0
- self.currentPlatform = 0
- self.lowestPlatform = 0
-
- # Score and coins
- if whichChar == 1:
- self.health = 4
- elif whichChar == 2:
- self.health = 6
- else:
- self.health = 10
- self.recoveryHealth = self.health
- self.flashing = True
- self.flashTimer = 0
- self.coins = 0
-
- # Load images and save the height and width of the character
- self.standingImage = pygame.image.load('character'+os.sep+'main'+os.sep+'p' + str(whichChar) + '_front.png').convert_alpha()
- self.jumpingImageL = pygame.image.load('character'+os.sep+'main'+os.sep+'p' + str(whichChar) + '_jump_l.png').convert_alpha()
- self.jumpingImageR = pygame.image.load('character'+os.sep+'main'+os.sep+'p' + str(whichChar) + '_jump.png').convert_alpha()
- self.width = pygame.Surface.get_width(self.standingImage)
- self.height = pygame.Surface.get_height(self.standingImage)
- self.walkImagesR = [] * 11
- self.walkImagesL = [] * 11
- for i in range(1, 11):
- walkImage = pygame.image.load('character'+os.sep+'main'+os.sep+'p' + str(whichChar) + '_walk'+os.sep+'PNG'+os.sep+'p' + str(whichChar) +
- '_walk' + str(i) + ".png").convert_alpha()
- self.walkImagesR.append(walkImage)
- walkImageL = pygame.transform.flip(walkImage, True, False)
- self.walkImagesL.append(walkImageL)
-
- # Use 2D kinematics to determine maximum jump height and length
- jumpTime = self.jumpSpeed / self.gravity
- self.maxJumpHeight = math.floor(0.5 * self.jumpSpeed * jumpTime)
- self.maxJumpLength = math.floor(abs(self.runSpeed * jumpTime))
-
- # Save the character ID
- self.whichChar = whichChar
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool):
- # Perform all player updates
- self.updateMotion(ev, platforms, movableObjects, aiCharacters)
- self.collide(platforms, blocks, aiCharacters, pool)
- self.determineLowestPlatform(platforms)
- self.draw()
-
- # -----------------------------------------------------------------------------------------------------------------
- def determineLowestPlatform(self, platforms):
- for platform in range(0, len(platforms)):
- if platforms[platform].y > platforms[self.lowestPlatform].y:
- self.lowestPlatform = platform
-
- # -----------------------------------------------------------------------------------------------------------------
- def jump(self, intensity=1.0):
- # Generic jump method that does not check if jumping is feasible
- self.Vy = math.floor(-intensity * self.jumpSpeed)
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, ev, platforms, movableObjects, aiCharacters):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0][3] - platforms[0][1] - 5
-
- # Apply gravity if necessary
- if self.onGround:
- self.Vy = 0
- self.mobJumping = False
- else:
- self.Vy += self.gravity
-
- # -----------------------------------------------------------------------------------------------------------------
- def blockCollision(self, blocks):
- # Local variables for player position
- left = self.x + 10
- right = self.x + self.width - 10
- top = self.y
- bottom = self.y + self.height
-
- for block in blocks:
- # Local variables for block position
- blockLeft = block.x
- blockRight = block.x + block.width
- blockTop = block.y
- blockBottom = block.y + block.height
- blockMiddleX = int(0.5 * blockLeft + 0.5 * blockRight)
- blockMiddleY = int(0.5 * blockBottom + 0.5 * blockTop)
-
- # Booleans for player position relative to block
- belowBlock = right >= blockLeft and left <= blockRight and blockMiddleY <= top <= blockBottom
- leftOfBlock = blockLeft <= right < blockMiddleX and bottom > blockTop and top < blockBottom
- rightOfBlock = blockRight >= left > blockMiddleX and bottom > blockTop and top < blockBottom
- aboveBlock = right >= blockLeft + 10 and left <= blockRight - 10 and blockBottom > bottom >= blockTop
-
- hitBlock = False
- if belowBlock and self.jumping:
- self.y = block.y + block.height + 1
- self.Vy = 0
- hitBlock = True
- elif leftOfBlock:
- self.x = blockLeft - self.width
- self.Vx *= -1
- return True
- elif rightOfBlock:
- self.x = blockRight
- self.Vx *= -1
- return True
- elif aboveBlock and self.Vy >= 0:
- self.y = blockTop - self.height
- self.onGround = True
- if not block.disabled and hitBlock:
- block.disable()
- if block.willExplode and not self.flashing:
- self.health -= 1
- self.flashing = True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
- def coinCollision(self, blocks):
- selfRect = pygame.Rect(self.x, self.y, self.width, self.height)
- for block in blocks:
- coin = block.coinPos
- coinRect = pygame.Rect(coin[0], coin[1], block.coinWidth, block.coinHeight)
- starRect = pygame.Rect(coin[0], coin[1], block.starWidth, block.starHeight)
- if block.coinVisible and selfRect.colliderect(coinRect) and not block.yieldsStar:
- self.coins += 1
- block.killcoin()
- elif block.coinVisible and selfRect.colliderect(starRect):
- self.coins += 10
- self.health += 2
- block.killcoin()
-
- # -----------------------------------------------------------------------------------------------------------------
- def platformCollision(self, platforms):
- platformTolerance = 15
- PlayerLeftX = self.x
- PlayerTopY = self.y
- PlayerRightX = self.x + self.width
- PlayerBottomY = self.y + self.height
- for i in range(0, len(platforms)):
- PlatformLeftX = platforms[i][0]
- PlatformTopY = platforms[i][1]
- PlatformRightX = platforms[i][2]
- PlatformBottomY = platforms[i][3]
- if PlayerRightX >= PlatformLeftX + platformTolerance and PlayerLeftX <= PlatformRightX - \
- platformTolerance and PlatformTopY <= PlayerBottomY <= PlatformBottomY + 15 and self.Vy >= 0:
- self.y = PlatformTopY - self.height
- self.onGround = True
- self.currentPlatform = i
- if PlayerRightX >= PlatformLeftX + platformTolerance and PlayerLeftX <= PlatformRightX - platformTolerance \
- and PlatformBottomY >= PlayerTopY >= PlatformTopY and self.Vy < 0:
- if PlayerRightX >= PlatformLeftX + platforms[i].tileWidth and \
- PlayerLeftX <= PlatformRightX - platforms[i].tileWidth:
- self.y = PlatformBottomY
- self.Vy = 0
- elif PlayerTopY <= PlatformTopY + platformTolerance + 10:
- self.y = PlatformBottomY
- self.Vy = 0
-
- # -----------------------------------------------------------------------------------------------------------------
- def collide(self, platforms, blocks, aiCharacters, pool):
- # Initially assume the player is not on the ground and not underwater
- self.onGround = False
- self.underwater = False
-
- # Detect block collisions
- self.blockCollision(blocks)
- self.coinCollision(blocks)
-
- # Detect platform collision and adjust player motion accordingly
- self.platformCollision(platforms)
-
- # Detect collision with (other) AI characters
- if not isinstance(self, AICharacter):
- for aiCharacter in aiCharacters:
- aiCharacterRect = pygame.Rect(aiCharacter.x, aiCharacter.y, aiCharacter.width, aiCharacter.height)
- selfRect = pygame.Rect(self.x, self.y, self.width, self.height)
- if selfRect.colliderect(aiCharacterRect) and aiCharacter.alive:
- if self.Vy > 0 and aiCharacter.mobType != 'fly':
- aiCharacter.health -= 7 - self.whichChar
- self.jump(0.6)
- self.mobJumping = True
- elif self.Vy > 0:
- aiCharacter.alive = False
- elif not self.flashing and not self.mobJumping:
- self.health -= 1
- self.flashing = True
-
- # Detect collision with pool platform
- if pool:
- PlayerLeftX = self.x
- PlayerRightX = self.x + self.width
- PlayerBottomY = self.y + self.height
- if pool.y <= PlayerBottomY <= pool.y + pool.tileWidth and ((PlayerRightX - 10 >= pool.x and PlayerLeftX + 10
- <= pool.poolStartX + pool.tileWidth) or (PlayerRightX - 10 >= pool.poolEndX and PlayerLeftX + 10
- <= pool.x + pool.width)) and self.Vy >= 0:
- self.onGround = True
- self.y = pool.y - self.height
- if PlayerLeftX + 10 >= pool.poolStartX and PlayerRightX - 10 <= pool.poolEndX + pool.tileWidth and \
- pool.y + pool.height <= PlayerBottomY <= pool.y + pool.height + pool.tileWidth and self.Vy >= 0:
- self.onGround = True
- self.y = pool.y + pool.height - self.height
- if pool.poolStartX + pool.tileWidth >= PlayerLeftX >= pool.poolStartX and \
- pool.y < PlayerBottomY <= pool.y + pool.height:
- self.x = pool.poolStartX + pool.tileWidth + 1
- self.Vx *= -1
- if pool.poolEndX <= PlayerRightX <= pool.poolEndX + pool.tileWidth and \
- pool.y < PlayerBottomY <= pool.y + pool.height:
- self.x = pool.poolEndX - self.width - 1
- self.Vx *= -1
- if PlayerRightX >= pool.poolStartX and PlayerLeftX <= pool.poolEndX and \
- pool.y + pool.height >= PlayerBottomY > pool.y:
- self.underwater = True
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self):
- global ScreenSurface # Allow writing to display surface object
-
- # Increment the current frame of the player walking animation
- footstepRarity = 1
- if pygame.time.get_ticks() % footstepRarity == 0:
- self.walkFrame += 1
- if self.walkFrame >= 10:
- self.walkFrame = 0
-
- # Correctly display the current action of the player
- totalFlashTime = 4
- if self.flashing:
- self.flashTimer += 1
- else:
- self.flashTimer = 0
- if self.flashTimer >= (FPS * totalFlashTime):
- self.flashing = False
- if self.flashTimer == 0 or self.flashTimer % FPS < (FPS * 0.75):
- if self.jumping and self.direction == 1:
- ScreenSurface.blit(self.jumpingImageR, (self.x, self.y))
- elif self.jumping and self.direction == 0:
- ScreenSurface.blit(self.jumpingImageL, (self.x, self.y))
- elif self.onGround and self.movingLaterally and self.direction == 1:
- ScreenSurface.blit(self.walkImagesR[self.walkFrame], (self.x, self.y))
- elif self.onGround and self.movingLaterally and self.direction == 0:
- ScreenSurface.blit(self.walkImagesL[self.walkFrame], (self.x, self.y))
- else:
- ScreenSurface.blit(self.standingImage, (self.x, self.y))
-
-# =====================================================================================================================
-class PlayableCharacter(Character):
- def __init__(self, x, y, Vx=0, Vy=0, whichChar=1):
- Character.__init__(self, x, y, Vx, Vy, whichChar)
-
- # HUD images
- self.whichChar = whichChar
- self.heartEmpty = pygame.image.load('hud' + os.sep + 'hud_heartEmpty.png').convert_alpha()
- self.heartHalf = pygame.image.load('hud' + os.sep + 'hud_heartHalf.png').convert_alpha()
- self.heartFull = pygame.image.load('hud' + os.sep + 'hud_heartFull.png').convert_alpha()
- self.heartWidth = pygame.Surface.get_width(self.heartFull)
- self.heartHeight = pygame.Surface.get_height(self.heartFull)
- self.coin = pygame.image.load('hud' + os.sep + 'hud_coins.png').convert_alpha()
- self.coinWidth = pygame.Surface.get_width(self.coin)
- self.coinsMultiplier = pygame.image.load('hud' + os.sep + 'hud_x.png').convert_alpha()
- self.hudNumber = []
- for i in range(0, 10):
- numberImage = pygame.image.load('hud' + os.sep + 'hud_' + str(i) + '.png').convert_alpha()
- self.hudNumber.append(numberImage)
- self.hudTextWidth = pygame.Surface.get_width(self.hudNumber[0])
- self.playerCoins = []
- for i in range(0, 3):
- playerCoinImage = pygame.image.load('hud' + os.sep + 'hud_p' + str(self.whichChar) + '.png').convert_alpha()
- self.playerCoins.append(playerCoinImage)
- self.key = pygame.image.load('hud' + os.sep + 'hud_keyBlue.png').convert_alpha()
- self.noKey = pygame.image.load('hud' + os.sep + 'hud_keyBlue_disabled.png').convert_alpha()
-
- # HUD variables
- self.spacing = 10
- self.coins = 0
- self.playerCoinCoords = (self.spacing, self.spacing)
- self.healthStart = (pygame.Surface.get_width(self.playerCoins[0]) + 2 * self.spacing, 10)
- self.healthInterval = self.spacing + self.heartWidth
-
- # Other variables
- if whichChar == 1:
- self.jumpSpeed = 22
- self.runSpeed = 8
- self.lives = 9
- else:
- self.jumpSpeed = 23
- self.runSpeed = 9
- self.lives = 4
- self.worldShiftCoefficient = 1.5
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, events, platforms, movableObjects, aiCharacters): # Override
- global bgrdX, bgrdY, bgrdInvX
-
- # Call base class implementation
- Character.updateMotion(self, events, platforms, movableObjects, aiCharacters)
- self.x -= self.Vx
-
- keys = pygame.key.get_pressed() # Get keyboard state
-
- # Enable horizontal motion
- if keys[K_LEFT]:
- self.Vx = -self.runSpeed
- self.movingLaterally = True
- self.direction = 0
- if keys[K_RIGHT]:
- self.Vx = self.runSpeed
- self.movingLaterally = True
- self.direction = 1
- if not keys[K_LEFT] and not keys[K_RIGHT]:
- self.Vx = 0
- self.movingLaterally = False
- self.direction = 2
-
- # Move world horizontally and vertically to follow player
- if self.y <= ScreenHeight:
- rightEdge = int(0.5 * ScreenWidth) + 2
- leftEdge = int(0.5 * ScreenWidth) - 2
- bottomEdge = int(0.5 * ScreenHeight) + 5
- topEdge = int(0.5 * ScreenHeight) - 5
- bgrdX -= self.Vx
- bgrdInvX -= self.Vx
- for obj in movableObjects:
- obj.x -= self.Vx
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] -= self.Vx
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] -= self.Vx
- for obj in movableObjects:
- obj.y -= self.Vy
- if self.x >= rightEdge:
- self.x -= int(self.worldShiftCoefficient * self.runSpeed)
- bgrdX -= int(self.worldShiftCoefficient * self.runSpeed)
- bgrdInvX -= int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.x -= int(self.worldShiftCoefficient * self.runSpeed)
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] -= int(self.worldShiftCoefficient * self.runSpeed)
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] -= int(self.worldShiftCoefficient * self.runSpeed)
- if self.x <= leftEdge:
- self.x += int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.x += int(self.worldShiftCoefficient * self.runSpeed)
- bgrdX += int(self.worldShiftCoefficient * self.runSpeed)
- bgrdInvX += int(self.worldShiftCoefficient * self.runSpeed)
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] += int(self.worldShiftCoefficient * self.runSpeed)
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] += int(self.worldShiftCoefficient * self.runSpeed)
- if self.y <= topEdge:
- self.y += int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.y += int(self.worldShiftCoefficient * self.runSpeed)
- if self.y >= bottomEdge:
- self.y -= int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.y -= int(self.worldShiftCoefficient * self.runSpeed)
- elif randint(0, 10) == 0:
- self.health -= 1
-
- # Allow jumping
- if self.jumping and self.onGround:
- self.jumping = False
- if (keys[K_SPACE] or keys[K_UP]) and self.canJump and self.onGround:
- Character.jump(self)
- self.jumping = True
- self.canJump = False
- self.onGround = False
- if not keys[K_SPACE] and not keys[K_UP] and self.onGround:
- self.canJump = True
-
- # Reset player if dead
- if self.health <= 0:
- self.x = int(0.5 * platforms[0][0] + 0.5 * platforms[0][2])
- self.y = platforms[0][1] - self.height - 10
- self.Vy = 0
- self.Vx = 0
- self.health = self.recoveryHealth
- self.flashing = True
- self.lives -= 1
- if self.x <= 0 or self.x >= ScreenWidth:
- self.worldShiftCoefficient = 20
- else:
- self.worldShiftCoefficient = 1.5
-
- # Show game over screen if no lives are remaining
- if self.lives <= 0:
- showGameOverScreen(False)
-
- # Check for any other I/O events
- for event in events:
- if event.type == QUIT:
- pygame.quit()
- sys.exit()
- elif event.type == KEYDOWN:
- if event.key == K_ESCAPE:
- pygame.quit()
- sys.exit()
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self):
- Character.draw(self)
-
- # DRAW HUD:
- # Player symbol
- ScreenSurface.blit(self.playerCoins[self.whichChar - 1], self.playerCoinCoords)
- ScreenSurface.blit(self.coinsMultiplier, (self.spacing + self.heartWidth, int(2.5 * self.spacing)))
- ScreenSurface.blit(self.hudNumber[self.lives], (5 * self.spacing + self.heartWidth, int(1.5 * self.spacing)))
- # Health
- health = self.health / 2
- for filledHearts in range(1, int(health) + 1):
- if health >= 0:
- ScreenSurface.blit(self.heartFull, (self.healthInterval * filledHearts - 55, 7 * self.spacing))
- if math.floor(health) != health and health >= 0:
- ScreenSurface.blit(self.heartHalf, (self.healthInterval * math.ceil(health) - 55, 7 * self.spacing))
- # Coins
- ScreenSurface.blit(self.coin, (self.spacing, 8 * self.spacing + self.heartHeight))
- ScreenSurface.blit(self.coinsMultiplier, (self.spacing + self.heartWidth,
- 8 * self.spacing + self.heartHeight + 15))
- coinsAsList = []
- for i in str(self.coins):
- coinsAsList.append(int(i))
- for i in range(0, len(coinsAsList)):
- ScreenSurface.blit(self.hudNumber[coinsAsList[i]], (3 * self.spacing + self.coinWidth + self.hudTextWidth *
- (i + 1), 7 * self.spacing + self.heartHeight + 15))
- # Key
- if self.hasKey:
- ScreenSurface.blit(self.key, (self.spacing, 13 * self.spacing + self.heartHeight + 15))
- else:
- ScreenSurface.blit(self.noKey, (self.spacing, 13 * self.spacing + self.heartHeight + 15))
-
-# =====================================================================================================================
-class AICharacter(Character):
- def __init__(self, x, y, Vx, Vy, properties=('slime', -1, -1)):
- # Properties should be a tuple of the form (STRING mobName, INT leftLimit,
- # INT rightLimit) where leftLimit and rightLimit can be -1 to remove the limit
- self.mobType = properties[0]
- self.limit = [properties[1], properties[2]]
-
- # Call base class implementation
- Character.__init__(self, x, y, Vx, Vy)
-
- # Load images
- self.slimeDL = pygame.image.load('enemies' + os.sep + 'slime' + os.sep + 'slimeGreen_squashed.png').convert_alpha()
- self.slimeDR = pygame.image.load('enemies' + os.sep + 'slime' + os.sep + 'slimeGreen_squashedR.png').convert_alpha()
- self.slimeL = pygame.image.load('enemies' + os.sep + 'slime' + os.sep + 'slimeGreen_walk.png').convert_alpha()
- self.slimeR = pygame.image.load('enemies' + os.sep + 'slime' + os.sep + 'slimeGreen_walkR.png').convert_alpha()
- self.flyDL = pygame.image.load('enemies' + os.sep + 'fly' + os.sep + 'fly_dead.png').convert_alpha()
- self.flyDR = pygame.image.load('enemies' + os.sep + 'fly' + os.sep + 'fly_dead_r.png').convert_alpha()
- self.flyL = pygame.image.load('enemies' + os.sep + 'fly' + os.sep + 'fly_fly.png').convert_alpha()
- self.flyR = pygame.image.load('enemies' + os.sep + 'fly' + os.sep + 'fly_fly_r.png').convert_alpha()
- self.fishDL = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'fishDead.png').convert_alpha()
- self.fishDR = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'fishDead_r.png').convert_alpha()
- self.fishL1 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'fishSwim1.png').convert_alpha()
- self.fishL2 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'fishSwim2.png').convert_alpha()
- self.fishR1 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'fishSwim1R.png').convert_alpha()
- self.fishR2 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'fishSwim2R.png').convert_alpha()
- self.snailL1 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'snailWalk1.png').convert_alpha()
- self.snailL2 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'snailWalk2.png').convert_alpha()
- self.snailR1 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'snailWalk1R.png').convert_alpha()
- self.snailR2 = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'snailWalk2R.png').convert_alpha()
- self.snailDL = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'snailShell.png').convert_alpha()
- self.snailDR = pygame.image.load('enemies' + os.sep + 'other' + os.sep + 'snailShellR.png').convert_alpha()
-
- # Other control variables
- self.originalHeight = y
- self.alive = True
- self.health = 1
- self.gravity = 1
- self.runSpeed = abs(self.Vx)
- self.currentStep = 0
- self.takenAction = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateAI(self, platforms, mainChar, blocks):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Determine direction for draw() method
- if self.Vx > 0:
- self.direction = 1
- elif self.Vx < 0:
- self.direction = 0
-
- # Check if character is still alive
- if self.health <= 0:
- self.alive = False
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0][3] - platforms[0][1] - 5
-
- # Apply gravity if necessary
- if self.onGround:
- self.Vy = 0
- elif ((self.mobType == 'fly' and not self.alive) or self.mobType != 'fly') and (self.mobType != 'fish' or
- (self.mobType == 'fish' and not self.alive)):
- self.Vy += self.gravity
-
- # Keep character within bounds
- if self.limit[0] != -1 and self.x <= self.limit[0]:
- self.x += self.runSpeed
- self.Vx = abs(self.Vx)
- if self.limit[1] != -1 and self.x >= self.limit[1]:
- self.x -= self.runSpeed
- self.Vx = -abs(self.Vx)
-
- # Switch to a dead state if close to explosion
- explosionRadius = 400
- for block in blocks:
- distanceFromBlock = distance((self.x + 0.5 * self.width, self.y + 0.5 * self.height),
- (block.x + 0.5 * block.width, block.y + 0.5 * block.height))
- if block.disabled and block.willExplode and block.explosionStep == 1 and \
- distanceFromBlock < explosionRadius:
- self.health = 0
-
- # Prevent AI from falling off the lowest platform
- if self.mobType == 'slime' or self.mobType == 'snail':
- testXLeft = self.x - 20
- testXRight = self.x + 20 + self.width
- lowestPlatLeft = platforms[self.lowestPlatform][0]
- lowestPlatRight = platforms[self.lowestPlatform][2]
- onLowestPlatform = self.currentPlatform == self.lowestPlatform
- if onLowestPlatform and testXLeft <= lowestPlatLeft and self.Vx < 0:
- self.x += self.runSpeed
- self.Vx *= -1
- elif onLowestPlatform and testXRight >= lowestPlatRight and self.Vx > 0:
- self.x -= self.runSpeed
- self.Vx *= -1
-
- # Implement simple AI
- if self.mobType == 'slime' or self.mobType == 'snail':
- platformsBelowSelf = []
- currentPlatformHeight = platforms[self.currentPlatform][1]
- limitBackup = [self.limit[0], self.limit[1]]
- self.limit[0] = platforms[self.currentPlatform][0] + 5
- self.limit[1] = platforms[self.currentPlatform][2] - 40
- safePlatformDropLeft, safePlatformDropRight = False, False
- for i in range(0, len(platforms)):
- if platforms[i][1] > currentPlatformHeight:
- platformsBelowSelf.append(platforms[i])
- for platform in platformsBelowSelf:
- if platform[0] < platforms[self.currentPlatform][0] < platform[2]:
- safePlatformDropLeft = True
- if platform[0] < platforms[self.currentPlatform][2] and platform[2] > platforms[self.currentPlatform][
- 2]:
- safePlatformDropRight = True
- if safePlatformDropLeft:
- self.limit[0] = limitBackup[0]
- if safePlatformDropRight:
- self.limit[1] = limitBackup[1]
- elif self.mobType == 'fly' and self.alive:
- self.limit[0] = platforms[0][0]
- for i in range(0, len(platforms)):
- if self.x + self.width + 5 >= platforms[i][0] and self.x <= platforms[i][2] and \
- platforms[i][1] <= self.y <= platforms[i][3]:
- self.limit[1] = platforms[i][0]
- self.Vx *= -1
- self.x -= self.runSpeed
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool):
- # Collide with other objects
- Character.collide(self, platforms, blocks, aiCharacters, pool)
-
- # Update motion and AI actions
- self.updateAI(platforms, mainChar, blocks)
-
- # Draw correct character
- self.draw()
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self):
- # Determine the correct image to use
- if self.mobType == 'slime':
- imageL1 = imageL2 = self.slimeL
- imageR1 = imageR2 = self.slimeR
- imageDL = self.slimeDL
- imageDR = self.slimeDR
- elif self.mobType == 'fly':
- imageL1 = imageL2 = self.flyL
- imageR1 = imageR2 = self.flyR
- imageDL = self.flyDL
- imageDR = self.flyDR
- elif self.mobType == 'fish':
- imageL1 = self.fishL1
- imageL2 = self.fishL2
- imageR1 = self.fishR1
- imageR2 = self.fishR2
- imageDL = self.fishDL
- imageDR = self.fishDR
- elif self.mobType == 'snail':
- imageL1 = self.snailL1
- imageL2 = self.snailL2
- imageR1 = self.snailR1
- imageR2 = self.snailR2
- imageDL = self.snailDL
- imageDR = self.snailDR
-
- # Get image widths and heights
- self.width = pygame.Surface.get_width(imageL1)
- self.height = pygame.Surface.get_height(imageL1)
- deadWidth = pygame.Surface.get_width(imageDL)
- deadHeight = pygame.Surface.get_height(imageDL)
-
- # Increment the walking/moving frame
- footstepRarity = 1
- if pygame.time.get_ticks() % footstepRarity == 0:
- self.walkFrame += 1
- if self.walkFrame > 1:
- self.walkFrame = 0
-
- if self.direction == 1 and self.alive and self.walkFrame == 0:
- ScreenSurface.blit(imageR1, (self.x, self.y))
- elif self.direction == 0 and self.alive and self.walkFrame == 0:
- ScreenSurface.blit(imageL1, (self.x, self.y))
- elif self.direction == 1 and self.alive and self.walkFrame == 1:
- ScreenSurface.blit(imageR2, (self.x, self.y))
- elif self.direction == 0 and self.alive and self.walkFrame == 1:
- ScreenSurface.blit(imageL2, (self.x, self.y))
- elif self.direction == 1 and not self.alive:
- ScreenSurface.blit(imageDR, (self.x, self.y))
- elif self.direction == 0 and not self.alive:
- ScreenSurface.blit(imageDL, (self.x, self.y))
-
- # Recalculate the image width and height, and stop horizontal motion if the AI char is dead
- if not self.alive:
- self.width = deadWidth
- self.height = deadHeight
- self.Vx = 0
- # -----------------------------------------------------------------------------------------------------------------
-
-# =====================================================================================================================
-class BackgroundFoliage:
- def __init__(self, x, y):
- self.x = x
- self.y = y
-
- # Images
- self.whichProp = randint(0, 2)
- self.hill = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'hill_small.png').convert_alpha()
- self.bush = pygame.image.load('items' + os.sep + 'bush.png').convert_alpha()
- self.rock = pygame.image.load('items' + os.sep + 'rock.png').convert_alpha()
- self.image = self.hill
- if self.whichProp == 1:
- self.image = self.bush
- elif self.whichProp == 2:
- self.image = self.rock
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
-
-# -----------------------------------------------------------------------------------------------------------------
- def draw(self):
- ScreenSurface.blit(self.image, (self.x, self.y))
-
-# =====================================================================================================================
-class Block:
- def __init__(self, x, y, form):
- # The argument for the "form" parameter should be one of the following strings:
- # 'locked'/'coin'/'regular'/'explosive'
- self.form = form
-
- # Initialize position
- self.x = x
- self.y = y
-
- # Load images
- self.lockedImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'lock_blue.png').convert_alpha()
- self.coinBlockImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'boxCoin.png').convert_alpha()
- self.coinBlockUsedImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'boxCoin_disabled.png').convert_alpha()
- self.explosiveImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'boxExplosive.png').convert_alpha()
- self.explosiveUsedImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'boxExplosive_disabled.png').convert_alpha()
- self.regularImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'boxItem.png').convert_alpha()
- self.regularUsedImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'boxItem_disabled.png').convert_alpha()
- self.explosion = []
- for i in range(0, 3):
- explosionImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'explosion' + str(i) + '.png').convert_alpha()
- explosionImage = pygame.transform.scale2x(explosionImage)
- self.explosion.append(explosionImage)
- self.width = pygame.Surface.get_width(self.regularImage)
- self.height = pygame.Surface.get_height(self.regularImage)
-
- # Load sounds
- self.explosionSfx = pygame.mixer.Sound('sounds' + os.sep + 'synthetic_explosion_1.ogg')
-
- # Coin images and variables
- self.coinImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'coinGold.png').convert_alpha()
- self.coinWidth = pygame.Surface.get_width(self.coinImage)
- self.coinHeight = pygame.Surface.get_height(self.coinImage)
- self.coinPos = [self.x - 15, self.y - self.coinHeight + 10,
- self.x + self.coinWidth - 15, self.y + 10]
- self.coinVisible = False
-
- # Other images and related variables
- self.starImage = pygame.image.load('items' + os.sep + 'star.png').convert_alpha()
- self.starWidth = pygame.Surface.get_width(self.starImage)
- self.starHeight = pygame.Surface.get_height(self.starImage)
-
- # Other variables to track state of block
- self.disabled = False
- self.willExplode = False
- self.yieldsStar = False
- if self.form == 'explosive':
- self.willExplode = True
- self.explosionStep = 0
-
- # -----------------------------------------------------------------------------------------------------------------
- def __getitem__(self, i):
- if i == 0:
- return self.x, self.y, self.x + self.width, self.y + self.height
- else:
- return self.coinPos[i - 1]
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, keys):
- self.updateState()
- self.draw(keys)
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateState(self):
- self.coinPos = [self.x - 15, self.y - self.coinHeight + 10,
- self.x + self.coinWidth - 15, self.y + 10]
-
- # -----------------------------------------------------------------------------------------------------------------
- def disable(self):
- self.coinVisible = True
- self.disabled = True
-
- # -----------------------------------------------------------------------------------------------------------------
- def killcoin(self):
- self.coinVisible = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, keys):
- global ScreenSurface
-
- # Draw the correct type of block
- if self.form == 'locked':
- image = self.lockedImage
- elif self.form == 'coin' and self.disabled:
- image = self.coinBlockUsedImage
- elif self.form == 'coin' and not self.disabled:
- image = self.coinBlockImage
- elif self.form == 'regular' and self.disabled:
- image = self.regularUsedImage
- elif self.form == 'regular' and not self.disabled:
- image = self.regularImage
- elif self.form == 'explosive' and self.disabled:
- image = self.explosiveUsedImage
- elif self.form == 'explosive' and not self.disabled:
- image = self.explosiveImage
- else:
- image = self.regularImage
- ScreenSurface.blit(image, (self.x, self.y))
-
- # Draw any coins or other objects that may be present
- if self.form == 'coin':
- for i in range(0, len(self.coinPos)):
- if self.coinVisible:
- ScreenSurface.blit(self.coinImage, (self.coinPos[0], self.coinPos[1]))
- if self.form == 'regular':
- for key in keys:
- if self.coinVisible and self.disabled and distance((self.x, self.y), (key.x, key.y)) < 1.5 * key.height:
- key.visible = True
- self.coinVisible = False
- if self.willExplode and self.disabled:
- if randint(0, 2) == 0 and self.explosionStep < len(self.explosion):
- self.explosionStep += 1
- if self.explosionStep < len(self.explosion):
- ScreenSurface.blit(self.explosion[self.explosionStep], (self.x - 65, self.y - 135))
- self.explosionSfx.play()
- if self.yieldsStar and self.disabled and self.coinVisible:
- ScreenSurface.blit(self.starImage, (self.coinPos[0] + 20, self.coinPos[1] + 30))
-
- # -----------------------------------------------------------------------------------------------------------------
-
-# =====================================================================================================================
-class Platform:
- def __init__(self, x, y, Vx, Vy, width, style='grass'):
- self.x = x
- self.y = y
- self.Vx = Vx
- self.Vy = Vy
-
- # Load platform image
- self.image = pygame.image.load('environment' + os.sep + 'main' + os.sep + '' + style + 'Mid.png').convert_alpha()
- self.width = width
- self.tileWidth = pygame.Surface.get_width(self.image)
- self.width -= self.width % self.tileWidth
- self.height = pygame.Surface.get_height(self.image)
-
- # Load platform edge images
- self.leftImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + '' + style + 'CliffLeft.png').convert_alpha()
- self.rightImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + '' + style + 'CliffRight.png').convert_alpha()
-
- # -----------------------------------------------------------------------------------------------------------------
- def __getitem__(self, i):
- # This method allows iteration of platform objects
- # From [0] to [3], it returns the left X, top Y,
- # rightX, and bottom Y, respectively
- if i == 0:
- return self.x
- elif i == 1:
- return self.y
- elif i == 2:
- return self.x + self.width
- elif i == 3:
- return self.y + self.height
- else:
- return i
-
- # -----------------------------------------------------------------------------------------------------------------
- def __setitem__(self, k, v):
- if k == 0:
- self.x = v
- elif k == 1:
- self.y = v
- elif k == 2:
- self.x = v - self.width
- elif k == 3:
- self.y = v - self.height
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, levelBorders):
- self.updateMotion(levelBorders)
- self.draw()
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, levelBorders):
- # Increment the position of the platform by the velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Wrap the motion of the platform around the level edges
- if self.x >= levelBorders[2] and self.Vx > 0:
- self.x = levelBorders[0] - self.width
- elif (self.x - self.width) <= levelBorders[0] and self.Vx < 0:
- self.x = levelBorders[2]
- elif self.y >= levelBorders[3] and self.Vy > 0:
- self.y = levelBorders[1] - self.height
- elif (self.y + self.height) <= levelBorders[1] and self.Vy < 0:
- self.y = levelBorders[3]
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self):
- # Draw platform edges
- ScreenSurface.blit(self.leftImage, (self.x, self.y))
- ScreenSurface.blit(self.rightImage, (self.x + self.width - self.tileWidth, self.y))
-
- # Fill in the platform between the two edges
- for i in range(self.x + self.tileWidth, self.x + self.width - self.tileWidth, self.tileWidth):
- ScreenSurface.blit(self.image, (i, self.y))
-
-# =====================================================================================================================
-class Pool:
- def __init__(self, x, y, width, height, style='grass'):
- self.x, self.y = x, y
- self.Vx, self.Vy = 0, 0
- self.width, self.height = width, height
-
- # Platform images
- self.image = pygame.image.load('environment' + os.sep + 'main' + os.sep + '' + style + 'Mid.png').convert_alpha()
- self.plainImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + '' + style + 'Center.png')
- self.leftImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + '' + style + 'CliffLeft.png').convert_alpha()
- self.rightImage = pygame.image.load('environment' + os.sep + 'main' + os.sep + '' + style + 'CliffRight.png').convert_alpha()
- self.tileWidth = pygame.Surface.get_width(self.image)
-
- # Water images
- self.waterFilled = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'liquidWater.png').convert_alpha()
- self.waterTop = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'liquidWaterTop_mid.png').convert_alpha()
-
- # Update coordinates
- self.width -= self.width % self.tileWidth
- self.height -= self.height % self.tileWidth
- self.poolStartX = int(self.x + 2 * self.tileWidth)
- self.poolEndX = int(self.x + self.width - 2 * self.tileWidth)
-
- # Other control variables
- self.tilesOnEitherSide = 2
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self):
- self.updateMotion()
- self.draw()
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self):
- # Draw edge platforms
- ScreenSurface.blit(self.leftImage, (self.x, self.y))
- ScreenSurface.blit(self.rightImage, (self.x + self.width - self.tileWidth, self.y))
-
- # Draw platform tiles on either side of the pool
- self.poolStartX = int(self.x + self.tilesOnEitherSide * self.tileWidth)
- self.poolEndX = int(self.x + self.width - (1 + self.tilesOnEitherSide) * self.tileWidth)
- for x in range(int(self.x + self.tileWidth), self.poolStartX + self.tileWidth, self.tileWidth):
- ScreenSurface.blit(self.image, (x, self.y))
- for x in range(self.poolEndX, int(self.x) + self.width - self.tileWidth, self.tileWidth):
- ScreenSurface.blit(self.image, (x, self.y))
-
- # Draw pool side columns
- for y in range(int(self.y + self.tileWidth), int(self.y + self.height), self.tileWidth):
- ScreenSurface.blit(self.plainImage, (self.poolStartX, y))
- ScreenSurface.blit(self.plainImage, (self.poolEndX, y))
-
- # Draw bottom of pool
- for x in range(self.poolStartX, self.poolEndX + self.tileWidth, self.tileWidth):
- ScreenSurface.blit(self.plainImage, (x, self.y + self.height))
-
- # Fill with water
- for y in range(int(self.y + self.tileWidth), int(self.y + self.height), self.tileWidth):
- for x in range(self.poolStartX + self.tileWidth, self.poolEndX, self.tileWidth):
- ScreenSurface.blit(self.waterFilled, (x, y))
- for x in range(self.poolStartX + self.tileWidth, self.poolEndX, self.tileWidth):
- ScreenSurface.blit(self.waterTop, (x, self.y))
-
-# =====================================================================================================================
-class FallingSpike:
- def __init__(self, x, y):
- # Initialize motion variables, "x" represents the x co-ordinate of the center of the spike
- self.x = x
- self.y = y
- self.Vx = 0
- self.Vy = 0
-
- # Initialize image
- self.image = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'spikeTop.png')
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
- self.x -= int(0.5 * self.width)
-
- # Other control variables
- self.visible = True
- self.gravityAcceleration = 1.5
- self.dislodged = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, chars, blocks):
- self.updateMotion(chars, platforms)
- self.collide(chars, platforms)
- self.draw(platforms, blocks)
-
- # -----------------------------------------------------------------------------------------------------------------
- def collide(self, chars, platforms):
- for char in chars:
- spikeCentre = (int(self.x + self.width / 2), self.y + int(0.5 * self.height))
- charRect = pygame.Rect(char.x, char.y, char.width, char.height)
- if charRect.collidepoint(spikeCentre) and self.visible and not char.flashing:
- char.health -= 1
- char.flashing = True
- self.visible = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, chars, platforms):
- # Increment position by velocity
- self.x += self.Vx
- self.y += int(self.Vy)
-
- # Check if spike should be dislodged
- for char in chars:
- if char.x + char.width >= self.x and char.x <= self.x + self.width and char.y >= self.y:
- self.dislodged = True
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0][3] - platforms[0][1] - 5
-
- # Apply gravity if dislodged
- if self.dislodged:
- self.Vy += self.gravityAcceleration
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, platforms, blocks):
- # Allow writing to display Surface
- global ScreenSurface
-
- # Only draw if icicle is either stationary or falling and not yet hit an object
- if self.visible:
- ScreenSurface.blit(self.image, (self.x, self.y))
- for platform in platforms:
- if self.y + 0.5 * self.height >= platform[1] > self.y and platform[0] <= self.x <= platform[2]:
- self.visible = False
- for block in blocks:
- if self.y + 0.5 * self.height >= block[0][1] and self.x + \
- self.width >= block[0][0] and self.x <= block[0][2]:
- self.visible = False
-
-# =====================================================================================================================
-class Door:
- def __init__(self, x, y):
- self.x = x
- self.y = y
- self.locked = True
-
- # Load images
- self.imageBottom = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'door_openMid.png').convert_alpha()
- self.imageTop = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'door_openTop.png').convert_alpha()
- self.imageBottomLocked = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'door_closedMid.png').convert_alpha()
- self.imageTopLocked = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'door_closedTop.png').convert_alpha()
- self.bottomHeight = pygame.Surface.get_height(self.imageBottom)
- self.topHeight = pygame.Surface.get_height(self.imageTop)
- self.topBlankSpace = 30
- self.height = self.bottomHeight + self.topHeight - self.topBlankSpace
- self.width = pygame.Surface.get_width(self.imageBottom)
- self.y -= self.bottomHeight + self.topHeight
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, mainChar, unlockable=True):
- charRect = pygame.Rect(mainChar.x, mainChar.y, mainChar.width, mainChar.height)
- selfRect = self.getRect()
- inDoor = charRect.colliderect(selfRect)
- hasKey = mainChar.hasKey
- if inDoor and hasKey and unlockable:
- self.locked = False
- if self.locked:
- ScreenSurface.blit(self.imageTopLocked, (self.x, self.y))
- ScreenSurface.blit(self.imageBottomLocked, (self.x, self.y + self.topHeight))
- elif unlockable:
- ScreenSurface.blit(self.imageTop, (self.x, self.y))
- ScreenSurface.blit(self.imageBottom, (self.x, self.y + self.topHeight))
- if not self.locked and inDoor and unlockable:
- return True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
- def getRect(self):
- return pygame.Rect(self.x, self.y + self.topBlankSpace, self.width, self.height)
-
-# =====================================================================================================================
-class Key:
- def __init__(self, x, y, colour):
- self.x = x
- self.y = y
- self.visible = False
-
- # Load image
- self.image = pygame.image.load('environment' + os.sep + 'main' + os.sep + 'key' + colour + '.png').convert_alpha()
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, mainChar):
- if self.visible:
- ScreenSurface.blit(self.image, (self.x, self.y))
- keyRect = pygame.Rect(self.x, self.y, self.width, self.height)
- charRect = pygame.Rect(mainChar.x, mainChar.y, mainChar.width, mainChar.height)
- if keyRect.colliderect(charRect):
- mainChar.hasKey = True
- self.visible = False
-
-# =====================================================================================================================
-class LevelData:
- def generateRandomLevel(self, theme, numberofplatforms, lvl):
- global p, c, b, mobs, AllMovableObjects, Enemies, spikes, initialBgrdSetup, door, keys, propDoor, textTimer, \
- foliage, poolPlatform, MeasuredFPS, FPS
-
- # Step 0: Clear all data from the previous level
- mobs, AllMovableObjects, Enemies, spikes = [], [], [], []
- initialBgrdSetup = True
- textTimer = 0
- c.hasKey = False
- MeasuredFPS, FPS = DesiredFPS, DesiredFPS
-
- # Step 1: Generate the necessary number of platforms using an iterative strategy
- firstPlatform = Platform(randint(-300, 500), randint(ScreenHeight - 200, ScreenHeight - 50),
- 0, 0, randint(800, 1500), theme)
- overlap = True
- attempts = 2 * numberofplatforms # Reduce number of attempts for slower computers
- maxHeightDifference = c.maxJumpHeight - 10
- maxWidthDifference = c.maxJumpLength * 2
- while overlap and attempts >= 0:
- overlap = False
- attempts -= 1
- p = [firstPlatform]
- for i in range(1, numberofplatforms):
- randomDirection = [1, randint(0, 1)]
- platformWidth = randint(400, 2000)
- prevPlatform = p[i - 1]
- if randomDirection[0] == 0 and randomDirection[1] == 0:
- platformRight = prevPlatform[0] - randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformLeft = platformRight - platformWidth
- platformTop = prevPlatform[1] + randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- elif randomDirection[0] == 0 and randomDirection[1] == 1:
- platformRight = prevPlatform[0] - randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformLeft = platformRight - platformWidth
- platformTop = prevPlatform[1] - randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- elif randomDirection[0] == 1 and randomDirection[1] == 1:
- platformLeft = prevPlatform[2] + randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformTop = prevPlatform[1] - randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- else:
- platformLeft = prevPlatform[2] + randint(int(1.2 * c.width), maxWidthDifference)
- platformTop = prevPlatform[1] + randint(int(0.5 * maxHeightDifference), int(0.4 * ScreenHeight))
- p.append(Platform(platformLeft, platformTop, 0, 0, platformWidth, theme))
- for x1 in range(p[i][0] - 50, p[i][2] + 50, int(p[i].width / 20)):
- for x2 in range(p[i - 1][0] - 50, p[i - 1][2] + 50, int(p[i - 1].width / 20)):
- if abs(x2 - x1) < max(p[i].width / 20, p[i - 1].width / 20) and \
- abs(p[i][3] - p[i - 1][1]) < 100:
- overlap = True
- for platform in p:
- AllMovableObjects.append(platform)
-
- # Step 2: Gather platform info
- topmostPlatform, lowestPlatform, shortestPlatform, longestPlatform, farthestPlatform = p[1], p[1], p[1], p[1], \
- p[1]
- for platform in p:
- if platform[1] < topmostPlatform[1]:
- topmostPlatform = platform
- if platform[1] > lowestPlatform[1]:
- lowestPlatform = platform
- if platform[2] - platform[0] > longestPlatform[2] - longestPlatform[0] and platform[0] != p[0]:
- longestPlatform = platform
- if platform[2] - platform[0] < shortestPlatform[2] - shortestPlatform[0]:
- shortestPlatform = platform
- if platform[2] > farthestPlatform[2]:
- farthestPlatform = platform
- focusHeight = longestPlatform[1] - 0.3 * ScreenHeight
-
- # Step 3: Generate rare pool platform
- poolPlatform = None
- if randint(0, 2) == 0 or Level <= 1:
- poolX = farthestPlatform[2] + int(0.5 * c.maxJumpLength)
- poolY = farthestPlatform[1]
- poolWidth = randint(700, 900)
- poolHeight = 3 * c.maxJumpHeight
- poolPlatform = Pool(poolX, poolY, poolWidth, poolHeight, theme)
- AllMovableObjects.append(poolPlatform)
-
- # Step 4: Generate blocks
- quantityBlocks = numberofplatforms
- sampleBlock = Block(0, 0, 'bonus')
- blockHeight = 2 * c.height + sampleBlock.height
- b = [Block(randint(p[0][0] + 50, p[0][2] - 50), p[0][1] - blockHeight, 'coin')]
- blockplatform = [0]
- keys = []
- for i in range(1, quantityBlocks):
- y = p[i][1] - blockHeight
- if p[i].x != longestPlatform.x and randint(0, 3) != 0:
- x = 0.5 * p[i][0] + 0.5 * p[i][2] + randint(int(-0.4 * p[i].width), int(0.4 * p[i].width))
- b.append(Block(x, y, 'coin'))
- blockplatform.append(i)
- elif p[i].x != longestPlatform.x and not keys:
- x = 0.5 * p[i][0] + 0.5 * p[i][2] + randint(int(-0.4 * p[i].width), int(0.4 * p[i].width))
- b.append(Block(x, y, 'regular'))
- blockplatform.append(i)
- if poolPlatform:
- poolBlock = Block(poolPlatform.poolStartX + poolPlatform.tileWidth,
- poolPlatform.y + poolPlatform.height - blockHeight, 'regular')
- poolBlock.yieldsStar = True
- b.append(poolBlock)
- shuffle(b)
- for block in b:
- if block.form == 'regular' and not keys and not block.yieldsStar:
- key = Key(block[0][0], block[0][1] - 80, 'blue')
- keys.append(key)
- AllMovableObjects.append(key)
- elif block.form == 'regular' and randint(0, 2) == 0:
- block.willExplode = True
- elif block.form == 'regular':
- block.yieldsStar = True
- AllMovableObjects.append(block)
-
- # Step 5: Generate spikes if necessary by first creating a platform to use as a ledge
- spikes = []
- if lvl == 1 or randint(0, 1) == 0:
- ledge = Platform(longestPlatform[0], focusHeight, 0, 0, longestPlatform.width, 'snow')
- p.append(ledge), AllMovableObjects.append(ledge)
- for i in range(ledge[0] + ledge.tileWidth * 2, ledge[2] - ledge.tileWidth * 2, 40):
- spikes.append(FallingSpike(i, ledge[3]))
- for spike in spikes:
- AllMovableObjects.append(spike)
-
- # Step 6: Add foliage to enhance the atmosphere
- foliage = []
- for platform in p:
- for x in range(platform.x, platform.x + platform.width - 100, 100):
- if randint(0, 10) == 0 and Decorations:
- decoration = BackgroundFoliage(x, platform.y)
- decoration.y -= decoration.height
- AllMovableObjects.append(decoration)
- foliage.append(decoration)
-
- # Step 7: Generate mobs
- quantityMobs = len(p) - 1
- mainMobType = 'slime'
- sampleMob = AICharacter(0, 0, 0, 0, (mainMobType, -1, -1))
- mobs = []
- for i in range(0, quantityMobs):
- whichPlatform = randint(1, len(p) - 1)
- while p[whichPlatform][0] == longestPlatform[0]:
- whichPlatform = randint(1, len(p) - 1)
- if randint(0, 1) == 0:
- mobs.append(AICharacter(randint(p[whichPlatform][0], p[whichPlatform][2]),
- p[whichPlatform][3] - sampleMob.height, int(0.7 * c.runSpeed),
- 0, (mainMobType, -1, -1)))
- else:
- mobs.append(AICharacter(randint(p[whichPlatform][0], p[whichPlatform][2]),
- p[whichPlatform][3] - sampleMob.height, int(0.7 * c.runSpeed),
- 0, ('snail', -1, -1)))
- mobs.append(AICharacter(70, p[0][1] - 750, 5, 0, ('fly', p[0][0], farthestPlatform[2])))
- if poolPlatform:
- mobs.append(AICharacter(poolPlatform.poolStartX + poolPlatform.tileWidth, poolPlatform.y +
- poolPlatform.tileWidth, 5, 0, ('fish', -1, -1)))
- for enemy in mobs:
- Enemies.append(enemy)
- AllMovableObjects.append(enemy)
-
- # Step 8: Place a door
- doorX = farthestPlatform[2] - 100
- doorY = farthestPlatform[1]
- door = Door(doorX, doorY)
- AllMovableObjects.append(door)
- propDoor = Door(p[0].x + 10, p[0].y)
- AllMovableObjects.append(propDoor)
-
- # Step 9: Ensure there is a way out of the level
- if not keys:
- key = Key(int(0.5 * (farthestPlatform[0] + farthestPlatform[2])), farthestPlatform[1] - 80, 'blue')
- keys.append(key)
- AllMovableObjects.append(key)
- for key in keys:
- key.visible = False
-
- # Step 10: Move the player to the leftmost platform
- c.x = int(0.5 * p[0][0] + 0.5 * p[0][2])
- c.y = p[0][1] - c.height
-
- # -----------------------------------------------------------------------------------------------------------------
- def loadLevel(self, level):
- fileName = 'levels/data_' + str(level[0]) + '_' + str(level[1]) + \
- '.txt'
- data = open(fileName)
-
-# =====================================================================================================================
-def printText(text, font, colour, coords):
- global ScreenSurface
- textSurf = font.render(text, Antialiasing, colour)
- textRect = textSurf.get_rect()
- textRect.topleft = coords
- ScreenSurface.blit(textSurf, textRect)
- return textRect
-
-# =====================================================================================================================
-def checkForQuit():
- keys = pygame.key.get_pressed()
- if keys[K_ESCAPE]:
- pygame.quit(), sys.exit()
-
-# =====================================================================================================================
-def distance(p0, p1):
- return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
-
-# =====================================================================================================================
-def drawBgrd(environment):
- global bgrdX, bgrdInvX, bgrdY, bgrdWidth, initialBgrdSetup
-
- # Determine correct background
- if environment == 'gloomy':
- bgrd = bgrdGloomy
- bgrdInv = bgrdGloomyInv
- elif environment == 'yellow':
- bgrd = bgrdYellowSky
- bgrdInv = bgrdYellowSkyInv
- elif environment == 'castle':
- bgrd = bgrdCastle
- bgrdInv = bgrdCastleInv
- elif environment == 'desert':
- bgrd = bgrdDesert
- bgrdInv = bgrdDesertInv
- bgrdWidth = pygame.Surface.get_width(bgrd)
-
- # Swap background positions as needed
- if bgrdX < -bgrdWidth:
- bgrdX = bgrdWidth
- elif bgrdX > bgrdWidth:
- bgrdX = -bgrdWidth
- if bgrdInvX < -bgrdWidth:
- bgrdInvX = bgrdWidth
- elif bgrdInvX > bgrdWidth:
- bgrdInvX = -bgrdWidth
-
- # Verify corrent positioning of the backgrounds
- if bgrdX > bgrdInvX:
- bgrdX = bgrdInvX + bgrdWidth
- elif bgrdInvX > bgrdX:
- bgrdInvX = bgrdX + bgrdWidth
-
- # If necessary, perform initial setup
- if initialBgrdSetup:
- initialBgrdSetup = False
- bgrdX, bgrdY = 0, 0
- bgrdInvX = -bgrdWidth
- ScreenSurface.blit(bgrd, (bgrdX, bgrdY))
- ScreenSurface.blit(bgrdInv, (bgrdInvX, bgrdY))
-
-# =====================================================================================================================
-def updateAll():
- global MeasuredFPS, Level
-
- # Draw prop door
- propDoor.update(c, False)
-
- # Update all objects
- if poolPlatform:
- poolPlatform.update()
- for f in foliage:
- f.draw()
- for i in range(0, len(p)):
- p[i].update((0, 0, ScreenWidth, ScreenHeight))
- for i in range(0, len(b)):
- b[i].update(keys)
- for enemy in Enemies:
- enemy.update(p, pygame.event.get(), AllMovableObjects, b, Enemies, c, poolPlatform)
- for spike in spikes:
- spike.update(p, [c] + mobs, b)
- c.update(p, pygame.event.get(), AllMovableObjects, b, Enemies, c, poolPlatform)
- for key in keys:
- key.update(c)
-
- # Draw temporary text
- drawTempText('Level ' + str(Level), mediumFont, white, (ScreenWidth - 150, 50), 8000)
-
- # Check for quit events
- checkForQuit()
-
- # Display developer mode info
- if DeveloperMode:
- videoInfo = pygame.display.Info()
- hardwareAccel = 'False'
- if videoInfo.hw:
- hardwareAccel = 'True'
- vram = 'Unknown'
- if videoInfo.video_mem != 0:
- vram = str(videoInfo.video_mem)
- printText('dx = ' + str(c.Vx), smallFont, white, (DevX, DevY))
- printText('dy = ' + str(c.Vy), smallFont, white, (DevX, DevY + DevSpacing))
- printText('fps = ' + str(round(MeasuredFPS, 1)) + (' (stable)' if StableFPS else ' (unstable)'), smallFont,
- white, (DevX, DevY + 2 * DevSpacing))
- printText('vol = ' + str(100 * round(pygame.mixer.music.get_volume(), 2)) + '%', smallFont, white,
- (DevX, DevY + 3 * DevSpacing))
- printText('onground = True' if c.onGround else 'onground = False', smallFont, white, (DevX, DevY +
- 4 * DevSpacing))
- printText('hw accel = ' + hardwareAccel, smallFont, white, (DevX, DevY + 5 * DevSpacing))
- printText('vram (MB): ' + vram, smallFont, white, (DevX, DevY + 6 * DevSpacing))
- printText('esc to quit', smallFont, white, (DevX, DevY + 7 * DevSpacing))
-
- # Update screen and enforce maximum FPS
- handleFPS()
-
-# =====================================================================================================================
-def drawTitleScreen():
- global ShouldDisplayOptions, MouseX, MouseY, MouseX_Hover, MouseY_Hover, gameStart, c
- whichChar = 0
-
- # Check for quit events
- checkForQuit()
- for event in pygame.event.get():
- if event.type == MOUSEBUTTONDOWN:
- MouseX, MouseY = event.pos
- elif event.type == MOUSEMOTION:
- MouseX_Hover, MouseY_Hover = event.pos
-
- # Fill screen with background
- ScreenSurface.fill(black)
- ScreenSurface.blit(bgrdTitle, origin)
-
- # Print static text
- printText('Welcome to Exit Dash: Hyperion!', genericFont, white, (50, 50))
- printText('Choose a character to begin:', genericFont, white, (math.floor(ScreenWidth / 2) - 350, 150))
-
- # Draw three characters to choose from
- firstCharX = math.floor(ScreenWidth / 4) - 30
- secondCharX = 2 * firstCharX + 80
- thirdCharX = 3 * firstCharX + 190
- charY = math.floor(ScreenHeight / 2) - 50
- firstChar = PlayableCharacter(firstCharX, charY, 0, 0, 1)
- secondChar = PlayableCharacter(secondCharX, charY, 0, 0, 2)
- thirdChar = PlayableCharacter(thirdCharX, charY, 0, 0, 3)
- firstCharRect = pygame.Rect(firstChar.x, firstChar.y, firstChar.width, firstChar.height)
- secondCharRect = pygame.Rect(secondChar.x, secondChar.y, secondChar.width, secondChar.height)
- thirdCharRect = pygame.Rect(thirdChar.x, thirdChar.y, thirdChar.width, thirdChar.height)
- ScreenSurface.blit(firstChar.standingImage, (firstCharX, charY))
- ScreenSurface.blit(secondChar.standingImage, (secondCharX, charY))
- ScreenSurface.blit(thirdChar.standingImage, (thirdCharX, charY))
- if firstCharRect.collidepoint(MouseX_Hover, MouseY_Hover):
- pygame.draw.rect(ScreenSurface, white, firstCharRect, 3)
- printText('Flight Commander Alex', mediumFont, yellow, (firstCharX - 95, charY + firstChar.height + 15))
- else:
- printText('Flight Commander Alex', mediumFont, white, (firstCharX - 95, charY + firstChar.height + 15))
- if secondCharRect.collidepoint(MouseX_Hover, MouseY_Hover):
- pygame.draw.rect(ScreenSurface, white, secondCharRect, 3)
- printText('Astronaut Allan', mediumFont, yellow, (secondCharX - 55, charY + secondChar.height + 15))
- else:
- printText('Astronaut Allan', mediumFont, white, (secondCharX - 55, charY + secondChar.height + 15))
- if thirdCharRect.collidepoint(MouseX_Hover, MouseY_Hover):
- pygame.draw.rect(ScreenSurface, white, thirdCharRect, 3)
- printText('Medical Specialist Lisa', mediumFont, yellow, (thirdCharX - 95, charY + thirdChar.height + 15))
- else:
- printText('Medical Specialist Lisa', mediumFont, white, (thirdCharX - 95, charY + thirdChar.height + 15))
- firstCharacterChosen = firstCharRect.collidepoint(MouseX, MouseY)
- secondCharacterChosen = secondCharRect.collidepoint(MouseX, MouseY)
- thirdCharacterChosen = thirdCharRect.collidepoint(MouseX, MouseY)
- if firstCharacterChosen:
- whichChar = 1
- elif secondCharacterChosen:
- whichChar = 2
- elif thirdCharacterChosen:
- whichChar = 3
-
- # Draw quit button
- quitRect = printText('Quit', genericFont, white,
- (int(ScreenWidth / 2) - 25, ScreenHeight - 200))
- if quitRect.collidepoint(MouseX, MouseY):
- pygame.quit()
- sys.exit()
- if quitRect.collidepoint(MouseX_Hover, MouseY_Hover):
- printText('Quit', genericFont, yellow, (int(ScreenWidth / 2) - 25, ScreenHeight - 200))
-
- # Draw settings button
- settingsRect = printText('Options', genericFont, white, (int(ScreenWidth / 2) - 60, ScreenHeight - 100))
- if settingsRect.collidepoint(MouseX, MouseY):
- ShouldDisplayOptions = True
- if settingsRect.collidepoint(MouseX_Hover, MouseY_Hover):
- printText('Options', genericFont, yellow, (int(ScreenWidth / 2) - 60, ScreenHeight - 100))
- while ShouldDisplayOptions:
- drawOptionsMenu()
-
- # Enter game if a character is chosen
- if firstCharacterChosen or secondCharacterChosen or thirdCharacterChosen:
- c = PlayableCharacter(0, 0, 0, 0, whichChar)
- return True
-
- return False
-
-# =====================================================================================================================
-def drawTempText(text, font, colour, coords, time):
- global textTimer
-
- # Set the timer
- timeElapsed = pygame.time.get_ticks()
- if textTimer == 0:
- textTimer = timeElapsed
-
- # Draw text if applicable
- if timeElapsed - textTimer < time:
- printText(text, font, colour, coords)
- return True
- else:
- return False
-
-# =====================================================================================================================
-def handleFPS():
- global MeasuredFPS, FPS
- pygame.display.update(pygame.Rect(0, 0, ScreenWidth, ScreenHeight))
- if StableFPS:
- FPSClock.tick_busy_loop(FPS)
- else:
- FPSClock.tick(FPS)
- MeasuredFPS = FPSClock.get_fps()
-
-# =====================================================================================================================
-def showGameOverScreen(won):
- ScreenSurface.blit(bgrdTitle, origin)
- outcome = 'win' if won else 'lose'
- printText('Game Over! You ' + outcome + '.', genericFont, white, (50, 50))
- printText(str(c.coins) + ' coins', mediumFont, white, (50, 100))
- printText(str(c.lives) + ' lives left', mediumFont, white, (50, 150))
- printText(str(int(pygame.time.get_ticks() / 1000)) + ' seconds', mediumFont, white, (50, 200))
- printText('TOTAL SCORE: ' + str(int(c.coins + 100 * c.lives - 0.1 * pygame.time.get_ticks() / 1000)), mediumFont,
- white, (50, 250))
- printText('Esc to Quit', mediumFont, white, (50, 300))
- keys = pygame.key.get_pressed()
- while not keys[K_ESCAPE]:
- keys = pygame.key.get_pressed()
- handleFPS()
- pygame.quit()
- sys.exit()
-
-# =====================================================================================================================
-def drawToggle(name, coords, mousepos, mousehoverpos, on=True):
- # Draw the text for the toggle and save the rects
- mainText = printText(name, mediumFont, white, coords)
- onText = printText('ON', smallFont, white, (mainText.right + 50, coords[1] + 10))
- slash = printText(' / ', smallFont, white, (onText.right + 5, coords[1] + 10))
- offText = printText('OFF', smallFont, white, (slash.right + 5, coords[1] + 10))
-
- # Make the ON/OFF text yellow if it is the selected option or if the mouse hovers over it
- if onText.collidepoint(mousehoverpos[0], mousehoverpos[1]) or on:
- onText = printText('ON', smallFont, yellow, (mainText.right + 50, coords[1] + 10))
- if offText.collidepoint(mousehoverpos[0], mousehoverpos[1]) or not on:
- offText = printText('OFF', smallFont, yellow, (slash.right + 5, coords[1] + 10))
-
- # Return a toggle output
- if onText.collidepoint(mousepos[0], mousepos[1]):
- return True
- elif offText.collidepoint(mousepos[0], mousepos[1]):
- return False
- return DefaultValue
-
-# =====================================================================================================================
-def drawOptionsMenu():
- global MeasuredFPS, DeveloperMode, ShouldDisplayOptions, MouseX, MouseY, MouseX_Hover, MouseY_Hover, Antialiasing, \
- StableFPS, Decorations
- ShouldDisplayOptions = True
-
- # Fill screen with background
- ScreenSurface.fill(black)
- ScreenSurface.blit(bgrdTitle, origin)
-
- # Get mouse status
- for event in pygame.event.get():
- if event.type == MOUSEBUTTONDOWN:
- MouseX, MouseY = event.pos
- elif event.type == MOUSEMOTION:
- MouseX_Hover, MouseY_Hover = event.pos
-
- # Draw title
- printText('Exit Dash: Hyperion | Options Menu', genericFont, white, (int(ScreenWidth / 2) - 420, 50))
-
- # Draw toggles
- devModeToggle = drawToggle('Debug Info', (math.ceil(0.25 * ScreenWidth), 150), (MouseX, MouseY),
- (MouseX_Hover, MouseY_Hover), DeveloperMode)
- aaToggle = drawToggle('Anti-aliasing', (math.ceil(0.25 * ScreenWidth), 200), (MouseX, MouseY), (MouseX_Hover,
- MouseY_Hover), Antialiasing)
- sFPSToggle = drawToggle('Stabilize Framerate', (math.ceil(0.5 * ScreenWidth), 150), (MouseX, MouseY), (MouseX_Hover,
- MouseY_Hover), StableFPS)
- decorationToggle = drawToggle('Visual Details', (math.ceil(0.5 * ScreenWidth), 200), (MouseX, MouseY),
- (MouseX_Hover, MouseY_Hover), Decorations)
-
- # Update global variables with the values from the toggles
- if devModeToggle != DefaultValue:
- DeveloperMode = devModeToggle
- if aaToggle != DefaultValue:
- Antialiasing = aaToggle
- if sFPSToggle != DefaultValue:
- StableFPS = sFPSToggle
- if decorationToggle != DefaultValue:
- Decorations = decorationToggle
-
- # Draw quit button
- quitRect = printText('Return to Menu', genericFont, white, (int(ScreenWidth / 2) - 185, ScreenHeight - 150))
- if quitRect.collidepoint(MouseX_Hover, MouseY_Hover):
- quitRect = printText('Return to Menu', genericFont, yellow, (int(ScreenWidth / 2) - 185, ScreenHeight - 150))
- if quitRect.collidepoint(MouseX, MouseY):
- ShouldDisplayOptions = False
-
- # Update display
- handleFPS()
-
-# =====================================================================================================================
-def main():
- global FPSClock, Level, MeasuredFPS, door, c, gameStart, textTimer
- ld = LevelData()
- textTimer = 0
- gameStart = False
- pygame.mixer.music.load('music' + os.sep + 'disconnected_jukeri12.ogg')
- pygame.mixer.music.set_volume(1.0)
- pygame.mixer.music.play(-1)
-
- while Level == 0:
- if drawTitleScreen():
- ld.generateRandomLevel('stone', 10, 1)
- pygame.mixer.music.load('music' + os.sep + 'artblock_jan125.ogg')
- pygame.mixer.music.set_volume(1.0)
- pygame.mixer.music.play(-1)
- Level = 1
-
- pygame.display.update()
- handleFPS()
-
- while Level == 1:
- ScreenSurface.fill(white)
- drawBgrd('castle')
- shouldAdvanceLevel = door.update(c)
- updateAll()
- if shouldAdvanceLevel:
- printText('Loading Level ' + str(Level + 1), mediumFont, white, (50, ScreenHeight - 50))
- Level += 1
- pygame.time.wait(TimeBetweenLevels)
- ld.generateRandomLevel('stone', 20, 2)
-
- while Level == 2:
- ScreenSurface.fill(white)
- drawBgrd('castle')
- shouldAdvanceLevel = door.update(c)
- updateAll()
- if shouldAdvanceLevel:
- printText('Loading Level ' + str(Level + 1), mediumFont, white, (50, ScreenHeight - 50))
- Level += 1
- pygame.time.wait(TimeBetweenLevels)
- ld.generateRandomLevel('stone', 25, 3)
-
-# =====================================================================================================================
-if __name__ == '__main__':
- main()
-
-
-
-
-
-
-
-
-
diff --git a/README.md b/README.md
index 3537d67..f727073 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,52 @@
-# exit-dash-hyperion
+# Exit Dash: Hyperion
-2D platformer
+A 2D platformer, originally written in 2014 (Python 2 + pygame 1.9.3) and modernized to
+run on **Python 3.12+** with **[pygame-ce](https://pyga.me/)** across macOS, Linux, and
+Windows.
-## Instructions to Play
+Rebuilt with a scene manager, a fixed-timestep simulation, dataclasses and full type
+hints. See [CLAUDE.md](CLAUDE.md) for the architecture and the (small) list of original
+features not yet re-ported (options menu, level editor).
-1. `pip install -r requirements.txt` to obtain Pygame
+## Play
-2. `python MainGame.py` to run the game in full screen
+You need [uv](https://docs.astral.sh/uv/) (it manages Python and the dependencies for you):
+```sh
+git clone https://github.com/burincode/exit-dash-hyperion
+cd exit-dash-hyperion
+uv run exit-dash-hyperion
+```
+Run in a window instead of fullscreen:
+
+```sh
+uv run exit-dash-hyperion --windowed
+```
+
+### Controls
+
+| Action | Keys |
+| ------ | ---- |
+| Move | ← / → |
+| Jump | ↑ or Space |
+| Duck | ↓ |
+| Quit | Esc or Q |
+
+## Development
+
+```sh
+uv sync --all-extras # create the venv and install dev tools
+uv run pre-commit install # enable lint/format on commit
+uv run pytest # tests (headless)
+uv run ruff check . && uv run ruff format --check .
+uv run mypy src
+```
+
+Tests, lint, format, type-check, and a headless smoke run are enforced in CI across
+{macOS, Linux, Windows} × Python {3.12, 3.13, 3.14}.
+
+## License
+
+Code is MIT (see [LICENSE](LICENSE)). Art, audio, and fonts are third-party assets under
+CC0 / open licenses — see [CREDITS.md](CREDITS.md).
diff --git a/RunGame.py b/RunGame.py
deleted file mode 100644
index 1c8e2c3..0000000
--- a/RunGame.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# coding=utf-8
-##############################################################################
-# Programmer: Kenneth Sinder
-# Date: 9-Mar-2014
-# Filename: RunGame.py
-# Description: The launching point for Exit Dash: Hyperion (a 2D Platform Game)
-##############################################################################
-# TODO: add ending, add bosses, add underground and dynamic levels, add final theme
-
-from data.game import *
-if __name__ == '__main__':
- g = Game(SMOOTHFPS)
- g.executeGameLoop()
-
-
-
-
-
-
-
-
-
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index 0689e24..0000000
--- a/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# Directory initialization
\ No newline at end of file
diff --git a/aicharacter.py b/aicharacter.py
deleted file mode 100644
index 512a088..0000000
--- a/aicharacter.py
+++ /dev/null
@@ -1,210 +0,0 @@
-# coding=utf-8
-import pygame, math
-from character import Character
-
-class AICharacter(Character):
-
- def __init__(self, x, y, Vx, Vy, properties=('slime', -1, -1)):
- # Properties should be a tuple of the form (STRING mobName, INT leftLimit,
- # INT rightLimit) where leftLimit and rightLimit can be -1 to remove the limit
- self.mobType = properties[0]
- self.limit = [properties[1], properties[2]]
-
- # Call base class implementation
- Character.__init__(self, x, y, Vx, Vy)
-
- # Load images
- self.slimeDL = pygame.image.load('enemies\\slime\\slimeGreen_squashed.png').convert_alpha()
- self.slimeDR = pygame.image.load('enemies\\slime\\slimeGreen_squashedR.png').convert_alpha()
- self.slimeL = pygame.image.load('enemies\\slime\\slimeGreen_walk.png').convert_alpha()
- self.slimeR = pygame.image.load('enemies\\slime\\slimeGreen_walkR.png').convert_alpha()
- self.flyDL = pygame.image.load('enemies\\fly\\fly_dead.png').convert_alpha()
- self.flyDR = pygame.image.load('enemies\\fly\\fly_dead_r.png').convert_alpha()
- self.flyL = pygame.image.load('enemies\\fly\\fly_fly.png').convert_alpha()
- self.flyR = pygame.image.load('enemies\\fly\\fly_fly_r.png').convert_alpha()
- self.fishDL = pygame.image.load('enemies\\other\\fishDead.png').convert_alpha()
- self.fishDR = pygame.image.load('enemies\\other\\fishDead_r.png').convert_alpha()
- self.fishL1 = pygame.image.load('enemies\\other\\fishSwim1.png').convert_alpha()
- self.fishL2 = pygame.image.load('enemies\\other\\fishSwim2.png').convert_alpha()
- self.fishR1 = pygame.image.load('enemies\\other\\fishSwim1R.png').convert_alpha()
- self.fishR2 = pygame.image.load('enemies\\other\\fishSwim2R.png').convert_alpha()
- self.snailL1 = pygame.image.load('enemies\\other\\snailWalk1.png').convert_alpha()
- self.snailL2 = pygame.image.load('enemies\\other\\snailWalk2.png').convert_alpha()
- self.snailR1 = pygame.image.load('enemies\\other\\snailWalk1R.png').convert_alpha()
- self.snailR2 = pygame.image.load('enemies\\other\\snailWalk2R.png').convert_alpha()
- self.snailDL = pygame.image.load('enemies\\other\\snailShell.png').convert_alpha()
- self.snailDR = pygame.image.load('enemies\\other\\snailShellR.png').convert_alpha()
-
- # Other control variables
- self.originalHeight = y
- self.alive = True
- self.health = 1
- self.gravity = 1
- self.runSpeed = abs(self.Vx)
- self.currentStep = 0
- self.takenAction = False
-
- # --------------------------------------------------------------------------------------------------------------
-
- def distance(self, p0, p1):
- return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateAI(self, platforms, mainChar, blocks):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Determine direction for draw() method
- if self.Vx > 0:
- self.direction = 1
- elif self.Vx < 0:
- self.direction = 0
-
- # Check if character is still alive
- if self.health <= 0:
- self.alive = False
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0][3] - platforms[0][1] - 5
-
- # Apply gravity if necessary
- if self.onGround:
- self.Vy = 0
- elif ((self.mobType == 'fly' and not self.alive) or self.mobType != 'fly') and (self.mobType != 'fish' or
- (self.mobType == 'fish' and not self.alive)):
- self.Vy += self.gravity
-
- # Keep character within bounds
- if self.limit[0] != -1 and self.x <= self.limit[0]:
- self.x += self.runSpeed
- self.Vx = abs(self.Vx)
- if self.limit[1] != -1 and self.x >= self.limit[1]:
- self.x -= self.runSpeed
- self.Vx = -abs(self.Vx)
-
- # Switch to a dead state if close to explosion
- explosionRadius = 400
- for block in blocks:
- distanceFromBlock = self.distance((self.x + 0.5 * self.width, self.y + 0.5 * self.height),
- (block.x + 0.5 * block.width, block.y + 0.5 * block.height))
- if block.disabled and block.willExplode and block.explosionStep == 1 and \
- distanceFromBlock < explosionRadius:
- self.health = 0
-
- # Prevent AI from falling off the lowest platform
- if self.mobType == 'slime' or self.mobType == 'snail':
- testXLeft = self.x - 20
- testXRight = self.x + 20 + self.width
- lowestPlatLeft = platforms[self.lowestPlatform][0]
- lowestPlatRight = platforms[self.lowestPlatform][2]
- onLowestPlatform = self.currentPlatform == self.lowestPlatform
- if onLowestPlatform and testXLeft <= lowestPlatLeft and self.Vx < 0:
- self.x += self.runSpeed
- self.Vx *= -1
- elif onLowestPlatform and testXRight >= lowestPlatRight and self.Vx > 0:
- self.x -= self.runSpeed
- self.Vx *= -1
-
- # Implement simple AI
- if self.mobType == 'slime' or self.mobType == 'snail':
- platformsBelowSelf = []
- currentPlatformHeight = platforms[self.currentPlatform][1]
- limitBackup = [self.limit[0], self.limit[1]]
- self.limit[0] = platforms[self.currentPlatform][0] + 5
- self.limit[1] = platforms[self.currentPlatform][2] - 40
- safePlatformDropLeft, safePlatformDropRight = False, False
- for i in range(0, len(platforms)):
- if platforms[i][1] > currentPlatformHeight:
- platformsBelowSelf.append(platforms[i])
- for platform in platformsBelowSelf:
- if platform[0] < platforms[self.currentPlatform][0] < platform[2]:
- safePlatformDropLeft = True
- if platform[0] < platforms[self.currentPlatform][2] and platform[2] > platforms[self.currentPlatform][
- 2]:
- safePlatformDropRight = True
- if safePlatformDropLeft:
- self.limit[0] = limitBackup[0]
- if safePlatformDropRight:
- self.limit[1] = limitBackup[1]
- elif self.mobType == 'fly' and self.alive:
- self.limit[0] = platforms[0][0]
- for i in range(0, len(platforms)):
- if self.x + self.width + 5 >= platforms[i][0] and self.x <= platforms[i][2] and \
- platforms[i][1] <= self.y <= platforms[i][3]:
- self.limit[1] = platforms[i][0]
- self.Vx *= -1
- self.x -= self.runSpeed
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool, surface):
- # Collide with other objects
- Character.collide(self, platforms, blocks, aiCharacters, pool)
-
- # Update motion and AI actions
- self.updateAI(platforms, mainChar, blocks)
-
- # Draw correct character
- self.draw(surface)
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, surface):
- # Determine the correct image to use
- if self.mobType == 'slime':
- imageL1 = imageL2 = self.slimeL
- imageR1 = imageR2 = self.slimeR
- imageDL = self.slimeDL
- imageDR = self.slimeDR
- elif self.mobType == 'fly':
- imageL1 = imageL2 = self.flyL
- imageR1 = imageR2 = self.flyR
- imageDL = self.flyDL
- imageDR = self.flyDR
- elif self.mobType == 'fish':
- imageL1 = self.fishL1
- imageL2 = self.fishL2
- imageR1 = self.fishR1
- imageR2 = self.fishR2
- imageDL = self.fishDL
- imageDR = self.fishDR
- elif self.mobType == 'snail':
- imageL1 = self.snailL1
- imageL2 = self.snailL2
- imageR1 = self.snailR1
- imageR2 = self.snailR2
- imageDL = self.snailDL
- imageDR = self.snailDR
-
- # Get image widths and heights
- self.width = pygame.Surface.get_width(imageL1)
- self.height = pygame.Surface.get_height(imageL1)
- deadWidth = pygame.Surface.get_width(imageDL)
- deadHeight = pygame.Surface.get_height(imageDL)
-
- # Increment the walking/moving frame
- footstepRarity = 1
- if pygame.time.get_ticks() % footstepRarity == 0:
- self.walkFrame += 1
- if self.walkFrame > 1:
- self.walkFrame = 0
-
- if self.direction == 1 and self.alive and self.walkFrame == 0:
- surface.blit(imageR1, (self.x, self.y))
- elif self.direction == 0 and self.alive and self.walkFrame == 0:
- surface.blit(imageL1, (self.x, self.y))
- elif self.direction == 1 and self.alive and self.walkFrame == 1:
- surface.blit(imageR2, (self.x, self.y))
- elif self.direction == 0 and self.alive and self.walkFrame == 1:
- surface.blit(imageL2, (self.x, self.y))
- elif self.direction == 1 and not self.alive:
- surface.blit(imageDR, (self.x, self.y))
- elif self.direction == 0 and not self.alive:
- surface.blit(imageDL, (self.x, self.y))
-
- # Recalculate the image width and height, and stop horizontal motion if the AI char is dead
- if not self.alive:
- self.width = deadWidth
- self.height = deadHeight
- self.Vx = 0
- # -----------------------------------------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/backgroundfoliage.py b/backgroundfoliage.py
deleted file mode 100644
index d4fcd53..0000000
--- a/backgroundfoliage.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# coding=utf-8
-import pygame
-from game import *
-
-class BackgroundFoliage(object):
-
- def __init__(self, x, y):
- self.x = x
- self.y = y
-
- # Images
- self.whichProp = randint(0, 2)
- self.hill = pygame.image.load('environment\\main\\hill_small.png').convert_alpha()
- self.bush = pygame.image.load('items\\bush.png').convert_alpha()
- self.rock = pygame.image.load('items\\rock.png').convert_alpha()
- self.image = self.hill
- if self.whichProp == 1:
- self.image = self.bush
- elif self.whichProp == 2:
- self.image = self.rock
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
-
-# -----------------------------------------------------------------------------------------------------------------
- def draw(self, surface):
- surface.blit(self.image, (self.x, self.y))
\ No newline at end of file
diff --git a/backgrounds/crossover/blue_sky.jpg b/backgrounds/crossover/blue_sky.jpg
deleted file mode 100644
index 157c187..0000000
Binary files a/backgrounds/crossover/blue_sky.jpg and /dev/null differ
diff --git a/backgrounds/crossover/blue_sky_inverted.jpg b/backgrounds/crossover/blue_sky_inverted.jpg
deleted file mode 100644
index e8f94dc..0000000
Binary files a/backgrounds/crossover/blue_sky_inverted.jpg and /dev/null differ
diff --git a/backgrounds/crossover/red_sky.jpg b/backgrounds/crossover/red_sky.jpg
deleted file mode 100644
index 89f29e2..0000000
Binary files a/backgrounds/crossover/red_sky.jpg and /dev/null differ
diff --git a/backgrounds/crossover/red_sky_inverted.jpg b/backgrounds/crossover/red_sky_inverted.jpg
deleted file mode 100644
index 673f7cb..0000000
Binary files a/backgrounds/crossover/red_sky_inverted.jpg and /dev/null differ
diff --git a/backgrounds/crossover/space.jpg b/backgrounds/crossover/space.jpg
deleted file mode 100644
index 60f4fc7..0000000
Binary files a/backgrounds/crossover/space.jpg and /dev/null differ
diff --git a/backgrounds/crossover/town.jpg b/backgrounds/crossover/town.jpg
deleted file mode 100644
index 9d063af..0000000
Binary files a/backgrounds/crossover/town.jpg and /dev/null differ
diff --git a/backgrounds/crossover/yellow-sky-inverted.jpg b/backgrounds/crossover/yellow-sky-inverted.jpg
deleted file mode 100644
index 60d5b99..0000000
Binary files a/backgrounds/crossover/yellow-sky-inverted.jpg and /dev/null differ
diff --git a/backgrounds/crossover/yellow-sky.jpg b/backgrounds/crossover/yellow-sky.jpg
deleted file mode 100644
index 26be3a6..0000000
Binary files a/backgrounds/crossover/yellow-sky.jpg and /dev/null differ
diff --git a/backgrounds/main/BG_NEW.png b/backgrounds/main/BG_NEW.png
deleted file mode 100644
index 9138490..0000000
Binary files a/backgrounds/main/BG_NEW.png and /dev/null differ
diff --git a/backgrounds/main/BG_only.png b/backgrounds/main/BG_only.png
deleted file mode 100644
index cb92968..0000000
Binary files a/backgrounds/main/BG_only.png and /dev/null differ
diff --git a/backgrounds/main/BKG_M0A061.jpg b/backgrounds/main/BKG_M0A061.jpg
deleted file mode 100644
index ea85b5d..0000000
Binary files a/backgrounds/main/BKG_M0A061.jpg and /dev/null differ
diff --git a/backgrounds/main/Background (2).png b/backgrounds/main/Background (2).png
deleted file mode 100644
index 05d0f5f..0000000
Binary files a/backgrounds/main/Background (2).png and /dev/null differ
diff --git a/backgrounds/main/Background (3).png b/backgrounds/main/Background (3).png
deleted file mode 100644
index 84a5733..0000000
Binary files a/backgrounds/main/Background (3).png and /dev/null differ
diff --git a/backgrounds/main/Background (4).png b/backgrounds/main/Background (4).png
deleted file mode 100644
index 08a688b..0000000
Binary files a/backgrounds/main/Background (4).png and /dev/null differ
diff --git a/backgrounds/main/Background (5).png b/backgrounds/main/Background (5).png
deleted file mode 100644
index fa5c3e8..0000000
Binary files a/backgrounds/main/Background (5).png and /dev/null differ
diff --git a/backgrounds/main/Background.png b/backgrounds/main/Background.png
deleted file mode 100644
index cb0c4ce..0000000
Binary files a/backgrounds/main/Background.png and /dev/null differ
diff --git a/backgrounds/main/G049_OT000_002A__background.png b/backgrounds/main/G049_OT000_002A__background.png
deleted file mode 100644
index 594bc7b..0000000
Binary files a/backgrounds/main/G049_OT000_002A__background.png and /dev/null differ
diff --git a/backgrounds/main/G104_OT000_002A_background.jpg b/backgrounds/main/G104_OT000_002A_background.jpg
deleted file mode 100644
index dd05a55..0000000
Binary files a/backgrounds/main/G104_OT000_002A_background.jpg and /dev/null differ
diff --git a/backgrounds/main/G110_OT000_005A_G110_OT000_01A_background.jpg b/backgrounds/main/G110_OT000_005A_G110_OT000_01A_background.jpg
deleted file mode 100644
index d3f5ff5..0000000
Binary files a/backgrounds/main/G110_OT000_005A_G110_OT000_01A_background.jpg and /dev/null differ
diff --git a/backgrounds/main/G112_OT000_002A_background.jpg b/backgrounds/main/G112_OT000_002A_background.jpg
deleted file mode 100644
index d0cc99d..0000000
Binary files a/backgrounds/main/G112_OT000_002A_background.jpg and /dev/null differ
diff --git a/backgrounds/main/G152_OT000_002A_background.jpg b/backgrounds/main/G152_OT000_002A_background.jpg
deleted file mode 100644
index 0705327..0000000
Binary files a/backgrounds/main/G152_OT000_002A_background.jpg and /dev/null differ
diff --git a/backgrounds/main/G153_OT000_002A_background.jpg b/backgrounds/main/G153_OT000_002A_background.jpg
deleted file mode 100644
index 129c6eb..0000000
Binary files a/backgrounds/main/G153_OT000_002A_background.jpg and /dev/null differ
diff --git a/backgrounds/main/G154_OT000_002A__background.png b/backgrounds/main/G154_OT000_002A__background.png
deleted file mode 100644
index a3aee0e..0000000
Binary files a/backgrounds/main/G154_OT000_002A__background.png and /dev/null differ
diff --git a/backgrounds/main/Tidal-Tally_2048x1536px_2.png b/backgrounds/main/Tidal-Tally_2048x1536px_2.png
deleted file mode 100644
index a5fb48f..0000000
Binary files a/backgrounds/main/Tidal-Tally_2048x1536px_2.png and /dev/null differ
diff --git a/backgrounds/main/aquatiled_jordan_irwin.png b/backgrounds/main/aquatiled_jordan_irwin.png
deleted file mode 100644
index 4d69d91..0000000
Binary files a/backgrounds/main/aquatiled_jordan_irwin.png and /dev/null differ
diff --git a/backgrounds/main/bg1.png b/backgrounds/main/bg1.png
deleted file mode 100644
index e5d6d13..0000000
Binary files a/backgrounds/main/bg1.png and /dev/null differ
diff --git a/backgrounds/main/bg_castle.png b/backgrounds/main/bg_castle.png
deleted file mode 100644
index d9706b8..0000000
Binary files a/backgrounds/main/bg_castle.png and /dev/null differ
diff --git a/backgrounds/main/bg_castle_inv.png b/backgrounds/main/bg_castle_inv.png
deleted file mode 100644
index 596898f..0000000
Binary files a/backgrounds/main/bg_castle_inv.png and /dev/null differ
diff --git a/backgrounds/main/bg_desert.png b/backgrounds/main/bg_desert.png
deleted file mode 100644
index 47823ed..0000000
Binary files a/backgrounds/main/bg_desert.png and /dev/null differ
diff --git a/backgrounds/main/bg_desert_inv.png b/backgrounds/main/bg_desert_inv.png
deleted file mode 100644
index f028804..0000000
Binary files a/backgrounds/main/bg_desert_inv.png and /dev/null differ
diff --git a/backgrounds/main/bg_grasslands.png b/backgrounds/main/bg_grasslands.png
deleted file mode 100644
index 1d2adce..0000000
Binary files a/backgrounds/main/bg_grasslands.png and /dev/null differ
diff --git a/backgrounds/main/bg_grasslands_inv.png b/backgrounds/main/bg_grasslands_inv.png
deleted file mode 100644
index 1bfb173..0000000
Binary files a/backgrounds/main/bg_grasslands_inv.png and /dev/null differ
diff --git a/backgrounds/main/bg_shroom.png b/backgrounds/main/bg_shroom.png
deleted file mode 100644
index 886aac6..0000000
Binary files a/backgrounds/main/bg_shroom.png and /dev/null differ
diff --git a/backgrounds/main/bg_shroom_inv.png b/backgrounds/main/bg_shroom_inv.png
deleted file mode 100644
index 829cd98..0000000
Binary files a/backgrounds/main/bg_shroom_inv.png and /dev/null differ
diff --git a/backgrounds/main/blue_sky.jpg b/backgrounds/main/blue_sky.jpg
deleted file mode 100644
index 157c187..0000000
Binary files a/backgrounds/main/blue_sky.jpg and /dev/null differ
diff --git a/backgrounds/main/blue_sky_inverted.jpg b/backgrounds/main/blue_sky_inverted.jpg
deleted file mode 100644
index e8f94dc..0000000
Binary files a/backgrounds/main/blue_sky_inverted.jpg and /dev/null differ
diff --git a/backgrounds/main/city.png b/backgrounds/main/city.png
deleted file mode 100644
index b1efd57..0000000
Binary files a/backgrounds/main/city.png and /dev/null differ
diff --git a/backgrounds/main/liquid-planet-blue-sky.jpg b/backgrounds/main/liquid-planet-blue-sky.jpg
deleted file mode 100644
index d4faf08..0000000
Binary files a/backgrounds/main/liquid-planet-blue-sky.jpg and /dev/null differ
diff --git a/backgrounds/main/red_sky.jpg b/backgrounds/main/red_sky.jpg
deleted file mode 100644
index 89f29e2..0000000
Binary files a/backgrounds/main/red_sky.jpg and /dev/null differ
diff --git a/backgrounds/main/red_sky_inverted.jpg b/backgrounds/main/red_sky_inverted.jpg
deleted file mode 100644
index 673f7cb..0000000
Binary files a/backgrounds/main/red_sky_inverted.jpg and /dev/null differ
diff --git a/backgrounds/main/seabed.png b/backgrounds/main/seabed.png
deleted file mode 100644
index 71588da..0000000
Binary files a/backgrounds/main/seabed.png and /dev/null differ
diff --git a/backgrounds/main/space.jpg b/backgrounds/main/space.jpg
deleted file mode 100644
index 60f4fc7..0000000
Binary files a/backgrounds/main/space.jpg and /dev/null differ
diff --git a/backgrounds/main/space_inv.jpg b/backgrounds/main/space_inv.jpg
deleted file mode 100644
index 2e194d7..0000000
Binary files a/backgrounds/main/space_inv.jpg and /dev/null differ
diff --git a/backgrounds/main/title_bgrd_compressed.png b/backgrounds/main/title_bgrd_compressed.png
deleted file mode 100644
index b3bd2d8..0000000
Binary files a/backgrounds/main/title_bgrd_compressed.png and /dev/null differ
diff --git a/backgrounds/main/town.jpg b/backgrounds/main/town.jpg
deleted file mode 100644
index 9d063af..0000000
Binary files a/backgrounds/main/town.jpg and /dev/null differ
diff --git a/backgrounds/main/tyre-recycling_bg_2048x1536.png b/backgrounds/main/tyre-recycling_bg_2048x1536.png
deleted file mode 100644
index 753a9bb..0000000
Binary files a/backgrounds/main/tyre-recycling_bg_2048x1536.png and /dev/null differ
diff --git a/backgrounds/main/yellow-sky-inverted.jpg b/backgrounds/main/yellow-sky-inverted.jpg
deleted file mode 100644
index 60d5b99..0000000
Binary files a/backgrounds/main/yellow-sky-inverted.jpg and /dev/null differ
diff --git a/backgrounds/main/yellow-sky.jpg b/backgrounds/main/yellow-sky.jpg
deleted file mode 100644
index 26be3a6..0000000
Binary files a/backgrounds/main/yellow-sky.jpg and /dev/null differ
diff --git a/backgrounds/unused/logo.bmp b/backgrounds/unused/logo.bmp
deleted file mode 100644
index a42fdff..0000000
Binary files a/backgrounds/unused/logo.bmp and /dev/null differ
diff --git a/backgrounds/unused/logo.jpg b/backgrounds/unused/logo.jpg
deleted file mode 100644
index 5555e36..0000000
Binary files a/backgrounds/unused/logo.jpg and /dev/null differ
diff --git a/block.py b/block.py
deleted file mode 100644
index f4ba17c..0000000
--- a/block.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# coding=utf-8
-import pygame
-from game import *
-
-class Block(object):
- def __init__(self, x, y, form):
- # The argument for the "form" parameter should be one of the following strings:
- # 'locked'/'coin'/'regular'/'explosive'
- self.form = form
-
- # Initialize position
- self.x = x
- self.y = y
-
- # Load images
- self.lockedImage = pygame.image.load('environment\\main\\lock_blue.png').convert_alpha()
- self.coinBlockImage = pygame.image.load('environment\\main\\boxCoin.png').convert_alpha()
- self.coinBlockUsedImage = pygame.image.load('environment\\main\\boxCoin_disabled.png').convert_alpha()
- self.explosiveImage = pygame.image.load('environment\\main\\boxExplosive.png').convert_alpha()
- self.explosiveUsedImage = pygame.image.load('environment\\main\\boxExplosive_disabled.png').convert_alpha()
- self.regularImage = pygame.image.load('environment\\main\\boxItem.png').convert_alpha()
- self.regularUsedImage = pygame.image.load('environment\\main\\boxItem_disabled.png').convert_alpha()
- self.explosion = []
- for i in range(0, 3):
- explosionImage = pygame.image.load('environment\\main\\explosion' + str(i) + '.png').convert_alpha()
- explosionImage = pygame.transform.scale2x(explosionImage)
- self.explosion.append(explosionImage)
- self.width = pygame.Surface.get_width(self.regularImage)
- self.height = pygame.Surface.get_height(self.regularImage)
-
- # Load sounds
- self.explosionSfx = pygame.mixer.Sound('sounds\\synthetic_explosion_1.ogg')
-
- # Coin images and variables
- self.coinImage = pygame.image.load('environment\\main\\coinGold.png').convert_alpha()
- self.coinWidth = pygame.Surface.get_width(self.coinImage)
- self.coinHeight = pygame.Surface.get_height(self.coinImage)
- self.coinPos = [self.x - 15, self.y - self.coinHeight + 10,
- self.x + self.coinWidth - 15, self.y + 10]
- self.coinVisible = False
-
- # Other images and related variables
- self.starImage = pygame.image.load('items\\star.png').convert_alpha()
- self.starWidth = pygame.Surface.get_width(self.starImage)
- self.starHeight = pygame.Surface.get_height(self.starImage)
-
- # Other variables to track state of block
- self.disabled = False
- self.willExplode = False
- self.yieldsStar = False
- if self.form == 'explosive':
- self.willExplode = True
- self.explosionStep = 0
-
- # -----------------------------------------------------------------------------------------------------------------
- def __getitem__(self, i):
- if i == 0:
- return self.x, self.y, self.x + self.width, self.y + self.height
- else:
- return self.coinPos[i - 1]
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, keys, surface):
- self.updateState()
- self.draw(keys, surface)
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateState(self):
- self.coinPos = [self.x - 15, self.y - self.coinHeight + 10,
- self.x + self.coinWidth - 15, self.y + 10]
-
- # -----------------------------------------------------------------------------------------------------------------
- def disable(self):
- self.coinVisible = True
- self.disabled = True
-
- # -----------------------------------------------------------------------------------------------------------------
- def killcoin(self):
- self.coinVisible = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, keys, surface):
-
- # Draw the correct type of block
- if self.form == 'locked':
- image = self.lockedImage
- elif self.form == 'coin' and self.disabled:
- image = self.coinBlockUsedImage
- elif self.form == 'coin' and not self.disabled:
- image = self.coinBlockImage
- elif self.form == 'regular' and self.disabled:
- image = self.regularUsedImage
- elif self.form == 'regular' and not self.disabled:
- image = self.regularImage
- elif self.form == 'explosive' and self.disabled:
- image = self.explosiveUsedImage
- elif self.form == 'explosive' and not self.disabled:
- image = self.explosiveImage
- else:
- image = self.regularImage
- surface.blit(image, (self.x, self.y))
-
- # Draw any coins or other objects that may be present
- if self.form == 'coin':
- for i in range(0, len(self.coinPos)):
- if self.coinVisible:
- surface.blit(self.coinImage, (self.coinPos[0], self.coinPos[1]))
- if self.form == 'regular':
- for key in keys:
- if self.coinVisible and self.disabled and distance((self.x, self.y), (key.x, key.y)) < 1.5 * key.height:
- key.visible = True
- self.coinVisible = False
- if self.willExplode and self.disabled:
- if randint(0, 2) == 0 and self.explosionStep < len(self.explosion):
- self.explosionStep += 1
- if self.explosionStep < len(self.explosion):
- surface.blit(self.explosion[self.explosionStep], (self.x - 65, self.y - 135))
- self.explosionSfx.play()
- if self.yieldsStar and self.disabled and self.coinVisible:
- surface.blit(self.starImage, (self.coinPos[0] + 20, self.coinPos[1] + 30))
-
- # -----------------------------------------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/character.py b/character.py
deleted file mode 100644
index 4528263..0000000
--- a/character.py
+++ /dev/null
@@ -1,276 +0,0 @@
-# coding=utf-8
-import pygame
-from game import *
-import aicharacter
-
-class Character(object):
-
- def __init__(self, x, y, Vx=0, Vy=0, whichChar=1):
- # Initialize motion variables
- self.x = x
- self.y = y
- self.Vx = Vx
- self.Vy = Vy
-
- # Hard-code the gravity acceleration, jumping speed, and run speed
- self.gravity = 1.5
- self.jumpSpeed = 22
- self.runSpeed = 4
-
- # Initialize variables related to drawing and motion to zero/false
- self.walkFrame = 0
- self.mobJumping = False
- self.underwater = False
- self.movingLaterally = False
- self.jumping = False
- self.canJump = False
- self.onGround = False
- self.hasKey = False
- self.direction = 0
- self.currentPlatform = 0
- self.lowestPlatform = 0
-
- # Score and coins
- if whichChar == 1:
- self.health = 4
- elif whichChar == 2:
- self.health = 6
- else:
- self.health = 10
- self.recoveryHealth = self.health
- self.flashing = True
- self.flashTimer = 0
- self.coins = 0
-
- # Load images and save the height and width of the character
- self.standingImage = pygame.image.load('character\main\p' + str(whichChar) + '_front.png').convert_alpha()
- self.jumpingImageL = pygame.image.load('character\main\p' + str(whichChar) + '_jump_l.png').convert_alpha()
- self.jumpingImageR = pygame.image.load('character\main\p' + str(whichChar) + '_jump.png').convert_alpha()
- self.width = pygame.Surface.get_width(self.standingImage)
- self.height = pygame.Surface.get_height(self.standingImage)
- self.walkImagesR = [] * 11
- self.walkImagesL = [] * 11
- for i in range(1, 11):
- walkImage = pygame.image.load('character\main\p' + str(whichChar) + '_walk\PNG\p' + str(whichChar) +
- '_walk' + str(i) + ".png").convert_alpha()
- self.walkImagesR.append(walkImage)
- walkImageL = pygame.transform.flip(walkImage, True, False)
- self.walkImagesL.append(walkImageL)
-
- # Use 2D kinematics to determine maximum jump height and length
- jumpTime = self.jumpSpeed / self.gravity
- self.maxJumpHeight = math.floor(0.5 * self.jumpSpeed * jumpTime)
- self.maxJumpLength = math.floor(abs(self.runSpeed * jumpTime))
-
- # Save the character ID
- self.whichChar = whichChar
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool, surface, FPS):
- # Perform all player updates
- self.updateMotion(ev, platforms, movableObjects, aiCharacters)
- self.collide(platforms, blocks, aiCharacters, pool)
- self.determineLowestPlatform(platforms)
- self.draw(surface, FPS)
- return True
-
- # -----------------------------------------------------------------------------------------------------------------
- def determineLowestPlatform(self, platforms):
- for platform in range(0, len(platforms)):
- if platforms[platform].y > platforms[self.lowestPlatform].y:
- self.lowestPlatform = platform
-
- # -----------------------------------------------------------------------------------------------------------------
- def jump(self, intensity=1.0):
- # Generic jump method that does not check if jumping is feasible
- self.Vy = math.floor(-intensity * self.jumpSpeed)
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, ev, platforms, movableObjects, aiCharacters):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0][3] - platforms[0][1] - 5
-
- # Apply gravity if necessary
- if self.onGround:
- self.Vy = 0
- self.mobJumping = False
- else:
- self.Vy += self.gravity
-
- # -----------------------------------------------------------------------------------------------------------------
- def blockCollision(self, blocks):
- # Local variables for player position
- left = self.x + 10
- right = self.x + self.width - 10
- top = self.y
- bottom = self.y + self.height
-
- for block in blocks:
- # Local variables for block position
- blockLeft = block.x
- blockRight = block.x + block.width
- blockTop = block.y
- blockBottom = block.y + block.height
- blockMiddleX = int(0.5 * blockLeft + 0.5 * blockRight)
- blockMiddleY = int(0.5 * blockBottom + 0.5 * blockTop)
-
- # Booleans for player position relative to block
- belowBlock = right >= blockLeft and left <= blockRight and blockMiddleY <= top <= blockBottom
- leftOfBlock = blockLeft <= right < blockMiddleX and bottom > blockTop and top < blockBottom
- rightOfBlock = blockRight >= left > blockMiddleX and bottom > blockTop and top < blockBottom
- aboveBlock = right >= blockLeft + 10 and left <= blockRight - 10 and blockBottom > bottom >= blockTop
-
- hitBlock = False
- if belowBlock and self.jumping:
- self.y = block.y + block.height + 1
- self.Vy = 0
- hitBlock = True
- elif leftOfBlock:
- self.x = blockLeft - self.width
- self.Vx *= -1
- return True
- elif rightOfBlock:
- self.x = blockRight
- self.Vx *= -1
- return True
- elif aboveBlock and self.Vy >= 0:
- self.y = blockTop - self.height
- self.onGround = True
- if not block.disabled and hitBlock:
- block.disable()
- if block.willExplode and not self.flashing:
- self.health -= 1
- self.flashing = True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
- def coinCollision(self, blocks):
- selfRect = pygame.Rect(self.x, self.y, self.width, self.height)
- for block in blocks:
- coin = block.coinPos
- coinRect = pygame.Rect(coin[0], coin[1], block.coinWidth, block.coinHeight)
- starRect = pygame.Rect(coin[0], coin[1], block.starWidth, block.starHeight)
- if block.coinVisible and selfRect.colliderect(coinRect) and not block.yieldsStar:
- self.coins += 1
- block.killcoin()
- elif block.coinVisible and selfRect.colliderect(starRect):
- self.coins += 10
- self.health += 2
- block.killcoin()
-
- # -----------------------------------------------------------------------------------------------------------------
- def platformCollision(self, platforms):
- platformTolerance = 15
- PlayerLeftX = self.x
- PlayerTopY = self.y
- PlayerRightX = self.x + self.width
- PlayerBottomY = self.y + self.height
- for i in range(0, len(platforms)):
- PlatformLeftX = platforms[i][0]
- PlatformTopY = platforms[i][1]
- PlatformRightX = platforms[i][2]
- PlatformBottomY = platforms[i][3]
- if PlayerRightX >= PlatformLeftX + platformTolerance and PlayerLeftX <= PlatformRightX - \
- platformTolerance and PlatformTopY <= PlayerBottomY <= PlatformBottomY + 15 and self.Vy >= 0:
- self.y = PlatformTopY - self.height
- self.onGround = True
- self.currentPlatform = i
- if PlayerRightX >= PlatformLeftX + platformTolerance and PlayerLeftX <= PlatformRightX - platformTolerance \
- and PlatformBottomY >= PlayerTopY >= PlatformTopY and self.Vy < 0:
- if PlayerRightX >= PlatformLeftX + platforms[i].tileWidth and \
- PlayerLeftX <= PlatformRightX - platforms[i].tileWidth:
- self.y = PlatformBottomY
- self.Vy = 0
- elif PlayerTopY <= PlatformTopY + platformTolerance + 10:
- self.y = PlatformBottomY
- self.Vy = 0
-
- # -----------------------------------------------------------------------------------------------------------------
- def collide(self, platforms, blocks, aiCharacters, pool):
- # Initially assume the player is not on the ground and not underwater
- self.onGround = False
- self.underwater = False
-
- # Detect block collisions
- self.blockCollision(blocks)
- self.coinCollision(blocks)
-
- # Detect platform collision and adjust player motion accordingly
- self.platformCollision(platforms)
-
- # Detect collision with (other) AI characters
- if not isinstance(self, aicharacter.AICharacter):
- for aiCharacter in aiCharacters:
- aiCharacterRect = pygame.Rect(aiCharacter.x, aiCharacter.y, aiCharacter.width, aiCharacter.height)
- selfRect = pygame.Rect(self.x, self.y, self.width, self.height)
- if selfRect.colliderect(aiCharacterRect) and aiCharacter.alive:
- if self.Vy > 0 and aiCharacter.mobType != 'fly':
- aiCharacter.health -= 7 - self.whichChar
- self.jump(0.6)
- self.mobJumping = True
- elif self.Vy > 0:
- aiCharacter.alive = False
- elif not self.flashing and not self.mobJumping:
- self.health -= 1
- self.flashing = True
-
- # Detect collision with pool platform
- if pool:
- PlayerLeftX = self.x
- PlayerRightX = self.x + self.width
- PlayerBottomY = self.y + self.height
- if pool.y <= PlayerBottomY <= pool.y + pool.tileWidth and ((PlayerRightX - 10 >= pool.x and PlayerLeftX + 10
- <= pool.poolStartX + pool.tileWidth) or (PlayerRightX - 10 >= pool.poolEndX and PlayerLeftX + 10
- <= pool.x + pool.width)) and self.Vy >= 0:
- self.onGround = True
- self.y = pool.y - self.height
- if PlayerLeftX + 10 >= pool.poolStartX and PlayerRightX - 10 <= pool.poolEndX + pool.tileWidth and \
- pool.y + pool.height <= PlayerBottomY <= pool.y + pool.height + pool.tileWidth and self.Vy >= 0:
- self.onGround = True
- self.y = pool.y + pool.height - self.height
- if pool.poolStartX + pool.tileWidth >= PlayerLeftX >= pool.poolStartX and \
- pool.y < PlayerBottomY <= pool.y + pool.height:
- self.x = pool.poolStartX + pool.tileWidth + 1
- self.Vx *= -1
- if pool.poolEndX <= PlayerRightX <= pool.poolEndX + pool.tileWidth and \
- pool.y < PlayerBottomY <= pool.y + pool.height:
- self.x = pool.poolEndX - self.width - 1
- self.Vx *= -1
- if PlayerRightX >= pool.poolStartX and PlayerLeftX <= pool.poolEndX and \
- pool.y + pool.height >= PlayerBottomY > pool.y:
- self.underwater = True
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, surface, FPS=60):
-
- # Increment the current frame of the player walking animation
- footstepRarity = 1
- if pygame.time.get_ticks() % footstepRarity == 0:
- self.walkFrame += 1
- if self.walkFrame >= 10:
- self.walkFrame = 0
-
- # Correctly display the current action of the player
- totalFlashTime = 4
- if self.flashing:
- self.flashTimer += 1
- else:
- self.flashTimer = 0
- if self.flashTimer >= (FPS * totalFlashTime):
- self.flashing = False
- if self.flashTimer == 0 or self.flashTimer % FPS < (FPS * 0.75):
- if self.jumping and self.direction == 1:
- surface.blit(self.jumpingImageR, (self.x, self.y))
- elif self.jumping and self.direction == 0:
- surface.blit(self.jumpingImageL, (self.x, self.y))
- elif self.onGround and self.movingLaterally and self.direction == 1:
- surface.blit(self.walkImagesR[self.walkFrame], (self.x, self.y))
- elif self.onGround and self.movingLaterally and self.direction == 0:
- surface.blit(self.walkImagesL[self.walkFrame], (self.x, self.y))
- else:
- surface.blit(self.standingImage, (self.x, self.y))
diff --git a/character/crossover/front.bmp b/character/crossover/front.bmp
deleted file mode 100644
index c26e184..0000000
Binary files a/character/crossover/front.bmp and /dev/null differ
diff --git a/character/crossover/jump_left.bmp b/character/crossover/jump_left.bmp
deleted file mode 100644
index 20a0366..0000000
Binary files a/character/crossover/jump_left.bmp and /dev/null differ
diff --git a/character/crossover/jump_right.bmp b/character/crossover/jump_right.bmp
deleted file mode 100644
index 59c4378..0000000
Binary files a/character/crossover/jump_right.bmp and /dev/null differ
diff --git a/character/crossover/walk0001.bmp b/character/crossover/walk0001.bmp
deleted file mode 100644
index b447f77..0000000
Binary files a/character/crossover/walk0001.bmp and /dev/null differ
diff --git a/character/crossover/walk0002.bmp b/character/crossover/walk0002.bmp
deleted file mode 100644
index b5570a5..0000000
Binary files a/character/crossover/walk0002.bmp and /dev/null differ
diff --git a/character/crossover/walk0003.bmp b/character/crossover/walk0003.bmp
deleted file mode 100644
index cf490dc..0000000
Binary files a/character/crossover/walk0003.bmp and /dev/null differ
diff --git a/character/crossover/walk0004.bmp b/character/crossover/walk0004.bmp
deleted file mode 100644
index e5b1f92..0000000
Binary files a/character/crossover/walk0004.bmp and /dev/null differ
diff --git a/character/crossover/walk0005.bmp b/character/crossover/walk0005.bmp
deleted file mode 100644
index 2db12f1..0000000
Binary files a/character/crossover/walk0005.bmp and /dev/null differ
diff --git a/character/crossover/walk0006.bmp b/character/crossover/walk0006.bmp
deleted file mode 100644
index 6dc49b4..0000000
Binary files a/character/crossover/walk0006.bmp and /dev/null differ
diff --git a/character/crossover/walk0007.bmp b/character/crossover/walk0007.bmp
deleted file mode 100644
index e45fa57..0000000
Binary files a/character/crossover/walk0007.bmp and /dev/null differ
diff --git a/character/crossover/walk0008.bmp b/character/crossover/walk0008.bmp
deleted file mode 100644
index 041f7e1..0000000
Binary files a/character/crossover/walk0008.bmp and /dev/null differ
diff --git a/character/crossover/walk0009.bmp b/character/crossover/walk0009.bmp
deleted file mode 100644
index 759744c..0000000
Binary files a/character/crossover/walk0009.bmp and /dev/null differ
diff --git a/character/crossover/walk0010.bmp b/character/crossover/walk0010.bmp
deleted file mode 100644
index bc25026..0000000
Binary files a/character/crossover/walk0010.bmp and /dev/null differ
diff --git a/character/crossover/walk0011.bmp b/character/crossover/walk0011.bmp
deleted file mode 100644
index b447f77..0000000
Binary files a/character/crossover/walk0011.bmp and /dev/null differ
diff --git a/character/main/Beige/Alpha/badge_1.png b/character/main/Beige/Alpha/badge_1.png
deleted file mode 100644
index 6030dd7..0000000
Binary files a/character/main/Beige/Alpha/badge_1.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/badge_2.png b/character/main/Beige/Alpha/badge_2.png
deleted file mode 100644
index de12fa8..0000000
Binary files a/character/main/Beige/Alpha/badge_2.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/climb_1.png b/character/main/Beige/Alpha/climb_1.png
deleted file mode 100644
index 42e78a1..0000000
Binary files a/character/main/Beige/Alpha/climb_1.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/climb_2.png b/character/main/Beige/Alpha/climb_2.png
deleted file mode 100644
index e7b42da..0000000
Binary files a/character/main/Beige/Alpha/climb_2.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/duck.png b/character/main/Beige/Alpha/duck.png
deleted file mode 100644
index 0e591e2..0000000
Binary files a/character/main/Beige/Alpha/duck.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/hurt.png b/character/main/Beige/Alpha/hurt.png
deleted file mode 100644
index fbd79d3..0000000
Binary files a/character/main/Beige/Alpha/hurt.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/idle.png b/character/main/Beige/Alpha/idle.png
deleted file mode 100644
index 06912f3..0000000
Binary files a/character/main/Beige/Alpha/idle.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/jump.png b/character/main/Beige/Alpha/jump.png
deleted file mode 100644
index 7b83397..0000000
Binary files a/character/main/Beige/Alpha/jump.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/stand.png b/character/main/Beige/Alpha/stand.png
deleted file mode 100644
index 5d49b74..0000000
Binary files a/character/main/Beige/Alpha/stand.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/swim_1.png b/character/main/Beige/Alpha/swim_1.png
deleted file mode 100644
index 731fb68..0000000
Binary files a/character/main/Beige/Alpha/swim_1.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/swim_2.png b/character/main/Beige/Alpha/swim_2.png
deleted file mode 100644
index 175aa95..0000000
Binary files a/character/main/Beige/Alpha/swim_2.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/walk_1.png b/character/main/Beige/Alpha/walk_1.png
deleted file mode 100644
index 9a7e402..0000000
Binary files a/character/main/Beige/Alpha/walk_1.png and /dev/null differ
diff --git a/character/main/Beige/Alpha/walk_2.png b/character/main/Beige/Alpha/walk_2.png
deleted file mode 100644
index 08fa18c..0000000
Binary files a/character/main/Beige/Alpha/walk_2.png and /dev/null differ
diff --git a/character/main/Beige/Beta/badge_1.png b/character/main/Beige/Beta/badge_1.png
deleted file mode 100644
index 1538364..0000000
Binary files a/character/main/Beige/Beta/badge_1.png and /dev/null differ
diff --git a/character/main/Beige/Beta/badge_2.png b/character/main/Beige/Beta/badge_2.png
deleted file mode 100644
index 0b19aad..0000000
Binary files a/character/main/Beige/Beta/badge_2.png and /dev/null differ
diff --git a/character/main/Beige/Beta/climb_1.png b/character/main/Beige/Beta/climb_1.png
deleted file mode 100644
index 278c542..0000000
Binary files a/character/main/Beige/Beta/climb_1.png and /dev/null differ
diff --git a/character/main/Beige/Beta/climb_2.png b/character/main/Beige/Beta/climb_2.png
deleted file mode 100644
index f9b4212..0000000
Binary files a/character/main/Beige/Beta/climb_2.png and /dev/null differ
diff --git a/character/main/Beige/Beta/duck.png b/character/main/Beige/Beta/duck.png
deleted file mode 100644
index 6105120..0000000
Binary files a/character/main/Beige/Beta/duck.png and /dev/null differ
diff --git a/character/main/Beige/Beta/hurt.png b/character/main/Beige/Beta/hurt.png
deleted file mode 100644
index 3c6376d..0000000
Binary files a/character/main/Beige/Beta/hurt.png and /dev/null differ
diff --git a/character/main/Beige/Beta/idle.png b/character/main/Beige/Beta/idle.png
deleted file mode 100644
index 3bb4929..0000000
Binary files a/character/main/Beige/Beta/idle.png and /dev/null differ
diff --git a/character/main/Beige/Beta/jump.png b/character/main/Beige/Beta/jump.png
deleted file mode 100644
index 4693ea7..0000000
Binary files a/character/main/Beige/Beta/jump.png and /dev/null differ
diff --git a/character/main/Beige/Beta/stand.png b/character/main/Beige/Beta/stand.png
deleted file mode 100644
index 8e82de5..0000000
Binary files a/character/main/Beige/Beta/stand.png and /dev/null differ
diff --git a/character/main/Beige/Beta/swim_1.png b/character/main/Beige/Beta/swim_1.png
deleted file mode 100644
index c9e40e8..0000000
Binary files a/character/main/Beige/Beta/swim_1.png and /dev/null differ
diff --git a/character/main/Beige/Beta/swim_2.png b/character/main/Beige/Beta/swim_2.png
deleted file mode 100644
index df16e53..0000000
Binary files a/character/main/Beige/Beta/swim_2.png and /dev/null differ
diff --git a/character/main/Beige/Beta/walk_1.png b/character/main/Beige/Beta/walk_1.png
deleted file mode 100644
index 7d9a78b..0000000
Binary files a/character/main/Beige/Beta/walk_1.png and /dev/null differ
diff --git a/character/main/Beige/Beta/walk_2.png b/character/main/Beige/Beta/walk_2.png
deleted file mode 100644
index 18761e6..0000000
Binary files a/character/main/Beige/Beta/walk_2.png and /dev/null differ
diff --git a/character/main/Beige/Delta/badge_1.png b/character/main/Beige/Delta/badge_1.png
deleted file mode 100644
index 0b64013..0000000
Binary files a/character/main/Beige/Delta/badge_1.png and /dev/null differ
diff --git a/character/main/Beige/Delta/badge_2.png b/character/main/Beige/Delta/badge_2.png
deleted file mode 100644
index 9086523..0000000
Binary files a/character/main/Beige/Delta/badge_2.png and /dev/null differ
diff --git a/character/main/Beige/Delta/climb_1.png b/character/main/Beige/Delta/climb_1.png
deleted file mode 100644
index d185222..0000000
Binary files a/character/main/Beige/Delta/climb_1.png and /dev/null differ
diff --git a/character/main/Beige/Delta/climb_2.png b/character/main/Beige/Delta/climb_2.png
deleted file mode 100644
index 957459d..0000000
Binary files a/character/main/Beige/Delta/climb_2.png and /dev/null differ
diff --git a/character/main/Beige/Delta/duck.png b/character/main/Beige/Delta/duck.png
deleted file mode 100644
index eeeb56b..0000000
Binary files a/character/main/Beige/Delta/duck.png and /dev/null differ
diff --git a/character/main/Beige/Delta/hurt.png b/character/main/Beige/Delta/hurt.png
deleted file mode 100644
index 1e140bb..0000000
Binary files a/character/main/Beige/Delta/hurt.png and /dev/null differ
diff --git a/character/main/Beige/Delta/idle.png b/character/main/Beige/Delta/idle.png
deleted file mode 100644
index b624962..0000000
Binary files a/character/main/Beige/Delta/idle.png and /dev/null differ
diff --git a/character/main/Beige/Delta/jump.png b/character/main/Beige/Delta/jump.png
deleted file mode 100644
index 917e6e3..0000000
Binary files a/character/main/Beige/Delta/jump.png and /dev/null differ
diff --git a/character/main/Beige/Delta/stand.png b/character/main/Beige/Delta/stand.png
deleted file mode 100644
index 66c975b..0000000
Binary files a/character/main/Beige/Delta/stand.png and /dev/null differ
diff --git a/character/main/Beige/Delta/swim_1.png b/character/main/Beige/Delta/swim_1.png
deleted file mode 100644
index 181befc..0000000
Binary files a/character/main/Beige/Delta/swim_1.png and /dev/null differ
diff --git a/character/main/Beige/Delta/swim_2.png b/character/main/Beige/Delta/swim_2.png
deleted file mode 100644
index 35535dc..0000000
Binary files a/character/main/Beige/Delta/swim_2.png and /dev/null differ
diff --git a/character/main/Beige/Delta/walk_1.png b/character/main/Beige/Delta/walk_1.png
deleted file mode 100644
index b01ca0f..0000000
Binary files a/character/main/Beige/Delta/walk_1.png and /dev/null differ
diff --git a/character/main/Beige/Delta/walk_2.png b/character/main/Beige/Delta/walk_2.png
deleted file mode 100644
index 918b3f5..0000000
Binary files a/character/main/Beige/Delta/walk_2.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/badge_1.png b/character/main/Beige/Gamma/badge_1.png
deleted file mode 100644
index 74be8e9..0000000
Binary files a/character/main/Beige/Gamma/badge_1.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/badge_2.png b/character/main/Beige/Gamma/badge_2.png
deleted file mode 100644
index 4ec4a93..0000000
Binary files a/character/main/Beige/Gamma/badge_2.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/climb_1.png b/character/main/Beige/Gamma/climb_1.png
deleted file mode 100644
index ec650fd..0000000
Binary files a/character/main/Beige/Gamma/climb_1.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/climb_2.png b/character/main/Beige/Gamma/climb_2.png
deleted file mode 100644
index feba8bc..0000000
Binary files a/character/main/Beige/Gamma/climb_2.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/duck.png b/character/main/Beige/Gamma/duck.png
deleted file mode 100644
index 92ef438..0000000
Binary files a/character/main/Beige/Gamma/duck.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/hurt.png b/character/main/Beige/Gamma/hurt.png
deleted file mode 100644
index 236dac3..0000000
Binary files a/character/main/Beige/Gamma/hurt.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/idle.png b/character/main/Beige/Gamma/idle.png
deleted file mode 100644
index 42b9a74..0000000
Binary files a/character/main/Beige/Gamma/idle.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/jump.png b/character/main/Beige/Gamma/jump.png
deleted file mode 100644
index 0a332b6..0000000
Binary files a/character/main/Beige/Gamma/jump.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/stand.png b/character/main/Beige/Gamma/stand.png
deleted file mode 100644
index 4d41793..0000000
Binary files a/character/main/Beige/Gamma/stand.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/swim_1.png b/character/main/Beige/Gamma/swim_1.png
deleted file mode 100644
index 98f8035..0000000
Binary files a/character/main/Beige/Gamma/swim_1.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/swim_2.png b/character/main/Beige/Gamma/swim_2.png
deleted file mode 100644
index c2c5eb8..0000000
Binary files a/character/main/Beige/Gamma/swim_2.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/walk_1.png b/character/main/Beige/Gamma/walk_1.png
deleted file mode 100644
index 8283b88..0000000
Binary files a/character/main/Beige/Gamma/walk_1.png and /dev/null differ
diff --git a/character/main/Beige/Gamma/walk_2.png b/character/main/Beige/Gamma/walk_2.png
deleted file mode 100644
index 5eefdf4..0000000
Binary files a/character/main/Beige/Gamma/walk_2.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/badge_1.png b/character/main/Beige/Zeta/badge_1.png
deleted file mode 100644
index 4b9aaab..0000000
Binary files a/character/main/Beige/Zeta/badge_1.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/badge_2.png b/character/main/Beige/Zeta/badge_2.png
deleted file mode 100644
index 888b254..0000000
Binary files a/character/main/Beige/Zeta/badge_2.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/climb_1.png b/character/main/Beige/Zeta/climb_1.png
deleted file mode 100644
index 2ae4453..0000000
Binary files a/character/main/Beige/Zeta/climb_1.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/climb_2.png b/character/main/Beige/Zeta/climb_2.png
deleted file mode 100644
index 4482768..0000000
Binary files a/character/main/Beige/Zeta/climb_2.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/duck.png b/character/main/Beige/Zeta/duck.png
deleted file mode 100644
index ff06b82..0000000
Binary files a/character/main/Beige/Zeta/duck.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/hurt.png b/character/main/Beige/Zeta/hurt.png
deleted file mode 100644
index 23db54a..0000000
Binary files a/character/main/Beige/Zeta/hurt.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/idle.png b/character/main/Beige/Zeta/idle.png
deleted file mode 100644
index 9b6f02b..0000000
Binary files a/character/main/Beige/Zeta/idle.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/jump.png b/character/main/Beige/Zeta/jump.png
deleted file mode 100644
index afd2b21..0000000
Binary files a/character/main/Beige/Zeta/jump.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/stand.png b/character/main/Beige/Zeta/stand.png
deleted file mode 100644
index b19397f..0000000
Binary files a/character/main/Beige/Zeta/stand.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/swim_1.png b/character/main/Beige/Zeta/swim_1.png
deleted file mode 100644
index 53ddd62..0000000
Binary files a/character/main/Beige/Zeta/swim_1.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/swim_2.png b/character/main/Beige/Zeta/swim_2.png
deleted file mode 100644
index 9a22094..0000000
Binary files a/character/main/Beige/Zeta/swim_2.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/walk_1.png b/character/main/Beige/Zeta/walk_1.png
deleted file mode 100644
index 583c589..0000000
Binary files a/character/main/Beige/Zeta/walk_1.png and /dev/null differ
diff --git a/character/main/Beige/Zeta/walk_2.png b/character/main/Beige/Zeta/walk_2.png
deleted file mode 100644
index 4835dad..0000000
Binary files a/character/main/Beige/Zeta/walk_2.png and /dev/null differ
diff --git a/character/main/Beige/beige_sheet.png b/character/main/Beige/beige_sheet.png
deleted file mode 100644
index 1b55867..0000000
Binary files a/character/main/Beige/beige_sheet.png and /dev/null differ
diff --git a/character/main/Beige/beige_vector.svg b/character/main/Beige/beige_vector.svg
deleted file mode 100644
index a82dbb1..0000000
--- a/character/main/Beige/beige_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/main/Blue/Alpha/badge_1.png b/character/main/Blue/Alpha/badge_1.png
deleted file mode 100644
index 2dc0618..0000000
Binary files a/character/main/Blue/Alpha/badge_1.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/badge_2.png b/character/main/Blue/Alpha/badge_2.png
deleted file mode 100644
index 901d805..0000000
Binary files a/character/main/Blue/Alpha/badge_2.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/climb_1.png b/character/main/Blue/Alpha/climb_1.png
deleted file mode 100644
index 1696c3b..0000000
Binary files a/character/main/Blue/Alpha/climb_1.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/climb_2.png b/character/main/Blue/Alpha/climb_2.png
deleted file mode 100644
index 04233f1..0000000
Binary files a/character/main/Blue/Alpha/climb_2.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/duck.png b/character/main/Blue/Alpha/duck.png
deleted file mode 100644
index 51c77dd..0000000
Binary files a/character/main/Blue/Alpha/duck.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/hurt.png b/character/main/Blue/Alpha/hurt.png
deleted file mode 100644
index 07dd5c0..0000000
Binary files a/character/main/Blue/Alpha/hurt.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/idle.png b/character/main/Blue/Alpha/idle.png
deleted file mode 100644
index b41e54a..0000000
Binary files a/character/main/Blue/Alpha/idle.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/jump.png b/character/main/Blue/Alpha/jump.png
deleted file mode 100644
index 7f27b43..0000000
Binary files a/character/main/Blue/Alpha/jump.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/stand.png b/character/main/Blue/Alpha/stand.png
deleted file mode 100644
index 959a9d1..0000000
Binary files a/character/main/Blue/Alpha/stand.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/swim_1.png b/character/main/Blue/Alpha/swim_1.png
deleted file mode 100644
index 99e9d43..0000000
Binary files a/character/main/Blue/Alpha/swim_1.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/swim_2.png b/character/main/Blue/Alpha/swim_2.png
deleted file mode 100644
index e80301a..0000000
Binary files a/character/main/Blue/Alpha/swim_2.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/walk_1.png b/character/main/Blue/Alpha/walk_1.png
deleted file mode 100644
index 36dffe9..0000000
Binary files a/character/main/Blue/Alpha/walk_1.png and /dev/null differ
diff --git a/character/main/Blue/Alpha/walk_2.png b/character/main/Blue/Alpha/walk_2.png
deleted file mode 100644
index 80c081b..0000000
Binary files a/character/main/Blue/Alpha/walk_2.png and /dev/null differ
diff --git a/character/main/Blue/Beta/badge_1.png b/character/main/Blue/Beta/badge_1.png
deleted file mode 100644
index b21933c..0000000
Binary files a/character/main/Blue/Beta/badge_1.png and /dev/null differ
diff --git a/character/main/Blue/Beta/badge_2.png b/character/main/Blue/Beta/badge_2.png
deleted file mode 100644
index 2616265..0000000
Binary files a/character/main/Blue/Beta/badge_2.png and /dev/null differ
diff --git a/character/main/Blue/Beta/climb_1.png b/character/main/Blue/Beta/climb_1.png
deleted file mode 100644
index adf98a5..0000000
Binary files a/character/main/Blue/Beta/climb_1.png and /dev/null differ
diff --git a/character/main/Blue/Beta/climb_2.png b/character/main/Blue/Beta/climb_2.png
deleted file mode 100644
index 9bd4d6a..0000000
Binary files a/character/main/Blue/Beta/climb_2.png and /dev/null differ
diff --git a/character/main/Blue/Beta/duck.png b/character/main/Blue/Beta/duck.png
deleted file mode 100644
index 65fd320..0000000
Binary files a/character/main/Blue/Beta/duck.png and /dev/null differ
diff --git a/character/main/Blue/Beta/hurt.png b/character/main/Blue/Beta/hurt.png
deleted file mode 100644
index 7e20c36..0000000
Binary files a/character/main/Blue/Beta/hurt.png and /dev/null differ
diff --git a/character/main/Blue/Beta/idle.png b/character/main/Blue/Beta/idle.png
deleted file mode 100644
index 3f35c70..0000000
Binary files a/character/main/Blue/Beta/idle.png and /dev/null differ
diff --git a/character/main/Blue/Beta/jump.png b/character/main/Blue/Beta/jump.png
deleted file mode 100644
index 2337537..0000000
Binary files a/character/main/Blue/Beta/jump.png and /dev/null differ
diff --git a/character/main/Blue/Beta/stand.png b/character/main/Blue/Beta/stand.png
deleted file mode 100644
index da059ce..0000000
Binary files a/character/main/Blue/Beta/stand.png and /dev/null differ
diff --git a/character/main/Blue/Beta/swim_1.png b/character/main/Blue/Beta/swim_1.png
deleted file mode 100644
index b4720a3..0000000
Binary files a/character/main/Blue/Beta/swim_1.png and /dev/null differ
diff --git a/character/main/Blue/Beta/swim_2.png b/character/main/Blue/Beta/swim_2.png
deleted file mode 100644
index 3e1cee5..0000000
Binary files a/character/main/Blue/Beta/swim_2.png and /dev/null differ
diff --git a/character/main/Blue/Beta/walk_1.png b/character/main/Blue/Beta/walk_1.png
deleted file mode 100644
index bbef849..0000000
Binary files a/character/main/Blue/Beta/walk_1.png and /dev/null differ
diff --git a/character/main/Blue/Beta/walk_2.png b/character/main/Blue/Beta/walk_2.png
deleted file mode 100644
index 505066c..0000000
Binary files a/character/main/Blue/Beta/walk_2.png and /dev/null differ
diff --git a/character/main/Blue/Delta/badge_1.png b/character/main/Blue/Delta/badge_1.png
deleted file mode 100644
index f895eb8..0000000
Binary files a/character/main/Blue/Delta/badge_1.png and /dev/null differ
diff --git a/character/main/Blue/Delta/badge_2.png b/character/main/Blue/Delta/badge_2.png
deleted file mode 100644
index 13eb277..0000000
Binary files a/character/main/Blue/Delta/badge_2.png and /dev/null differ
diff --git a/character/main/Blue/Delta/climb_1.png b/character/main/Blue/Delta/climb_1.png
deleted file mode 100644
index 697b6c4..0000000
Binary files a/character/main/Blue/Delta/climb_1.png and /dev/null differ
diff --git a/character/main/Blue/Delta/climb_2.png b/character/main/Blue/Delta/climb_2.png
deleted file mode 100644
index a5dcb2f..0000000
Binary files a/character/main/Blue/Delta/climb_2.png and /dev/null differ
diff --git a/character/main/Blue/Delta/duck.png b/character/main/Blue/Delta/duck.png
deleted file mode 100644
index a34d271..0000000
Binary files a/character/main/Blue/Delta/duck.png and /dev/null differ
diff --git a/character/main/Blue/Delta/hurt.png b/character/main/Blue/Delta/hurt.png
deleted file mode 100644
index 632f29e..0000000
Binary files a/character/main/Blue/Delta/hurt.png and /dev/null differ
diff --git a/character/main/Blue/Delta/idle.png b/character/main/Blue/Delta/idle.png
deleted file mode 100644
index ea19992..0000000
Binary files a/character/main/Blue/Delta/idle.png and /dev/null differ
diff --git a/character/main/Blue/Delta/jump.png b/character/main/Blue/Delta/jump.png
deleted file mode 100644
index e533edf..0000000
Binary files a/character/main/Blue/Delta/jump.png and /dev/null differ
diff --git a/character/main/Blue/Delta/stand.png b/character/main/Blue/Delta/stand.png
deleted file mode 100644
index 3ccdfbc..0000000
Binary files a/character/main/Blue/Delta/stand.png and /dev/null differ
diff --git a/character/main/Blue/Delta/swim_1.png b/character/main/Blue/Delta/swim_1.png
deleted file mode 100644
index 32fa555..0000000
Binary files a/character/main/Blue/Delta/swim_1.png and /dev/null differ
diff --git a/character/main/Blue/Delta/swim_2.png b/character/main/Blue/Delta/swim_2.png
deleted file mode 100644
index c55632b..0000000
Binary files a/character/main/Blue/Delta/swim_2.png and /dev/null differ
diff --git a/character/main/Blue/Delta/walk_1.png b/character/main/Blue/Delta/walk_1.png
deleted file mode 100644
index 8d0c3f8..0000000
Binary files a/character/main/Blue/Delta/walk_1.png and /dev/null differ
diff --git a/character/main/Blue/Delta/walk_2.png b/character/main/Blue/Delta/walk_2.png
deleted file mode 100644
index be2ae9b..0000000
Binary files a/character/main/Blue/Delta/walk_2.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/badge_1.png b/character/main/Blue/Gamma/badge_1.png
deleted file mode 100644
index b77acc1..0000000
Binary files a/character/main/Blue/Gamma/badge_1.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/badge_2.png b/character/main/Blue/Gamma/badge_2.png
deleted file mode 100644
index 53ab45f..0000000
Binary files a/character/main/Blue/Gamma/badge_2.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/climb_1.png b/character/main/Blue/Gamma/climb_1.png
deleted file mode 100644
index 4badfae..0000000
Binary files a/character/main/Blue/Gamma/climb_1.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/climb_2.png b/character/main/Blue/Gamma/climb_2.png
deleted file mode 100644
index 8ddcee0..0000000
Binary files a/character/main/Blue/Gamma/climb_2.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/duck.png b/character/main/Blue/Gamma/duck.png
deleted file mode 100644
index 774fb8c..0000000
Binary files a/character/main/Blue/Gamma/duck.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/hurt.png b/character/main/Blue/Gamma/hurt.png
deleted file mode 100644
index 38266d9..0000000
Binary files a/character/main/Blue/Gamma/hurt.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/idle.png b/character/main/Blue/Gamma/idle.png
deleted file mode 100644
index 0049bc6..0000000
Binary files a/character/main/Blue/Gamma/idle.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/jump.png b/character/main/Blue/Gamma/jump.png
deleted file mode 100644
index 91af75d..0000000
Binary files a/character/main/Blue/Gamma/jump.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/stand.png b/character/main/Blue/Gamma/stand.png
deleted file mode 100644
index 68299cf..0000000
Binary files a/character/main/Blue/Gamma/stand.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/swim_1.png b/character/main/Blue/Gamma/swim_1.png
deleted file mode 100644
index 99ede6c..0000000
Binary files a/character/main/Blue/Gamma/swim_1.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/swim_2.png b/character/main/Blue/Gamma/swim_2.png
deleted file mode 100644
index aa63a38..0000000
Binary files a/character/main/Blue/Gamma/swim_2.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/walk_1.png b/character/main/Blue/Gamma/walk_1.png
deleted file mode 100644
index 063b89d..0000000
Binary files a/character/main/Blue/Gamma/walk_1.png and /dev/null differ
diff --git a/character/main/Blue/Gamma/walk_2.png b/character/main/Blue/Gamma/walk_2.png
deleted file mode 100644
index 5cc7421..0000000
Binary files a/character/main/Blue/Gamma/walk_2.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/badge_1.png b/character/main/Blue/Zeta/badge_1.png
deleted file mode 100644
index c650326..0000000
Binary files a/character/main/Blue/Zeta/badge_1.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/badge_2.png b/character/main/Blue/Zeta/badge_2.png
deleted file mode 100644
index e388e4e..0000000
Binary files a/character/main/Blue/Zeta/badge_2.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/climb_1.png b/character/main/Blue/Zeta/climb_1.png
deleted file mode 100644
index a722913..0000000
Binary files a/character/main/Blue/Zeta/climb_1.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/climb_2.png b/character/main/Blue/Zeta/climb_2.png
deleted file mode 100644
index 33b76bd..0000000
Binary files a/character/main/Blue/Zeta/climb_2.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/duck.png b/character/main/Blue/Zeta/duck.png
deleted file mode 100644
index 14ead88..0000000
Binary files a/character/main/Blue/Zeta/duck.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/hurt.png b/character/main/Blue/Zeta/hurt.png
deleted file mode 100644
index f26e265..0000000
Binary files a/character/main/Blue/Zeta/hurt.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/idle.png b/character/main/Blue/Zeta/idle.png
deleted file mode 100644
index b29f5cb..0000000
Binary files a/character/main/Blue/Zeta/idle.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/jump.png b/character/main/Blue/Zeta/jump.png
deleted file mode 100644
index 71a302c..0000000
Binary files a/character/main/Blue/Zeta/jump.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/stand.png b/character/main/Blue/Zeta/stand.png
deleted file mode 100644
index 631b79e..0000000
Binary files a/character/main/Blue/Zeta/stand.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/swim_1.png b/character/main/Blue/Zeta/swim_1.png
deleted file mode 100644
index 395d541..0000000
Binary files a/character/main/Blue/Zeta/swim_1.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/swim_2.png b/character/main/Blue/Zeta/swim_2.png
deleted file mode 100644
index d8caa14..0000000
Binary files a/character/main/Blue/Zeta/swim_2.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/walk_1.png b/character/main/Blue/Zeta/walk_1.png
deleted file mode 100644
index e0b5ae2..0000000
Binary files a/character/main/Blue/Zeta/walk_1.png and /dev/null differ
diff --git a/character/main/Blue/Zeta/walk_2.png b/character/main/Blue/Zeta/walk_2.png
deleted file mode 100644
index 1b23a01..0000000
Binary files a/character/main/Blue/Zeta/walk_2.png and /dev/null differ
diff --git a/character/main/Blue/blue_sheet.png b/character/main/Blue/blue_sheet.png
deleted file mode 100644
index 4b2ebaa..0000000
Binary files a/character/main/Blue/blue_sheet.png and /dev/null differ
diff --git a/character/main/Blue/blue_vector.svg b/character/main/Blue/blue_vector.svg
deleted file mode 100644
index bf8dc1b..0000000
--- a/character/main/Blue/blue_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/main/Green/Alpha/badge_1.png b/character/main/Green/Alpha/badge_1.png
deleted file mode 100644
index 1d03d54..0000000
Binary files a/character/main/Green/Alpha/badge_1.png and /dev/null differ
diff --git a/character/main/Green/Alpha/badge_2.png b/character/main/Green/Alpha/badge_2.png
deleted file mode 100644
index 8101242..0000000
Binary files a/character/main/Green/Alpha/badge_2.png and /dev/null differ
diff --git a/character/main/Green/Alpha/climb_1.png b/character/main/Green/Alpha/climb_1.png
deleted file mode 100644
index 7181452..0000000
Binary files a/character/main/Green/Alpha/climb_1.png and /dev/null differ
diff --git a/character/main/Green/Alpha/climb_2.png b/character/main/Green/Alpha/climb_2.png
deleted file mode 100644
index 9b0e571..0000000
Binary files a/character/main/Green/Alpha/climb_2.png and /dev/null differ
diff --git a/character/main/Green/Alpha/duck.png b/character/main/Green/Alpha/duck.png
deleted file mode 100644
index 3684f3c..0000000
Binary files a/character/main/Green/Alpha/duck.png and /dev/null differ
diff --git a/character/main/Green/Alpha/hurt.png b/character/main/Green/Alpha/hurt.png
deleted file mode 100644
index 9c5d0f0..0000000
Binary files a/character/main/Green/Alpha/hurt.png and /dev/null differ
diff --git a/character/main/Green/Alpha/idle.png b/character/main/Green/Alpha/idle.png
deleted file mode 100644
index 5da8db1..0000000
Binary files a/character/main/Green/Alpha/idle.png and /dev/null differ
diff --git a/character/main/Green/Alpha/jump.png b/character/main/Green/Alpha/jump.png
deleted file mode 100644
index 7bf9938..0000000
Binary files a/character/main/Green/Alpha/jump.png and /dev/null differ
diff --git a/character/main/Green/Alpha/stand.png b/character/main/Green/Alpha/stand.png
deleted file mode 100644
index 4c3f0d1..0000000
Binary files a/character/main/Green/Alpha/stand.png and /dev/null differ
diff --git a/character/main/Green/Alpha/swim_1.png b/character/main/Green/Alpha/swim_1.png
deleted file mode 100644
index 2a74554..0000000
Binary files a/character/main/Green/Alpha/swim_1.png and /dev/null differ
diff --git a/character/main/Green/Alpha/swim_2.png b/character/main/Green/Alpha/swim_2.png
deleted file mode 100644
index d80fd30..0000000
Binary files a/character/main/Green/Alpha/swim_2.png and /dev/null differ
diff --git a/character/main/Green/Alpha/walk_1.png b/character/main/Green/Alpha/walk_1.png
deleted file mode 100644
index 5efa479..0000000
Binary files a/character/main/Green/Alpha/walk_1.png and /dev/null differ
diff --git a/character/main/Green/Alpha/walk_2.png b/character/main/Green/Alpha/walk_2.png
deleted file mode 100644
index 916cc63..0000000
Binary files a/character/main/Green/Alpha/walk_2.png and /dev/null differ
diff --git a/character/main/Green/Beta/badge_1.png b/character/main/Green/Beta/badge_1.png
deleted file mode 100644
index 6b2fde3..0000000
Binary files a/character/main/Green/Beta/badge_1.png and /dev/null differ
diff --git a/character/main/Green/Beta/badge_2.png b/character/main/Green/Beta/badge_2.png
deleted file mode 100644
index 5af53bd..0000000
Binary files a/character/main/Green/Beta/badge_2.png and /dev/null differ
diff --git a/character/main/Green/Beta/climb_1.png b/character/main/Green/Beta/climb_1.png
deleted file mode 100644
index adadd32..0000000
Binary files a/character/main/Green/Beta/climb_1.png and /dev/null differ
diff --git a/character/main/Green/Beta/climb_2.png b/character/main/Green/Beta/climb_2.png
deleted file mode 100644
index 888c4ac..0000000
Binary files a/character/main/Green/Beta/climb_2.png and /dev/null differ
diff --git a/character/main/Green/Beta/duck.png b/character/main/Green/Beta/duck.png
deleted file mode 100644
index c51639c..0000000
Binary files a/character/main/Green/Beta/duck.png and /dev/null differ
diff --git a/character/main/Green/Beta/hurt.png b/character/main/Green/Beta/hurt.png
deleted file mode 100644
index edbb230..0000000
Binary files a/character/main/Green/Beta/hurt.png and /dev/null differ
diff --git a/character/main/Green/Beta/idle.png b/character/main/Green/Beta/idle.png
deleted file mode 100644
index 9889622..0000000
Binary files a/character/main/Green/Beta/idle.png and /dev/null differ
diff --git a/character/main/Green/Beta/jump.png b/character/main/Green/Beta/jump.png
deleted file mode 100644
index 0bf7ae4..0000000
Binary files a/character/main/Green/Beta/jump.png and /dev/null differ
diff --git a/character/main/Green/Beta/stand.png b/character/main/Green/Beta/stand.png
deleted file mode 100644
index 7810252..0000000
Binary files a/character/main/Green/Beta/stand.png and /dev/null differ
diff --git a/character/main/Green/Beta/swim_1.png b/character/main/Green/Beta/swim_1.png
deleted file mode 100644
index d816935..0000000
Binary files a/character/main/Green/Beta/swim_1.png and /dev/null differ
diff --git a/character/main/Green/Beta/swim_2.png b/character/main/Green/Beta/swim_2.png
deleted file mode 100644
index 261b61d..0000000
Binary files a/character/main/Green/Beta/swim_2.png and /dev/null differ
diff --git a/character/main/Green/Beta/walk_1.png b/character/main/Green/Beta/walk_1.png
deleted file mode 100644
index 90e45b1..0000000
Binary files a/character/main/Green/Beta/walk_1.png and /dev/null differ
diff --git a/character/main/Green/Beta/walk_2.png b/character/main/Green/Beta/walk_2.png
deleted file mode 100644
index ab3e611..0000000
Binary files a/character/main/Green/Beta/walk_2.png and /dev/null differ
diff --git a/character/main/Green/Delta/badge_1.png b/character/main/Green/Delta/badge_1.png
deleted file mode 100644
index 6137be4..0000000
Binary files a/character/main/Green/Delta/badge_1.png and /dev/null differ
diff --git a/character/main/Green/Delta/badge_2.png b/character/main/Green/Delta/badge_2.png
deleted file mode 100644
index cb56d9c..0000000
Binary files a/character/main/Green/Delta/badge_2.png and /dev/null differ
diff --git a/character/main/Green/Delta/climb_1.png b/character/main/Green/Delta/climb_1.png
deleted file mode 100644
index 344287c..0000000
Binary files a/character/main/Green/Delta/climb_1.png and /dev/null differ
diff --git a/character/main/Green/Delta/climb_2.png b/character/main/Green/Delta/climb_2.png
deleted file mode 100644
index 2a957bd..0000000
Binary files a/character/main/Green/Delta/climb_2.png and /dev/null differ
diff --git a/character/main/Green/Delta/duck.png b/character/main/Green/Delta/duck.png
deleted file mode 100644
index b02991f..0000000
Binary files a/character/main/Green/Delta/duck.png and /dev/null differ
diff --git a/character/main/Green/Delta/hurt.png b/character/main/Green/Delta/hurt.png
deleted file mode 100644
index 63d7a37..0000000
Binary files a/character/main/Green/Delta/hurt.png and /dev/null differ
diff --git a/character/main/Green/Delta/idle.png b/character/main/Green/Delta/idle.png
deleted file mode 100644
index 7520fce..0000000
Binary files a/character/main/Green/Delta/idle.png and /dev/null differ
diff --git a/character/main/Green/Delta/jump.png b/character/main/Green/Delta/jump.png
deleted file mode 100644
index c97d392..0000000
Binary files a/character/main/Green/Delta/jump.png and /dev/null differ
diff --git a/character/main/Green/Delta/stand.png b/character/main/Green/Delta/stand.png
deleted file mode 100644
index 09cfd74..0000000
Binary files a/character/main/Green/Delta/stand.png and /dev/null differ
diff --git a/character/main/Green/Delta/swim_1.png b/character/main/Green/Delta/swim_1.png
deleted file mode 100644
index 248dafb..0000000
Binary files a/character/main/Green/Delta/swim_1.png and /dev/null differ
diff --git a/character/main/Green/Delta/swim_2.png b/character/main/Green/Delta/swim_2.png
deleted file mode 100644
index aa59084..0000000
Binary files a/character/main/Green/Delta/swim_2.png and /dev/null differ
diff --git a/character/main/Green/Delta/walk_1.png b/character/main/Green/Delta/walk_1.png
deleted file mode 100644
index 1bead8b..0000000
Binary files a/character/main/Green/Delta/walk_1.png and /dev/null differ
diff --git a/character/main/Green/Delta/walk_2.png b/character/main/Green/Delta/walk_2.png
deleted file mode 100644
index deb93de..0000000
Binary files a/character/main/Green/Delta/walk_2.png and /dev/null differ
diff --git a/character/main/Green/Gamma/badge_1.png b/character/main/Green/Gamma/badge_1.png
deleted file mode 100644
index a664463..0000000
Binary files a/character/main/Green/Gamma/badge_1.png and /dev/null differ
diff --git a/character/main/Green/Gamma/badge_2.png b/character/main/Green/Gamma/badge_2.png
deleted file mode 100644
index aa7ed76..0000000
Binary files a/character/main/Green/Gamma/badge_2.png and /dev/null differ
diff --git a/character/main/Green/Gamma/climb_1.png b/character/main/Green/Gamma/climb_1.png
deleted file mode 100644
index 1fab230..0000000
Binary files a/character/main/Green/Gamma/climb_1.png and /dev/null differ
diff --git a/character/main/Green/Gamma/climb_2.png b/character/main/Green/Gamma/climb_2.png
deleted file mode 100644
index 400dfbe..0000000
Binary files a/character/main/Green/Gamma/climb_2.png and /dev/null differ
diff --git a/character/main/Green/Gamma/duck.png b/character/main/Green/Gamma/duck.png
deleted file mode 100644
index ef04e09..0000000
Binary files a/character/main/Green/Gamma/duck.png and /dev/null differ
diff --git a/character/main/Green/Gamma/hurt.png b/character/main/Green/Gamma/hurt.png
deleted file mode 100644
index f307897..0000000
Binary files a/character/main/Green/Gamma/hurt.png and /dev/null differ
diff --git a/character/main/Green/Gamma/idle.png b/character/main/Green/Gamma/idle.png
deleted file mode 100644
index f05d6cd..0000000
Binary files a/character/main/Green/Gamma/idle.png and /dev/null differ
diff --git a/character/main/Green/Gamma/jump.png b/character/main/Green/Gamma/jump.png
deleted file mode 100644
index da9cdc3..0000000
Binary files a/character/main/Green/Gamma/jump.png and /dev/null differ
diff --git a/character/main/Green/Gamma/stand.png b/character/main/Green/Gamma/stand.png
deleted file mode 100644
index 4a19ada..0000000
Binary files a/character/main/Green/Gamma/stand.png and /dev/null differ
diff --git a/character/main/Green/Gamma/swim_1.png b/character/main/Green/Gamma/swim_1.png
deleted file mode 100644
index e75bd2d..0000000
Binary files a/character/main/Green/Gamma/swim_1.png and /dev/null differ
diff --git a/character/main/Green/Gamma/swim_2.png b/character/main/Green/Gamma/swim_2.png
deleted file mode 100644
index 4dedbd0..0000000
Binary files a/character/main/Green/Gamma/swim_2.png and /dev/null differ
diff --git a/character/main/Green/Gamma/walk_1.png b/character/main/Green/Gamma/walk_1.png
deleted file mode 100644
index 38fced4..0000000
Binary files a/character/main/Green/Gamma/walk_1.png and /dev/null differ
diff --git a/character/main/Green/Gamma/walk_2.png b/character/main/Green/Gamma/walk_2.png
deleted file mode 100644
index a1d4458..0000000
Binary files a/character/main/Green/Gamma/walk_2.png and /dev/null differ
diff --git a/character/main/Green/Zeta/badge_1.png b/character/main/Green/Zeta/badge_1.png
deleted file mode 100644
index ff8d745..0000000
Binary files a/character/main/Green/Zeta/badge_1.png and /dev/null differ
diff --git a/character/main/Green/Zeta/badge_2.png b/character/main/Green/Zeta/badge_2.png
deleted file mode 100644
index 2557505..0000000
Binary files a/character/main/Green/Zeta/badge_2.png and /dev/null differ
diff --git a/character/main/Green/Zeta/climb_1.png b/character/main/Green/Zeta/climb_1.png
deleted file mode 100644
index 68ca1c7..0000000
Binary files a/character/main/Green/Zeta/climb_1.png and /dev/null differ
diff --git a/character/main/Green/Zeta/climb_2.png b/character/main/Green/Zeta/climb_2.png
deleted file mode 100644
index 10f1360..0000000
Binary files a/character/main/Green/Zeta/climb_2.png and /dev/null differ
diff --git a/character/main/Green/Zeta/duck.png b/character/main/Green/Zeta/duck.png
deleted file mode 100644
index 912aaa5..0000000
Binary files a/character/main/Green/Zeta/duck.png and /dev/null differ
diff --git a/character/main/Green/Zeta/hurt.png b/character/main/Green/Zeta/hurt.png
deleted file mode 100644
index 20bfa85..0000000
Binary files a/character/main/Green/Zeta/hurt.png and /dev/null differ
diff --git a/character/main/Green/Zeta/idle.png b/character/main/Green/Zeta/idle.png
deleted file mode 100644
index 8bd63b9..0000000
Binary files a/character/main/Green/Zeta/idle.png and /dev/null differ
diff --git a/character/main/Green/Zeta/jump.png b/character/main/Green/Zeta/jump.png
deleted file mode 100644
index 45aac4e..0000000
Binary files a/character/main/Green/Zeta/jump.png and /dev/null differ
diff --git a/character/main/Green/Zeta/stand.png b/character/main/Green/Zeta/stand.png
deleted file mode 100644
index 1d8ca5e..0000000
Binary files a/character/main/Green/Zeta/stand.png and /dev/null differ
diff --git a/character/main/Green/Zeta/swim_1.png b/character/main/Green/Zeta/swim_1.png
deleted file mode 100644
index 40b4598..0000000
Binary files a/character/main/Green/Zeta/swim_1.png and /dev/null differ
diff --git a/character/main/Green/Zeta/swim_2.png b/character/main/Green/Zeta/swim_2.png
deleted file mode 100644
index e0b93ff..0000000
Binary files a/character/main/Green/Zeta/swim_2.png and /dev/null differ
diff --git a/character/main/Green/Zeta/walk_1.png b/character/main/Green/Zeta/walk_1.png
deleted file mode 100644
index 2bc5f38..0000000
Binary files a/character/main/Green/Zeta/walk_1.png and /dev/null differ
diff --git a/character/main/Green/Zeta/walk_2.png b/character/main/Green/Zeta/walk_2.png
deleted file mode 100644
index cd42d32..0000000
Binary files a/character/main/Green/Zeta/walk_2.png and /dev/null differ
diff --git a/character/main/Green/green_sheet.png b/character/main/Green/green_sheet.png
deleted file mode 100644
index 31fe388..0000000
Binary files a/character/main/Green/green_sheet.png and /dev/null differ
diff --git a/character/main/Green/green_vector.svg b/character/main/Green/green_vector.svg
deleted file mode 100644
index a3cf022..0000000
--- a/character/main/Green/green_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/main/Purple/Alpha/badge_1.png b/character/main/Purple/Alpha/badge_1.png
deleted file mode 100644
index 4d34d7f..0000000
Binary files a/character/main/Purple/Alpha/badge_1.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/badge_2.png b/character/main/Purple/Alpha/badge_2.png
deleted file mode 100644
index 4bf5d13..0000000
Binary files a/character/main/Purple/Alpha/badge_2.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/climb_1.png b/character/main/Purple/Alpha/climb_1.png
deleted file mode 100644
index 3392943..0000000
Binary files a/character/main/Purple/Alpha/climb_1.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/climb_2.png b/character/main/Purple/Alpha/climb_2.png
deleted file mode 100644
index e83428d..0000000
Binary files a/character/main/Purple/Alpha/climb_2.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/duck.png b/character/main/Purple/Alpha/duck.png
deleted file mode 100644
index c82dcb2..0000000
Binary files a/character/main/Purple/Alpha/duck.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/hurt.png b/character/main/Purple/Alpha/hurt.png
deleted file mode 100644
index 7780b50..0000000
Binary files a/character/main/Purple/Alpha/hurt.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/idle.png b/character/main/Purple/Alpha/idle.png
deleted file mode 100644
index 992acec..0000000
Binary files a/character/main/Purple/Alpha/idle.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/jump.png b/character/main/Purple/Alpha/jump.png
deleted file mode 100644
index 9fc9022..0000000
Binary files a/character/main/Purple/Alpha/jump.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/stand.png b/character/main/Purple/Alpha/stand.png
deleted file mode 100644
index 9bd2326..0000000
Binary files a/character/main/Purple/Alpha/stand.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/swim_1.png b/character/main/Purple/Alpha/swim_1.png
deleted file mode 100644
index 3b0948f..0000000
Binary files a/character/main/Purple/Alpha/swim_1.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/swim_2.png b/character/main/Purple/Alpha/swim_2.png
deleted file mode 100644
index 15c3be6..0000000
Binary files a/character/main/Purple/Alpha/swim_2.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/walk_1.png b/character/main/Purple/Alpha/walk_1.png
deleted file mode 100644
index 5ed4dcb..0000000
Binary files a/character/main/Purple/Alpha/walk_1.png and /dev/null differ
diff --git a/character/main/Purple/Alpha/walk_2.png b/character/main/Purple/Alpha/walk_2.png
deleted file mode 100644
index 84a32c0..0000000
Binary files a/character/main/Purple/Alpha/walk_2.png and /dev/null differ
diff --git a/character/main/Purple/Beta/badge_1.png b/character/main/Purple/Beta/badge_1.png
deleted file mode 100644
index 396938e..0000000
Binary files a/character/main/Purple/Beta/badge_1.png and /dev/null differ
diff --git a/character/main/Purple/Beta/badge_2.png b/character/main/Purple/Beta/badge_2.png
deleted file mode 100644
index 5cddc31..0000000
Binary files a/character/main/Purple/Beta/badge_2.png and /dev/null differ
diff --git a/character/main/Purple/Beta/climb_1.png b/character/main/Purple/Beta/climb_1.png
deleted file mode 100644
index 935e5fb..0000000
Binary files a/character/main/Purple/Beta/climb_1.png and /dev/null differ
diff --git a/character/main/Purple/Beta/climb_2.png b/character/main/Purple/Beta/climb_2.png
deleted file mode 100644
index 27d4cc4..0000000
Binary files a/character/main/Purple/Beta/climb_2.png and /dev/null differ
diff --git a/character/main/Purple/Beta/duck.png b/character/main/Purple/Beta/duck.png
deleted file mode 100644
index 54ae910..0000000
Binary files a/character/main/Purple/Beta/duck.png and /dev/null differ
diff --git a/character/main/Purple/Beta/hurt.png b/character/main/Purple/Beta/hurt.png
deleted file mode 100644
index 0aac328..0000000
Binary files a/character/main/Purple/Beta/hurt.png and /dev/null differ
diff --git a/character/main/Purple/Beta/idle.png b/character/main/Purple/Beta/idle.png
deleted file mode 100644
index 7298f26..0000000
Binary files a/character/main/Purple/Beta/idle.png and /dev/null differ
diff --git a/character/main/Purple/Beta/jump.png b/character/main/Purple/Beta/jump.png
deleted file mode 100644
index 740c670..0000000
Binary files a/character/main/Purple/Beta/jump.png and /dev/null differ
diff --git a/character/main/Purple/Beta/stand.png b/character/main/Purple/Beta/stand.png
deleted file mode 100644
index e79f860..0000000
Binary files a/character/main/Purple/Beta/stand.png and /dev/null differ
diff --git a/character/main/Purple/Beta/swim_1.png b/character/main/Purple/Beta/swim_1.png
deleted file mode 100644
index 1b4c618..0000000
Binary files a/character/main/Purple/Beta/swim_1.png and /dev/null differ
diff --git a/character/main/Purple/Beta/swim_2.png b/character/main/Purple/Beta/swim_2.png
deleted file mode 100644
index e77e021..0000000
Binary files a/character/main/Purple/Beta/swim_2.png and /dev/null differ
diff --git a/character/main/Purple/Beta/walk_1.png b/character/main/Purple/Beta/walk_1.png
deleted file mode 100644
index aac12ea..0000000
Binary files a/character/main/Purple/Beta/walk_1.png and /dev/null differ
diff --git a/character/main/Purple/Beta/walk_2.png b/character/main/Purple/Beta/walk_2.png
deleted file mode 100644
index feecde6..0000000
Binary files a/character/main/Purple/Beta/walk_2.png and /dev/null differ
diff --git a/character/main/Purple/Delta/badge_1.png b/character/main/Purple/Delta/badge_1.png
deleted file mode 100644
index 478575d..0000000
Binary files a/character/main/Purple/Delta/badge_1.png and /dev/null differ
diff --git a/character/main/Purple/Delta/badge_2.png b/character/main/Purple/Delta/badge_2.png
deleted file mode 100644
index 0fae5bb..0000000
Binary files a/character/main/Purple/Delta/badge_2.png and /dev/null differ
diff --git a/character/main/Purple/Delta/climb_1.png b/character/main/Purple/Delta/climb_1.png
deleted file mode 100644
index f01d1ca..0000000
Binary files a/character/main/Purple/Delta/climb_1.png and /dev/null differ
diff --git a/character/main/Purple/Delta/climb_2.png b/character/main/Purple/Delta/climb_2.png
deleted file mode 100644
index c66037c..0000000
Binary files a/character/main/Purple/Delta/climb_2.png and /dev/null differ
diff --git a/character/main/Purple/Delta/duck.png b/character/main/Purple/Delta/duck.png
deleted file mode 100644
index 5e7bfa4..0000000
Binary files a/character/main/Purple/Delta/duck.png and /dev/null differ
diff --git a/character/main/Purple/Delta/hurt.png b/character/main/Purple/Delta/hurt.png
deleted file mode 100644
index 399532b..0000000
Binary files a/character/main/Purple/Delta/hurt.png and /dev/null differ
diff --git a/character/main/Purple/Delta/idle.png b/character/main/Purple/Delta/idle.png
deleted file mode 100644
index b48d5e9..0000000
Binary files a/character/main/Purple/Delta/idle.png and /dev/null differ
diff --git a/character/main/Purple/Delta/jump.png b/character/main/Purple/Delta/jump.png
deleted file mode 100644
index a558cb9..0000000
Binary files a/character/main/Purple/Delta/jump.png and /dev/null differ
diff --git a/character/main/Purple/Delta/stand.png b/character/main/Purple/Delta/stand.png
deleted file mode 100644
index a28b63f..0000000
Binary files a/character/main/Purple/Delta/stand.png and /dev/null differ
diff --git a/character/main/Purple/Delta/swim_1.png b/character/main/Purple/Delta/swim_1.png
deleted file mode 100644
index 19360d3..0000000
Binary files a/character/main/Purple/Delta/swim_1.png and /dev/null differ
diff --git a/character/main/Purple/Delta/swim_2.png b/character/main/Purple/Delta/swim_2.png
deleted file mode 100644
index 45bd969..0000000
Binary files a/character/main/Purple/Delta/swim_2.png and /dev/null differ
diff --git a/character/main/Purple/Delta/walk_1.png b/character/main/Purple/Delta/walk_1.png
deleted file mode 100644
index ccd2256..0000000
Binary files a/character/main/Purple/Delta/walk_1.png and /dev/null differ
diff --git a/character/main/Purple/Delta/walk_2.png b/character/main/Purple/Delta/walk_2.png
deleted file mode 100644
index abe00b6..0000000
Binary files a/character/main/Purple/Delta/walk_2.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/badge_1.png b/character/main/Purple/Gamma/badge_1.png
deleted file mode 100644
index 9782091..0000000
Binary files a/character/main/Purple/Gamma/badge_1.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/badge_2.png b/character/main/Purple/Gamma/badge_2.png
deleted file mode 100644
index 88efd44..0000000
Binary files a/character/main/Purple/Gamma/badge_2.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/climb_1.png b/character/main/Purple/Gamma/climb_1.png
deleted file mode 100644
index 1db32c4..0000000
Binary files a/character/main/Purple/Gamma/climb_1.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/climb_2.png b/character/main/Purple/Gamma/climb_2.png
deleted file mode 100644
index 09e3a03..0000000
Binary files a/character/main/Purple/Gamma/climb_2.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/duck.png b/character/main/Purple/Gamma/duck.png
deleted file mode 100644
index e338ec3..0000000
Binary files a/character/main/Purple/Gamma/duck.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/hurt.png b/character/main/Purple/Gamma/hurt.png
deleted file mode 100644
index 7b3ac55..0000000
Binary files a/character/main/Purple/Gamma/hurt.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/idle.png b/character/main/Purple/Gamma/idle.png
deleted file mode 100644
index 10d9724..0000000
Binary files a/character/main/Purple/Gamma/idle.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/jump.png b/character/main/Purple/Gamma/jump.png
deleted file mode 100644
index 3037bae..0000000
Binary files a/character/main/Purple/Gamma/jump.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/stand.png b/character/main/Purple/Gamma/stand.png
deleted file mode 100644
index d312936..0000000
Binary files a/character/main/Purple/Gamma/stand.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/swim_1.png b/character/main/Purple/Gamma/swim_1.png
deleted file mode 100644
index d73d184..0000000
Binary files a/character/main/Purple/Gamma/swim_1.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/swim_2.png b/character/main/Purple/Gamma/swim_2.png
deleted file mode 100644
index df3a414..0000000
Binary files a/character/main/Purple/Gamma/swim_2.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/walk_1.png b/character/main/Purple/Gamma/walk_1.png
deleted file mode 100644
index 116f9d9..0000000
Binary files a/character/main/Purple/Gamma/walk_1.png and /dev/null differ
diff --git a/character/main/Purple/Gamma/walk_2.png b/character/main/Purple/Gamma/walk_2.png
deleted file mode 100644
index d9d74e9..0000000
Binary files a/character/main/Purple/Gamma/walk_2.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/badge_1.png b/character/main/Purple/Zeta/badge_1.png
deleted file mode 100644
index 3422634..0000000
Binary files a/character/main/Purple/Zeta/badge_1.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/badge_2.png b/character/main/Purple/Zeta/badge_2.png
deleted file mode 100644
index 90df94a..0000000
Binary files a/character/main/Purple/Zeta/badge_2.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/climb_1.png b/character/main/Purple/Zeta/climb_1.png
deleted file mode 100644
index b481a34..0000000
Binary files a/character/main/Purple/Zeta/climb_1.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/climb_2.png b/character/main/Purple/Zeta/climb_2.png
deleted file mode 100644
index 95c9b65..0000000
Binary files a/character/main/Purple/Zeta/climb_2.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/duck.png b/character/main/Purple/Zeta/duck.png
deleted file mode 100644
index 5285fcf..0000000
Binary files a/character/main/Purple/Zeta/duck.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/hurt.png b/character/main/Purple/Zeta/hurt.png
deleted file mode 100644
index ad2bbbd..0000000
Binary files a/character/main/Purple/Zeta/hurt.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/idle.png b/character/main/Purple/Zeta/idle.png
deleted file mode 100644
index fe38ed8..0000000
Binary files a/character/main/Purple/Zeta/idle.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/jump.png b/character/main/Purple/Zeta/jump.png
deleted file mode 100644
index 69245b8..0000000
Binary files a/character/main/Purple/Zeta/jump.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/stand.png b/character/main/Purple/Zeta/stand.png
deleted file mode 100644
index c518197..0000000
Binary files a/character/main/Purple/Zeta/stand.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/swim_1.png b/character/main/Purple/Zeta/swim_1.png
deleted file mode 100644
index cfdacc5..0000000
Binary files a/character/main/Purple/Zeta/swim_1.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/swim_2.png b/character/main/Purple/Zeta/swim_2.png
deleted file mode 100644
index ef8e309..0000000
Binary files a/character/main/Purple/Zeta/swim_2.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/walk_1.png b/character/main/Purple/Zeta/walk_1.png
deleted file mode 100644
index 081fb07..0000000
Binary files a/character/main/Purple/Zeta/walk_1.png and /dev/null differ
diff --git a/character/main/Purple/Zeta/walk_2.png b/character/main/Purple/Zeta/walk_2.png
deleted file mode 100644
index efbfda2..0000000
Binary files a/character/main/Purple/Zeta/walk_2.png and /dev/null differ
diff --git a/character/main/Purple/purple_sheet.png b/character/main/Purple/purple_sheet.png
deleted file mode 100644
index 49871de..0000000
Binary files a/character/main/Purple/purple_sheet.png and /dev/null differ
diff --git a/character/main/Purple/purple_vector.svg b/character/main/Purple/purple_vector.svg
deleted file mode 100644
index 3e5f2b0..0000000
--- a/character/main/Purple/purple_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/main/Red/Alpha/badge_1.png b/character/main/Red/Alpha/badge_1.png
deleted file mode 100644
index 5cfaea8..0000000
Binary files a/character/main/Red/Alpha/badge_1.png and /dev/null differ
diff --git a/character/main/Red/Alpha/badge_2.png b/character/main/Red/Alpha/badge_2.png
deleted file mode 100644
index 34cb2d0..0000000
Binary files a/character/main/Red/Alpha/badge_2.png and /dev/null differ
diff --git a/character/main/Red/Alpha/climb_1.png b/character/main/Red/Alpha/climb_1.png
deleted file mode 100644
index f92aa14..0000000
Binary files a/character/main/Red/Alpha/climb_1.png and /dev/null differ
diff --git a/character/main/Red/Alpha/climb_2.png b/character/main/Red/Alpha/climb_2.png
deleted file mode 100644
index ccfc9f2..0000000
Binary files a/character/main/Red/Alpha/climb_2.png and /dev/null differ
diff --git a/character/main/Red/Alpha/duck.png b/character/main/Red/Alpha/duck.png
deleted file mode 100644
index a5c1651..0000000
Binary files a/character/main/Red/Alpha/duck.png and /dev/null differ
diff --git a/character/main/Red/Alpha/hurt.png b/character/main/Red/Alpha/hurt.png
deleted file mode 100644
index 4f0f2d9..0000000
Binary files a/character/main/Red/Alpha/hurt.png and /dev/null differ
diff --git a/character/main/Red/Alpha/idle.png b/character/main/Red/Alpha/idle.png
deleted file mode 100644
index cf75799..0000000
Binary files a/character/main/Red/Alpha/idle.png and /dev/null differ
diff --git a/character/main/Red/Alpha/jump.png b/character/main/Red/Alpha/jump.png
deleted file mode 100644
index 4ea21e7..0000000
Binary files a/character/main/Red/Alpha/jump.png and /dev/null differ
diff --git a/character/main/Red/Alpha/stand.png b/character/main/Red/Alpha/stand.png
deleted file mode 100644
index e4d40db..0000000
Binary files a/character/main/Red/Alpha/stand.png and /dev/null differ
diff --git a/character/main/Red/Alpha/swim_1.png b/character/main/Red/Alpha/swim_1.png
deleted file mode 100644
index 67d4304..0000000
Binary files a/character/main/Red/Alpha/swim_1.png and /dev/null differ
diff --git a/character/main/Red/Alpha/swim_2.png b/character/main/Red/Alpha/swim_2.png
deleted file mode 100644
index 421ff36..0000000
Binary files a/character/main/Red/Alpha/swim_2.png and /dev/null differ
diff --git a/character/main/Red/Alpha/walk_1.png b/character/main/Red/Alpha/walk_1.png
deleted file mode 100644
index 79a5e48..0000000
Binary files a/character/main/Red/Alpha/walk_1.png and /dev/null differ
diff --git a/character/main/Red/Alpha/walk_2.png b/character/main/Red/Alpha/walk_2.png
deleted file mode 100644
index 964277c..0000000
Binary files a/character/main/Red/Alpha/walk_2.png and /dev/null differ
diff --git a/character/main/Red/Beta/badge_1.png b/character/main/Red/Beta/badge_1.png
deleted file mode 100644
index 27cb252..0000000
Binary files a/character/main/Red/Beta/badge_1.png and /dev/null differ
diff --git a/character/main/Red/Beta/badge_2.png b/character/main/Red/Beta/badge_2.png
deleted file mode 100644
index 9587cdb..0000000
Binary files a/character/main/Red/Beta/badge_2.png and /dev/null differ
diff --git a/character/main/Red/Beta/climb_1.png b/character/main/Red/Beta/climb_1.png
deleted file mode 100644
index 2d00593..0000000
Binary files a/character/main/Red/Beta/climb_1.png and /dev/null differ
diff --git a/character/main/Red/Beta/climb_2.png b/character/main/Red/Beta/climb_2.png
deleted file mode 100644
index 39fc3d5..0000000
Binary files a/character/main/Red/Beta/climb_2.png and /dev/null differ
diff --git a/character/main/Red/Beta/duck.png b/character/main/Red/Beta/duck.png
deleted file mode 100644
index 1593854..0000000
Binary files a/character/main/Red/Beta/duck.png and /dev/null differ
diff --git a/character/main/Red/Beta/hurt.png b/character/main/Red/Beta/hurt.png
deleted file mode 100644
index 3d989ff..0000000
Binary files a/character/main/Red/Beta/hurt.png and /dev/null differ
diff --git a/character/main/Red/Beta/idle.png b/character/main/Red/Beta/idle.png
deleted file mode 100644
index e885323..0000000
Binary files a/character/main/Red/Beta/idle.png and /dev/null differ
diff --git a/character/main/Red/Beta/jump.png b/character/main/Red/Beta/jump.png
deleted file mode 100644
index 3befd93..0000000
Binary files a/character/main/Red/Beta/jump.png and /dev/null differ
diff --git a/character/main/Red/Beta/stand.png b/character/main/Red/Beta/stand.png
deleted file mode 100644
index 17b6a7a..0000000
Binary files a/character/main/Red/Beta/stand.png and /dev/null differ
diff --git a/character/main/Red/Beta/swim_1.png b/character/main/Red/Beta/swim_1.png
deleted file mode 100644
index a7368bc..0000000
Binary files a/character/main/Red/Beta/swim_1.png and /dev/null differ
diff --git a/character/main/Red/Beta/swim_2.png b/character/main/Red/Beta/swim_2.png
deleted file mode 100644
index 0e6d5a2..0000000
Binary files a/character/main/Red/Beta/swim_2.png and /dev/null differ
diff --git a/character/main/Red/Beta/walk_1.png b/character/main/Red/Beta/walk_1.png
deleted file mode 100644
index 2bf861d..0000000
Binary files a/character/main/Red/Beta/walk_1.png and /dev/null differ
diff --git a/character/main/Red/Beta/walk_2.png b/character/main/Red/Beta/walk_2.png
deleted file mode 100644
index 7ce0c23..0000000
Binary files a/character/main/Red/Beta/walk_2.png and /dev/null differ
diff --git a/character/main/Red/Delta/badge_1.png b/character/main/Red/Delta/badge_1.png
deleted file mode 100644
index 8e94757..0000000
Binary files a/character/main/Red/Delta/badge_1.png and /dev/null differ
diff --git a/character/main/Red/Delta/badge_2.png b/character/main/Red/Delta/badge_2.png
deleted file mode 100644
index 28def12..0000000
Binary files a/character/main/Red/Delta/badge_2.png and /dev/null differ
diff --git a/character/main/Red/Delta/climb_1.png b/character/main/Red/Delta/climb_1.png
deleted file mode 100644
index dc3e668..0000000
Binary files a/character/main/Red/Delta/climb_1.png and /dev/null differ
diff --git a/character/main/Red/Delta/climb_2.png b/character/main/Red/Delta/climb_2.png
deleted file mode 100644
index 7b5376f..0000000
Binary files a/character/main/Red/Delta/climb_2.png and /dev/null differ
diff --git a/character/main/Red/Delta/duck.png b/character/main/Red/Delta/duck.png
deleted file mode 100644
index 5641b5d..0000000
Binary files a/character/main/Red/Delta/duck.png and /dev/null differ
diff --git a/character/main/Red/Delta/hurt.png b/character/main/Red/Delta/hurt.png
deleted file mode 100644
index 365a8cf..0000000
Binary files a/character/main/Red/Delta/hurt.png and /dev/null differ
diff --git a/character/main/Red/Delta/idle.png b/character/main/Red/Delta/idle.png
deleted file mode 100644
index b39a409..0000000
Binary files a/character/main/Red/Delta/idle.png and /dev/null differ
diff --git a/character/main/Red/Delta/jump.png b/character/main/Red/Delta/jump.png
deleted file mode 100644
index 1651646..0000000
Binary files a/character/main/Red/Delta/jump.png and /dev/null differ
diff --git a/character/main/Red/Delta/stand.png b/character/main/Red/Delta/stand.png
deleted file mode 100644
index 3052847..0000000
Binary files a/character/main/Red/Delta/stand.png and /dev/null differ
diff --git a/character/main/Red/Delta/swim_1.png b/character/main/Red/Delta/swim_1.png
deleted file mode 100644
index a96a9ca..0000000
Binary files a/character/main/Red/Delta/swim_1.png and /dev/null differ
diff --git a/character/main/Red/Delta/swim_2.png b/character/main/Red/Delta/swim_2.png
deleted file mode 100644
index c275aa1..0000000
Binary files a/character/main/Red/Delta/swim_2.png and /dev/null differ
diff --git a/character/main/Red/Delta/walk_1.png b/character/main/Red/Delta/walk_1.png
deleted file mode 100644
index 3c64b79..0000000
Binary files a/character/main/Red/Delta/walk_1.png and /dev/null differ
diff --git a/character/main/Red/Delta/walk_2.png b/character/main/Red/Delta/walk_2.png
deleted file mode 100644
index 4d839f3..0000000
Binary files a/character/main/Red/Delta/walk_2.png and /dev/null differ
diff --git a/character/main/Red/Gamma/badge_1.png b/character/main/Red/Gamma/badge_1.png
deleted file mode 100644
index 0dcfc80..0000000
Binary files a/character/main/Red/Gamma/badge_1.png and /dev/null differ
diff --git a/character/main/Red/Gamma/badge_2.png b/character/main/Red/Gamma/badge_2.png
deleted file mode 100644
index 258cb9b..0000000
Binary files a/character/main/Red/Gamma/badge_2.png and /dev/null differ
diff --git a/character/main/Red/Gamma/climb_1.png b/character/main/Red/Gamma/climb_1.png
deleted file mode 100644
index b9d00e4..0000000
Binary files a/character/main/Red/Gamma/climb_1.png and /dev/null differ
diff --git a/character/main/Red/Gamma/climb_2.png b/character/main/Red/Gamma/climb_2.png
deleted file mode 100644
index 79128af..0000000
Binary files a/character/main/Red/Gamma/climb_2.png and /dev/null differ
diff --git a/character/main/Red/Gamma/duck.png b/character/main/Red/Gamma/duck.png
deleted file mode 100644
index bf62354..0000000
Binary files a/character/main/Red/Gamma/duck.png and /dev/null differ
diff --git a/character/main/Red/Gamma/hurt.png b/character/main/Red/Gamma/hurt.png
deleted file mode 100644
index 60e4127..0000000
Binary files a/character/main/Red/Gamma/hurt.png and /dev/null differ
diff --git a/character/main/Red/Gamma/idle.png b/character/main/Red/Gamma/idle.png
deleted file mode 100644
index 3911d10..0000000
Binary files a/character/main/Red/Gamma/idle.png and /dev/null differ
diff --git a/character/main/Red/Gamma/jump.png b/character/main/Red/Gamma/jump.png
deleted file mode 100644
index 9baad21..0000000
Binary files a/character/main/Red/Gamma/jump.png and /dev/null differ
diff --git a/character/main/Red/Gamma/stand.png b/character/main/Red/Gamma/stand.png
deleted file mode 100644
index 0142686..0000000
Binary files a/character/main/Red/Gamma/stand.png and /dev/null differ
diff --git a/character/main/Red/Gamma/swim_1.png b/character/main/Red/Gamma/swim_1.png
deleted file mode 100644
index 03fa96b..0000000
Binary files a/character/main/Red/Gamma/swim_1.png and /dev/null differ
diff --git a/character/main/Red/Gamma/swim_2.png b/character/main/Red/Gamma/swim_2.png
deleted file mode 100644
index 1bb1fa9..0000000
Binary files a/character/main/Red/Gamma/swim_2.png and /dev/null differ
diff --git a/character/main/Red/Gamma/walk_1.png b/character/main/Red/Gamma/walk_1.png
deleted file mode 100644
index fe0d644..0000000
Binary files a/character/main/Red/Gamma/walk_1.png and /dev/null differ
diff --git a/character/main/Red/Gamma/walk_2.png b/character/main/Red/Gamma/walk_2.png
deleted file mode 100644
index 6563417..0000000
Binary files a/character/main/Red/Gamma/walk_2.png and /dev/null differ
diff --git a/character/main/Red/Zeta/badge_1.png b/character/main/Red/Zeta/badge_1.png
deleted file mode 100644
index a02fbc1..0000000
Binary files a/character/main/Red/Zeta/badge_1.png and /dev/null differ
diff --git a/character/main/Red/Zeta/badge_2.png b/character/main/Red/Zeta/badge_2.png
deleted file mode 100644
index c562cc9..0000000
Binary files a/character/main/Red/Zeta/badge_2.png and /dev/null differ
diff --git a/character/main/Red/Zeta/climb_1.png b/character/main/Red/Zeta/climb_1.png
deleted file mode 100644
index f4cda7c..0000000
Binary files a/character/main/Red/Zeta/climb_1.png and /dev/null differ
diff --git a/character/main/Red/Zeta/climb_2.png b/character/main/Red/Zeta/climb_2.png
deleted file mode 100644
index 3937926..0000000
Binary files a/character/main/Red/Zeta/climb_2.png and /dev/null differ
diff --git a/character/main/Red/Zeta/duck.png b/character/main/Red/Zeta/duck.png
deleted file mode 100644
index 8efc97d..0000000
Binary files a/character/main/Red/Zeta/duck.png and /dev/null differ
diff --git a/character/main/Red/Zeta/hurt.png b/character/main/Red/Zeta/hurt.png
deleted file mode 100644
index 00436ae..0000000
Binary files a/character/main/Red/Zeta/hurt.png and /dev/null differ
diff --git a/character/main/Red/Zeta/idle.png b/character/main/Red/Zeta/idle.png
deleted file mode 100644
index cc6e2b3..0000000
Binary files a/character/main/Red/Zeta/idle.png and /dev/null differ
diff --git a/character/main/Red/Zeta/jump.png b/character/main/Red/Zeta/jump.png
deleted file mode 100644
index d3b918c..0000000
Binary files a/character/main/Red/Zeta/jump.png and /dev/null differ
diff --git a/character/main/Red/Zeta/stand.png b/character/main/Red/Zeta/stand.png
deleted file mode 100644
index 1599884..0000000
Binary files a/character/main/Red/Zeta/stand.png and /dev/null differ
diff --git a/character/main/Red/Zeta/swim_1.png b/character/main/Red/Zeta/swim_1.png
deleted file mode 100644
index c49a67b..0000000
Binary files a/character/main/Red/Zeta/swim_1.png and /dev/null differ
diff --git a/character/main/Red/Zeta/swim_2.png b/character/main/Red/Zeta/swim_2.png
deleted file mode 100644
index b39d405..0000000
Binary files a/character/main/Red/Zeta/swim_2.png and /dev/null differ
diff --git a/character/main/Red/Zeta/walk_1.png b/character/main/Red/Zeta/walk_1.png
deleted file mode 100644
index 3d76f8d..0000000
Binary files a/character/main/Red/Zeta/walk_1.png and /dev/null differ
diff --git a/character/main/Red/Zeta/walk_2.png b/character/main/Red/Zeta/walk_2.png
deleted file mode 100644
index 4e1b563..0000000
Binary files a/character/main/Red/Zeta/walk_2.png and /dev/null differ
diff --git a/character/main/Red/red_sheet.png b/character/main/Red/red_sheet.png
deleted file mode 100644
index 08207a1..0000000
Binary files a/character/main/Red/red_sheet.png and /dev/null differ
diff --git a/character/main/Red/red_vector.svg b/character/main/Red/red_vector.svg
deleted file mode 100644
index dc0d966..0000000
--- a/character/main/Red/red_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/main/Yellow/Alpha/badge_1.png b/character/main/Yellow/Alpha/badge_1.png
deleted file mode 100644
index e3f3672..0000000
Binary files a/character/main/Yellow/Alpha/badge_1.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/badge_2.png b/character/main/Yellow/Alpha/badge_2.png
deleted file mode 100644
index 68383ca..0000000
Binary files a/character/main/Yellow/Alpha/badge_2.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/climb_1.png b/character/main/Yellow/Alpha/climb_1.png
deleted file mode 100644
index 64962ca..0000000
Binary files a/character/main/Yellow/Alpha/climb_1.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/climb_2.png b/character/main/Yellow/Alpha/climb_2.png
deleted file mode 100644
index b37abf2..0000000
Binary files a/character/main/Yellow/Alpha/climb_2.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/duck.png b/character/main/Yellow/Alpha/duck.png
deleted file mode 100644
index a2f76dc..0000000
Binary files a/character/main/Yellow/Alpha/duck.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/hurt.png b/character/main/Yellow/Alpha/hurt.png
deleted file mode 100644
index b67d03b..0000000
Binary files a/character/main/Yellow/Alpha/hurt.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/idle.png b/character/main/Yellow/Alpha/idle.png
deleted file mode 100644
index 56e423b..0000000
Binary files a/character/main/Yellow/Alpha/idle.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/jump.png b/character/main/Yellow/Alpha/jump.png
deleted file mode 100644
index aeecbc6..0000000
Binary files a/character/main/Yellow/Alpha/jump.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/stand.png b/character/main/Yellow/Alpha/stand.png
deleted file mode 100644
index 2590b3d..0000000
Binary files a/character/main/Yellow/Alpha/stand.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/swim_1.png b/character/main/Yellow/Alpha/swim_1.png
deleted file mode 100644
index 4624b18..0000000
Binary files a/character/main/Yellow/Alpha/swim_1.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/swim_2.png b/character/main/Yellow/Alpha/swim_2.png
deleted file mode 100644
index 2a55133..0000000
Binary files a/character/main/Yellow/Alpha/swim_2.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/walk_1.png b/character/main/Yellow/Alpha/walk_1.png
deleted file mode 100644
index 1188b2e..0000000
Binary files a/character/main/Yellow/Alpha/walk_1.png and /dev/null differ
diff --git a/character/main/Yellow/Alpha/walk_2.png b/character/main/Yellow/Alpha/walk_2.png
deleted file mode 100644
index 91f13a1..0000000
Binary files a/character/main/Yellow/Alpha/walk_2.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/badge_1.png b/character/main/Yellow/Beta/badge_1.png
deleted file mode 100644
index 753190e..0000000
Binary files a/character/main/Yellow/Beta/badge_1.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/badge_2.png b/character/main/Yellow/Beta/badge_2.png
deleted file mode 100644
index 8c9db0b..0000000
Binary files a/character/main/Yellow/Beta/badge_2.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/climb_1.png b/character/main/Yellow/Beta/climb_1.png
deleted file mode 100644
index 58291c3..0000000
Binary files a/character/main/Yellow/Beta/climb_1.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/climb_2.png b/character/main/Yellow/Beta/climb_2.png
deleted file mode 100644
index 7d9a6f1..0000000
Binary files a/character/main/Yellow/Beta/climb_2.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/duck.png b/character/main/Yellow/Beta/duck.png
deleted file mode 100644
index f3e6570..0000000
Binary files a/character/main/Yellow/Beta/duck.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/hurt.png b/character/main/Yellow/Beta/hurt.png
deleted file mode 100644
index ced9e59..0000000
Binary files a/character/main/Yellow/Beta/hurt.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/idle.png b/character/main/Yellow/Beta/idle.png
deleted file mode 100644
index 5de3e9b..0000000
Binary files a/character/main/Yellow/Beta/idle.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/jump.png b/character/main/Yellow/Beta/jump.png
deleted file mode 100644
index e2b50af..0000000
Binary files a/character/main/Yellow/Beta/jump.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/stand.png b/character/main/Yellow/Beta/stand.png
deleted file mode 100644
index 3ae44d7..0000000
Binary files a/character/main/Yellow/Beta/stand.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/swim_1.png b/character/main/Yellow/Beta/swim_1.png
deleted file mode 100644
index 07090fe..0000000
Binary files a/character/main/Yellow/Beta/swim_1.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/swim_2.png b/character/main/Yellow/Beta/swim_2.png
deleted file mode 100644
index 9eb9d46..0000000
Binary files a/character/main/Yellow/Beta/swim_2.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/walk_1.png b/character/main/Yellow/Beta/walk_1.png
deleted file mode 100644
index 77302a5..0000000
Binary files a/character/main/Yellow/Beta/walk_1.png and /dev/null differ
diff --git a/character/main/Yellow/Beta/walk_2.png b/character/main/Yellow/Beta/walk_2.png
deleted file mode 100644
index 0365f32..0000000
Binary files a/character/main/Yellow/Beta/walk_2.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/badge_1.png b/character/main/Yellow/Delta/badge_1.png
deleted file mode 100644
index 7938916..0000000
Binary files a/character/main/Yellow/Delta/badge_1.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/badge_2.png b/character/main/Yellow/Delta/badge_2.png
deleted file mode 100644
index 422df2c..0000000
Binary files a/character/main/Yellow/Delta/badge_2.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/climb_1.png b/character/main/Yellow/Delta/climb_1.png
deleted file mode 100644
index 3255abd..0000000
Binary files a/character/main/Yellow/Delta/climb_1.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/climb_2.png b/character/main/Yellow/Delta/climb_2.png
deleted file mode 100644
index 5e6bce4..0000000
Binary files a/character/main/Yellow/Delta/climb_2.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/duck.png b/character/main/Yellow/Delta/duck.png
deleted file mode 100644
index 030fb7c..0000000
Binary files a/character/main/Yellow/Delta/duck.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/hurt.png b/character/main/Yellow/Delta/hurt.png
deleted file mode 100644
index 0ea2f69..0000000
Binary files a/character/main/Yellow/Delta/hurt.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/idle.png b/character/main/Yellow/Delta/idle.png
deleted file mode 100644
index b83f47d..0000000
Binary files a/character/main/Yellow/Delta/idle.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/jump.png b/character/main/Yellow/Delta/jump.png
deleted file mode 100644
index 8860d58..0000000
Binary files a/character/main/Yellow/Delta/jump.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/stand.png b/character/main/Yellow/Delta/stand.png
deleted file mode 100644
index 12d0734..0000000
Binary files a/character/main/Yellow/Delta/stand.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/swim_1.png b/character/main/Yellow/Delta/swim_1.png
deleted file mode 100644
index 4120ea0..0000000
Binary files a/character/main/Yellow/Delta/swim_1.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/swim_2.png b/character/main/Yellow/Delta/swim_2.png
deleted file mode 100644
index a0374ea..0000000
Binary files a/character/main/Yellow/Delta/swim_2.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/walk_1.png b/character/main/Yellow/Delta/walk_1.png
deleted file mode 100644
index 5925e29..0000000
Binary files a/character/main/Yellow/Delta/walk_1.png and /dev/null differ
diff --git a/character/main/Yellow/Delta/walk_2.png b/character/main/Yellow/Delta/walk_2.png
deleted file mode 100644
index 3baef0a..0000000
Binary files a/character/main/Yellow/Delta/walk_2.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/badge_1.png b/character/main/Yellow/Gamma/badge_1.png
deleted file mode 100644
index 40e3f64..0000000
Binary files a/character/main/Yellow/Gamma/badge_1.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/badge_2.png b/character/main/Yellow/Gamma/badge_2.png
deleted file mode 100644
index 1703acd..0000000
Binary files a/character/main/Yellow/Gamma/badge_2.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/climb_1.png b/character/main/Yellow/Gamma/climb_1.png
deleted file mode 100644
index 0580668..0000000
Binary files a/character/main/Yellow/Gamma/climb_1.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/climb_2.png b/character/main/Yellow/Gamma/climb_2.png
deleted file mode 100644
index 3c8bdbb..0000000
Binary files a/character/main/Yellow/Gamma/climb_2.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/duck.png b/character/main/Yellow/Gamma/duck.png
deleted file mode 100644
index 21da1de..0000000
Binary files a/character/main/Yellow/Gamma/duck.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/hurt.png b/character/main/Yellow/Gamma/hurt.png
deleted file mode 100644
index b34e93d..0000000
Binary files a/character/main/Yellow/Gamma/hurt.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/idle.png b/character/main/Yellow/Gamma/idle.png
deleted file mode 100644
index ed981c0..0000000
Binary files a/character/main/Yellow/Gamma/idle.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/jump.png b/character/main/Yellow/Gamma/jump.png
deleted file mode 100644
index 4767ca5..0000000
Binary files a/character/main/Yellow/Gamma/jump.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/stand.png b/character/main/Yellow/Gamma/stand.png
deleted file mode 100644
index cb9441c..0000000
Binary files a/character/main/Yellow/Gamma/stand.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/swim_1.png b/character/main/Yellow/Gamma/swim_1.png
deleted file mode 100644
index b4394b8..0000000
Binary files a/character/main/Yellow/Gamma/swim_1.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/swim_2.png b/character/main/Yellow/Gamma/swim_2.png
deleted file mode 100644
index f1723f9..0000000
Binary files a/character/main/Yellow/Gamma/swim_2.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/walk_1.png b/character/main/Yellow/Gamma/walk_1.png
deleted file mode 100644
index 5199211..0000000
Binary files a/character/main/Yellow/Gamma/walk_1.png and /dev/null differ
diff --git a/character/main/Yellow/Gamma/walk_2.png b/character/main/Yellow/Gamma/walk_2.png
deleted file mode 100644
index ba2cfe1..0000000
Binary files a/character/main/Yellow/Gamma/walk_2.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/badge_1.png b/character/main/Yellow/Zeta/badge_1.png
deleted file mode 100644
index 52a2211..0000000
Binary files a/character/main/Yellow/Zeta/badge_1.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/badge_2.png b/character/main/Yellow/Zeta/badge_2.png
deleted file mode 100644
index 65e9a47..0000000
Binary files a/character/main/Yellow/Zeta/badge_2.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/climb_1.png b/character/main/Yellow/Zeta/climb_1.png
deleted file mode 100644
index b8264b3..0000000
Binary files a/character/main/Yellow/Zeta/climb_1.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/climb_2.png b/character/main/Yellow/Zeta/climb_2.png
deleted file mode 100644
index 7078592..0000000
Binary files a/character/main/Yellow/Zeta/climb_2.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/duck.png b/character/main/Yellow/Zeta/duck.png
deleted file mode 100644
index bb6703a..0000000
Binary files a/character/main/Yellow/Zeta/duck.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/hurt.png b/character/main/Yellow/Zeta/hurt.png
deleted file mode 100644
index 78666e1..0000000
Binary files a/character/main/Yellow/Zeta/hurt.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/idle.png b/character/main/Yellow/Zeta/idle.png
deleted file mode 100644
index e59e2db..0000000
Binary files a/character/main/Yellow/Zeta/idle.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/jump.png b/character/main/Yellow/Zeta/jump.png
deleted file mode 100644
index 747b1a4..0000000
Binary files a/character/main/Yellow/Zeta/jump.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/stand.png b/character/main/Yellow/Zeta/stand.png
deleted file mode 100644
index c8f7ba1..0000000
Binary files a/character/main/Yellow/Zeta/stand.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/swim_1.png b/character/main/Yellow/Zeta/swim_1.png
deleted file mode 100644
index ed8421c..0000000
Binary files a/character/main/Yellow/Zeta/swim_1.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/swim_2.png b/character/main/Yellow/Zeta/swim_2.png
deleted file mode 100644
index 0e5b541..0000000
Binary files a/character/main/Yellow/Zeta/swim_2.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/walk_1.png b/character/main/Yellow/Zeta/walk_1.png
deleted file mode 100644
index d522d4b..0000000
Binary files a/character/main/Yellow/Zeta/walk_1.png and /dev/null differ
diff --git a/character/main/Yellow/Zeta/walk_2.png b/character/main/Yellow/Zeta/walk_2.png
deleted file mode 100644
index c57ec11..0000000
Binary files a/character/main/Yellow/Zeta/walk_2.png and /dev/null differ
diff --git a/character/main/Yellow/yellow_sheet.png b/character/main/Yellow/yellow_sheet.png
deleted file mode 100644
index 9112675..0000000
Binary files a/character/main/Yellow/yellow_sheet.png and /dev/null differ
diff --git a/character/main/Yellow/yellow_vector.svg b/character/main/Yellow/yellow_vector.svg
deleted file mode 100644
index 6789cab..0000000
--- a/character/main/Yellow/yellow_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/main/license.txt b/character/main/license.txt
deleted file mode 100644
index 8b342ff..0000000
--- a/character/main/license.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-###############################################################################
-
- Platformer Art (Xeno Diversity) by Arsonide
-
- ------------------------------
-
- License (CC0)
- http://creativecommons.org/publicdomain/zero/1.0/
-
- You may use these graphics in personal and commercial projects.
- Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
- Credit Arsonide would also be nice but is not mandatory.
-
-###############################################################################
\ No newline at end of file
diff --git a/character/main/master_sheet.png b/character/main/master_sheet.png
deleted file mode 100644
index a7d25c5..0000000
Binary files a/character/main/master_sheet.png and /dev/null differ
diff --git a/character/main/p1_duck.png b/character/main/p1_duck.png
deleted file mode 100644
index ef9ec41..0000000
Binary files a/character/main/p1_duck.png and /dev/null differ
diff --git a/character/main/p1_duck_l.png b/character/main/p1_duck_l.png
deleted file mode 100644
index 98601ff..0000000
Binary files a/character/main/p1_duck_l.png and /dev/null differ
diff --git a/character/main/p1_front.png b/character/main/p1_front.png
deleted file mode 100644
index 1dbe260..0000000
Binary files a/character/main/p1_front.png and /dev/null differ
diff --git a/character/main/p1_hurt.png b/character/main/p1_hurt.png
deleted file mode 100644
index b89d366..0000000
Binary files a/character/main/p1_hurt.png and /dev/null differ
diff --git a/character/main/p1_jump.png b/character/main/p1_jump.png
deleted file mode 100644
index b735399..0000000
Binary files a/character/main/p1_jump.png and /dev/null differ
diff --git a/character/main/p1_jump_l.png b/character/main/p1_jump_l.png
deleted file mode 100644
index 63d3241..0000000
Binary files a/character/main/p1_jump_l.png and /dev/null differ
diff --git a/character/main/p1_spritesheet.png b/character/main/p1_spritesheet.png
deleted file mode 100644
index 6dc17f2..0000000
Binary files a/character/main/p1_spritesheet.png and /dev/null differ
diff --git a/character/main/p1_spritesheet.txt b/character/main/p1_spritesheet.txt
deleted file mode 100644
index 73387e3..0000000
--- a/character/main/p1_spritesheet.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-p1_duck = 365 98 69 71
-p1_front = 0 196 66 92
-p1_hurt = 438 0 69 92
-p1_jump = 438 93 67 94
-p1_stand = 67 196 66 92
-p1_walk01 = 0 0 72 97
-p1_walk02 = 73 0 72 97
-p1_walk03 = 146 0 72 97
-p1_walk04 = 0 98 72 97
-p1_walk05 = 73 98 72 97
-p1_walk06 = 146 98 72 97
-p1_walk07 = 219 0 72 97
-p1_walk08 = 292 0 72 97
-p1_walk09 = 219 98 72 97
-p1_walk10 = 365 0 72 97
-p1_walk11 = 292 98 72 97
diff --git a/character/main/p1_stand.png b/character/main/p1_stand.png
deleted file mode 100644
index e7613ad..0000000
Binary files a/character/main/p1_stand.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk1.png b/character/main/p1_walk/PNG/p1_walk1.png
deleted file mode 100644
index 0470616..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk1.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk10.png b/character/main/p1_walk/PNG/p1_walk10.png
deleted file mode 100644
index 41053eb..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk10.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk11.png b/character/main/p1_walk/PNG/p1_walk11.png
deleted file mode 100644
index 1cef9e3..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk11.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk2.png b/character/main/p1_walk/PNG/p1_walk2.png
deleted file mode 100644
index d5613b0..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk2.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk3.png b/character/main/p1_walk/PNG/p1_walk3.png
deleted file mode 100644
index f148178..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk3.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk4.png b/character/main/p1_walk/PNG/p1_walk4.png
deleted file mode 100644
index 878152c..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk4.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk5.png b/character/main/p1_walk/PNG/p1_walk5.png
deleted file mode 100644
index 7bc369b..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk5.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk6.png b/character/main/p1_walk/PNG/p1_walk6.png
deleted file mode 100644
index 0a80b03..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk6.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk7.png b/character/main/p1_walk/PNG/p1_walk7.png
deleted file mode 100644
index d570bda..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk7.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk8.png b/character/main/p1_walk/PNG/p1_walk8.png
deleted file mode 100644
index bdfd4f6..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk8.png and /dev/null differ
diff --git a/character/main/p1_walk/PNG/p1_walk9.png b/character/main/p1_walk/PNG/p1_walk9.png
deleted file mode 100644
index d57448c..0000000
Binary files a/character/main/p1_walk/PNG/p1_walk9.png and /dev/null differ
diff --git a/character/main/p1_walk/p1_walk.json b/character/main/p1_walk/p1_walk.json
deleted file mode 100644
index 684d5a0..0000000
Binary files a/character/main/p1_walk/p1_walk.json and /dev/null differ
diff --git a/character/main/p1_walk/p1_walk.png b/character/main/p1_walk/p1_walk.png
deleted file mode 100644
index 692a0e0..0000000
Binary files a/character/main/p1_walk/p1_walk.png and /dev/null differ
diff --git a/character/main/p2_duck.png b/character/main/p2_duck.png
deleted file mode 100644
index b0b9812..0000000
Binary files a/character/main/p2_duck.png and /dev/null differ
diff --git a/character/main/p2_duck_l.png b/character/main/p2_duck_l.png
deleted file mode 100644
index 16edfd7..0000000
Binary files a/character/main/p2_duck_l.png and /dev/null differ
diff --git a/character/main/p2_front.png b/character/main/p2_front.png
deleted file mode 100644
index 95b66ac..0000000
Binary files a/character/main/p2_front.png and /dev/null differ
diff --git a/character/main/p2_hurt.png b/character/main/p2_hurt.png
deleted file mode 100644
index 0058ed3..0000000
Binary files a/character/main/p2_hurt.png and /dev/null differ
diff --git a/character/main/p2_jump.png b/character/main/p2_jump.png
deleted file mode 100644
index b5d467a..0000000
Binary files a/character/main/p2_jump.png and /dev/null differ
diff --git a/character/main/p2_jump_l.png b/character/main/p2_jump_l.png
deleted file mode 100644
index 2bfc60b..0000000
Binary files a/character/main/p2_jump_l.png and /dev/null differ
diff --git a/character/main/p2_spritesheet.png b/character/main/p2_spritesheet.png
deleted file mode 100644
index d2dfa8b..0000000
Binary files a/character/main/p2_spritesheet.png and /dev/null differ
diff --git a/character/main/p2_spritesheet.txt b/character/main/p2_spritesheet.txt
deleted file mode 100644
index 1649947..0000000
--- a/character/main/p2_spritesheet.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-p2_duck = 355 95 67 72
-p2_front = 0 190 66 92
-p2_hurt = 426 0 67 92
-p2_jump = 423 95 66 94
-p2_stand = 67 190 66 92
-p2_walk01 = 0 0 70 94
-p2_walk02 = 71 0 70 94
-p2_walk03 = 142 0 70 94
-p2_walk04 = 0 95 70 94
-p2_walk05 = 71 95 70 94
-p2_walk06 = 142 95 70 94
-p2_walk07 = 213 0 70 94
-p2_walk08 = 284 0 70 94
-p2_walk09 = 213 95 70 94
-p2_walk10 = 355 0 70 94
-p2_walk11 = 284 95 70 94
diff --git a/character/main/p2_stand.png b/character/main/p2_stand.png
deleted file mode 100644
index f3a52ee..0000000
Binary files a/character/main/p2_stand.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk1.png b/character/main/p2_walk/PNG/p2_walk1.png
deleted file mode 100644
index baf710f..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk1.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk10.png b/character/main/p2_walk/PNG/p2_walk10.png
deleted file mode 100644
index 7409e77..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk10.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk11.png b/character/main/p2_walk/PNG/p2_walk11.png
deleted file mode 100644
index 53d6534..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk11.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk2.png b/character/main/p2_walk/PNG/p2_walk2.png
deleted file mode 100644
index 4e8e10b..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk2.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk3.png b/character/main/p2_walk/PNG/p2_walk3.png
deleted file mode 100644
index 3492b45..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk3.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk4.png b/character/main/p2_walk/PNG/p2_walk4.png
deleted file mode 100644
index e28891e..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk4.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk5.png b/character/main/p2_walk/PNG/p2_walk5.png
deleted file mode 100644
index 0f4b8bc..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk5.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk6.png b/character/main/p2_walk/PNG/p2_walk6.png
deleted file mode 100644
index 9fc723b..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk6.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk7.png b/character/main/p2_walk/PNG/p2_walk7.png
deleted file mode 100644
index 2931121..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk7.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk8.png b/character/main/p2_walk/PNG/p2_walk8.png
deleted file mode 100644
index 0967074..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk8.png and /dev/null differ
diff --git a/character/main/p2_walk/PNG/p2_walk9.png b/character/main/p2_walk/PNG/p2_walk9.png
deleted file mode 100644
index 34fa9c7..0000000
Binary files a/character/main/p2_walk/PNG/p2_walk9.png and /dev/null differ
diff --git a/character/main/p2_walk/p2_walk.json b/character/main/p2_walk/p2_walk.json
deleted file mode 100644
index 0812415..0000000
Binary files a/character/main/p2_walk/p2_walk.json and /dev/null differ
diff --git a/character/main/p2_walk/p2_walk.png b/character/main/p2_walk/p2_walk.png
deleted file mode 100644
index 2b50f03..0000000
Binary files a/character/main/p2_walk/p2_walk.png and /dev/null differ
diff --git a/character/main/p3_duck.png b/character/main/p3_duck.png
deleted file mode 100644
index 8bd9c85..0000000
Binary files a/character/main/p3_duck.png and /dev/null differ
diff --git a/character/main/p3_duck_l.png b/character/main/p3_duck_l.png
deleted file mode 100644
index 7d42dea..0000000
Binary files a/character/main/p3_duck_l.png and /dev/null differ
diff --git a/character/main/p3_front.png b/character/main/p3_front.png
deleted file mode 100644
index 736d240..0000000
Binary files a/character/main/p3_front.png and /dev/null differ
diff --git a/character/main/p3_hurt.png b/character/main/p3_hurt.png
deleted file mode 100644
index 250e6e8..0000000
Binary files a/character/main/p3_hurt.png and /dev/null differ
diff --git a/character/main/p3_jump.png b/character/main/p3_jump.png
deleted file mode 100644
index 6bab534..0000000
Binary files a/character/main/p3_jump.png and /dev/null differ
diff --git a/character/main/p3_jump_l.png b/character/main/p3_jump_l.png
deleted file mode 100644
index 6b9d0c4..0000000
Binary files a/character/main/p3_jump_l.png and /dev/null differ
diff --git a/character/main/p3_spritesheet.png b/character/main/p3_spritesheet.png
deleted file mode 100644
index 9e09eeb..0000000
Binary files a/character/main/p3_spritesheet.png and /dev/null differ
diff --git a/character/main/p3_spritesheet.txt b/character/main/p3_spritesheet.txt
deleted file mode 100644
index 3be97ff..0000000
--- a/character/main/p3_spritesheet.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-p3_duck = 365 98 69 71
-p3_front = 0 196 66 92
-p3_hurt = 438 0 69 92
-p3_jump = 438 93 67 94
-p3_stand = 67 196 66 92
-p3_walk01 = 0 0 72 97
-p3_walk02 = 73 0 72 97
-p3_walk03 = 146 0 72 97
-p3_walk04 = 0 98 72 97
-p3_walk05 = 73 98 72 97
-p3_walk06 = 146 98 72 97
-p3_walk07 = 219 0 72 97
-p3_walk08 = 292 0 72 97
-p3_walk09 = 219 98 72 97
-p3_walk10 = 365 0 72 97
-p3_walk11 = 292 98 72 97
diff --git a/character/main/p3_stand.png b/character/main/p3_stand.png
deleted file mode 100644
index 7900bb8..0000000
Binary files a/character/main/p3_stand.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk1.png b/character/main/p3_walk/PNG/p3_walk1.png
deleted file mode 100644
index f0acba5..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk1.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk10.png b/character/main/p3_walk/PNG/p3_walk10.png
deleted file mode 100644
index a736726..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk10.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk11.png b/character/main/p3_walk/PNG/p3_walk11.png
deleted file mode 100644
index 87c5ca0..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk11.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk2.png b/character/main/p3_walk/PNG/p3_walk2.png
deleted file mode 100644
index 23af2be..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk2.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk3.png b/character/main/p3_walk/PNG/p3_walk3.png
deleted file mode 100644
index e837c65..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk3.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk4.png b/character/main/p3_walk/PNG/p3_walk4.png
deleted file mode 100644
index c8f4cfd..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk4.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk5.png b/character/main/p3_walk/PNG/p3_walk5.png
deleted file mode 100644
index 05f6034..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk5.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk6.png b/character/main/p3_walk/PNG/p3_walk6.png
deleted file mode 100644
index b160623..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk6.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk7.png b/character/main/p3_walk/PNG/p3_walk7.png
deleted file mode 100644
index d0a282b..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk7.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk8.png b/character/main/p3_walk/PNG/p3_walk8.png
deleted file mode 100644
index f39e060..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk8.png and /dev/null differ
diff --git a/character/main/p3_walk/PNG/p3_walk9.png b/character/main/p3_walk/PNG/p3_walk9.png
deleted file mode 100644
index 7a79e67..0000000
Binary files a/character/main/p3_walk/PNG/p3_walk9.png and /dev/null differ
diff --git a/character/main/p3_walk/p3_walk.json b/character/main/p3_walk/p3_walk.json
deleted file mode 100644
index a3b8110..0000000
Binary files a/character/main/p3_walk/p3_walk.json and /dev/null differ
diff --git a/character/main/p3_walk/p3_walk.png b/character/main/p3_walk/p3_walk.png
deleted file mode 100644
index 7f6ac12..0000000
Binary files a/character/main/p3_walk/p3_walk.png and /dev/null differ
diff --git a/character/main/preview.png b/character/main/preview.png
deleted file mode 100644
index 71a2849..0000000
Binary files a/character/main/preview.png and /dev/null differ
diff --git a/character/main/sample.png b/character/main/sample.png
deleted file mode 100644
index 808c9ce..0000000
Binary files a/character/main/sample.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/badge_1.png b/character/unused/Beige/Alpha/badge_1.png
deleted file mode 100644
index 6030dd7..0000000
Binary files a/character/unused/Beige/Alpha/badge_1.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/badge_2.png b/character/unused/Beige/Alpha/badge_2.png
deleted file mode 100644
index de12fa8..0000000
Binary files a/character/unused/Beige/Alpha/badge_2.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/climb_1.png b/character/unused/Beige/Alpha/climb_1.png
deleted file mode 100644
index 42e78a1..0000000
Binary files a/character/unused/Beige/Alpha/climb_1.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/climb_2.png b/character/unused/Beige/Alpha/climb_2.png
deleted file mode 100644
index e7b42da..0000000
Binary files a/character/unused/Beige/Alpha/climb_2.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/duck.png b/character/unused/Beige/Alpha/duck.png
deleted file mode 100644
index 0e591e2..0000000
Binary files a/character/unused/Beige/Alpha/duck.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/hurt.png b/character/unused/Beige/Alpha/hurt.png
deleted file mode 100644
index fbd79d3..0000000
Binary files a/character/unused/Beige/Alpha/hurt.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/idle.png b/character/unused/Beige/Alpha/idle.png
deleted file mode 100644
index 06912f3..0000000
Binary files a/character/unused/Beige/Alpha/idle.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/jump.png b/character/unused/Beige/Alpha/jump.png
deleted file mode 100644
index 7b83397..0000000
Binary files a/character/unused/Beige/Alpha/jump.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/stand.png b/character/unused/Beige/Alpha/stand.png
deleted file mode 100644
index 5d49b74..0000000
Binary files a/character/unused/Beige/Alpha/stand.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/swim_1.png b/character/unused/Beige/Alpha/swim_1.png
deleted file mode 100644
index 731fb68..0000000
Binary files a/character/unused/Beige/Alpha/swim_1.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/swim_2.png b/character/unused/Beige/Alpha/swim_2.png
deleted file mode 100644
index 175aa95..0000000
Binary files a/character/unused/Beige/Alpha/swim_2.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/walk_1.png b/character/unused/Beige/Alpha/walk_1.png
deleted file mode 100644
index 9a7e402..0000000
Binary files a/character/unused/Beige/Alpha/walk_1.png and /dev/null differ
diff --git a/character/unused/Beige/Alpha/walk_2.png b/character/unused/Beige/Alpha/walk_2.png
deleted file mode 100644
index 08fa18c..0000000
Binary files a/character/unused/Beige/Alpha/walk_2.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/badge_1.png b/character/unused/Beige/Beta/badge_1.png
deleted file mode 100644
index 1538364..0000000
Binary files a/character/unused/Beige/Beta/badge_1.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/badge_2.png b/character/unused/Beige/Beta/badge_2.png
deleted file mode 100644
index 0b19aad..0000000
Binary files a/character/unused/Beige/Beta/badge_2.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/climb_1.png b/character/unused/Beige/Beta/climb_1.png
deleted file mode 100644
index 278c542..0000000
Binary files a/character/unused/Beige/Beta/climb_1.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/climb_2.png b/character/unused/Beige/Beta/climb_2.png
deleted file mode 100644
index f9b4212..0000000
Binary files a/character/unused/Beige/Beta/climb_2.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/duck.png b/character/unused/Beige/Beta/duck.png
deleted file mode 100644
index 6105120..0000000
Binary files a/character/unused/Beige/Beta/duck.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/hurt.png b/character/unused/Beige/Beta/hurt.png
deleted file mode 100644
index 3c6376d..0000000
Binary files a/character/unused/Beige/Beta/hurt.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/idle.png b/character/unused/Beige/Beta/idle.png
deleted file mode 100644
index 3bb4929..0000000
Binary files a/character/unused/Beige/Beta/idle.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/jump.png b/character/unused/Beige/Beta/jump.png
deleted file mode 100644
index 4693ea7..0000000
Binary files a/character/unused/Beige/Beta/jump.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/stand.png b/character/unused/Beige/Beta/stand.png
deleted file mode 100644
index 8e82de5..0000000
Binary files a/character/unused/Beige/Beta/stand.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/swim_1.png b/character/unused/Beige/Beta/swim_1.png
deleted file mode 100644
index c9e40e8..0000000
Binary files a/character/unused/Beige/Beta/swim_1.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/swim_2.png b/character/unused/Beige/Beta/swim_2.png
deleted file mode 100644
index df16e53..0000000
Binary files a/character/unused/Beige/Beta/swim_2.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/walk_1.png b/character/unused/Beige/Beta/walk_1.png
deleted file mode 100644
index 7d9a78b..0000000
Binary files a/character/unused/Beige/Beta/walk_1.png and /dev/null differ
diff --git a/character/unused/Beige/Beta/walk_2.png b/character/unused/Beige/Beta/walk_2.png
deleted file mode 100644
index 18761e6..0000000
Binary files a/character/unused/Beige/Beta/walk_2.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/badge_1.png b/character/unused/Beige/Delta/badge_1.png
deleted file mode 100644
index 0b64013..0000000
Binary files a/character/unused/Beige/Delta/badge_1.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/badge_2.png b/character/unused/Beige/Delta/badge_2.png
deleted file mode 100644
index 9086523..0000000
Binary files a/character/unused/Beige/Delta/badge_2.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/climb_1.png b/character/unused/Beige/Delta/climb_1.png
deleted file mode 100644
index d185222..0000000
Binary files a/character/unused/Beige/Delta/climb_1.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/climb_2.png b/character/unused/Beige/Delta/climb_2.png
deleted file mode 100644
index 957459d..0000000
Binary files a/character/unused/Beige/Delta/climb_2.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/duck.png b/character/unused/Beige/Delta/duck.png
deleted file mode 100644
index eeeb56b..0000000
Binary files a/character/unused/Beige/Delta/duck.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/hurt.png b/character/unused/Beige/Delta/hurt.png
deleted file mode 100644
index 1e140bb..0000000
Binary files a/character/unused/Beige/Delta/hurt.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/idle.png b/character/unused/Beige/Delta/idle.png
deleted file mode 100644
index b624962..0000000
Binary files a/character/unused/Beige/Delta/idle.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/jump.png b/character/unused/Beige/Delta/jump.png
deleted file mode 100644
index 917e6e3..0000000
Binary files a/character/unused/Beige/Delta/jump.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/stand.png b/character/unused/Beige/Delta/stand.png
deleted file mode 100644
index 66c975b..0000000
Binary files a/character/unused/Beige/Delta/stand.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/swim_1.png b/character/unused/Beige/Delta/swim_1.png
deleted file mode 100644
index 181befc..0000000
Binary files a/character/unused/Beige/Delta/swim_1.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/swim_2.png b/character/unused/Beige/Delta/swim_2.png
deleted file mode 100644
index 35535dc..0000000
Binary files a/character/unused/Beige/Delta/swim_2.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/walk_1.png b/character/unused/Beige/Delta/walk_1.png
deleted file mode 100644
index b01ca0f..0000000
Binary files a/character/unused/Beige/Delta/walk_1.png and /dev/null differ
diff --git a/character/unused/Beige/Delta/walk_2.png b/character/unused/Beige/Delta/walk_2.png
deleted file mode 100644
index 918b3f5..0000000
Binary files a/character/unused/Beige/Delta/walk_2.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/badge_1.png b/character/unused/Beige/Gamma/badge_1.png
deleted file mode 100644
index 74be8e9..0000000
Binary files a/character/unused/Beige/Gamma/badge_1.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/badge_2.png b/character/unused/Beige/Gamma/badge_2.png
deleted file mode 100644
index 4ec4a93..0000000
Binary files a/character/unused/Beige/Gamma/badge_2.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/climb_1.png b/character/unused/Beige/Gamma/climb_1.png
deleted file mode 100644
index ec650fd..0000000
Binary files a/character/unused/Beige/Gamma/climb_1.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/climb_2.png b/character/unused/Beige/Gamma/climb_2.png
deleted file mode 100644
index feba8bc..0000000
Binary files a/character/unused/Beige/Gamma/climb_2.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/duck.png b/character/unused/Beige/Gamma/duck.png
deleted file mode 100644
index 92ef438..0000000
Binary files a/character/unused/Beige/Gamma/duck.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/hurt.png b/character/unused/Beige/Gamma/hurt.png
deleted file mode 100644
index 236dac3..0000000
Binary files a/character/unused/Beige/Gamma/hurt.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/idle.png b/character/unused/Beige/Gamma/idle.png
deleted file mode 100644
index 42b9a74..0000000
Binary files a/character/unused/Beige/Gamma/idle.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/jump.png b/character/unused/Beige/Gamma/jump.png
deleted file mode 100644
index 0a332b6..0000000
Binary files a/character/unused/Beige/Gamma/jump.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/stand.png b/character/unused/Beige/Gamma/stand.png
deleted file mode 100644
index 4d41793..0000000
Binary files a/character/unused/Beige/Gamma/stand.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/swim_1.png b/character/unused/Beige/Gamma/swim_1.png
deleted file mode 100644
index 98f8035..0000000
Binary files a/character/unused/Beige/Gamma/swim_1.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/swim_2.png b/character/unused/Beige/Gamma/swim_2.png
deleted file mode 100644
index c2c5eb8..0000000
Binary files a/character/unused/Beige/Gamma/swim_2.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/walk_1.png b/character/unused/Beige/Gamma/walk_1.png
deleted file mode 100644
index 8283b88..0000000
Binary files a/character/unused/Beige/Gamma/walk_1.png and /dev/null differ
diff --git a/character/unused/Beige/Gamma/walk_2.png b/character/unused/Beige/Gamma/walk_2.png
deleted file mode 100644
index 5eefdf4..0000000
Binary files a/character/unused/Beige/Gamma/walk_2.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/badge_1.png b/character/unused/Beige/Zeta/badge_1.png
deleted file mode 100644
index 4b9aaab..0000000
Binary files a/character/unused/Beige/Zeta/badge_1.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/badge_2.png b/character/unused/Beige/Zeta/badge_2.png
deleted file mode 100644
index 888b254..0000000
Binary files a/character/unused/Beige/Zeta/badge_2.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/climb_1.png b/character/unused/Beige/Zeta/climb_1.png
deleted file mode 100644
index 2ae4453..0000000
Binary files a/character/unused/Beige/Zeta/climb_1.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/climb_2.png b/character/unused/Beige/Zeta/climb_2.png
deleted file mode 100644
index 4482768..0000000
Binary files a/character/unused/Beige/Zeta/climb_2.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/duck.png b/character/unused/Beige/Zeta/duck.png
deleted file mode 100644
index ff06b82..0000000
Binary files a/character/unused/Beige/Zeta/duck.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/hurt.png b/character/unused/Beige/Zeta/hurt.png
deleted file mode 100644
index 23db54a..0000000
Binary files a/character/unused/Beige/Zeta/hurt.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/idle.png b/character/unused/Beige/Zeta/idle.png
deleted file mode 100644
index 9b6f02b..0000000
Binary files a/character/unused/Beige/Zeta/idle.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/jump.png b/character/unused/Beige/Zeta/jump.png
deleted file mode 100644
index afd2b21..0000000
Binary files a/character/unused/Beige/Zeta/jump.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/stand.png b/character/unused/Beige/Zeta/stand.png
deleted file mode 100644
index b19397f..0000000
Binary files a/character/unused/Beige/Zeta/stand.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/swim_1.png b/character/unused/Beige/Zeta/swim_1.png
deleted file mode 100644
index 53ddd62..0000000
Binary files a/character/unused/Beige/Zeta/swim_1.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/swim_2.png b/character/unused/Beige/Zeta/swim_2.png
deleted file mode 100644
index 9a22094..0000000
Binary files a/character/unused/Beige/Zeta/swim_2.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/walk_1.png b/character/unused/Beige/Zeta/walk_1.png
deleted file mode 100644
index 583c589..0000000
Binary files a/character/unused/Beige/Zeta/walk_1.png and /dev/null differ
diff --git a/character/unused/Beige/Zeta/walk_2.png b/character/unused/Beige/Zeta/walk_2.png
deleted file mode 100644
index 4835dad..0000000
Binary files a/character/unused/Beige/Zeta/walk_2.png and /dev/null differ
diff --git a/character/unused/Beige/beige_sheet.png b/character/unused/Beige/beige_sheet.png
deleted file mode 100644
index 1b55867..0000000
Binary files a/character/unused/Beige/beige_sheet.png and /dev/null differ
diff --git a/character/unused/Beige/beige_vector.svg b/character/unused/Beige/beige_vector.svg
deleted file mode 100644
index a82dbb1..0000000
--- a/character/unused/Beige/beige_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/unused/Blue/Alpha/badge_1.png b/character/unused/Blue/Alpha/badge_1.png
deleted file mode 100644
index 2dc0618..0000000
Binary files a/character/unused/Blue/Alpha/badge_1.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/badge_2.png b/character/unused/Blue/Alpha/badge_2.png
deleted file mode 100644
index 901d805..0000000
Binary files a/character/unused/Blue/Alpha/badge_2.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/climb_1.png b/character/unused/Blue/Alpha/climb_1.png
deleted file mode 100644
index 1696c3b..0000000
Binary files a/character/unused/Blue/Alpha/climb_1.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/climb_2.png b/character/unused/Blue/Alpha/climb_2.png
deleted file mode 100644
index 04233f1..0000000
Binary files a/character/unused/Blue/Alpha/climb_2.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/duck.png b/character/unused/Blue/Alpha/duck.png
deleted file mode 100644
index 51c77dd..0000000
Binary files a/character/unused/Blue/Alpha/duck.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/hurt.png b/character/unused/Blue/Alpha/hurt.png
deleted file mode 100644
index 07dd5c0..0000000
Binary files a/character/unused/Blue/Alpha/hurt.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/idle.png b/character/unused/Blue/Alpha/idle.png
deleted file mode 100644
index b41e54a..0000000
Binary files a/character/unused/Blue/Alpha/idle.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/jump.png b/character/unused/Blue/Alpha/jump.png
deleted file mode 100644
index 7f27b43..0000000
Binary files a/character/unused/Blue/Alpha/jump.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/stand.png b/character/unused/Blue/Alpha/stand.png
deleted file mode 100644
index 959a9d1..0000000
Binary files a/character/unused/Blue/Alpha/stand.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/swim_1.png b/character/unused/Blue/Alpha/swim_1.png
deleted file mode 100644
index 99e9d43..0000000
Binary files a/character/unused/Blue/Alpha/swim_1.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/swim_2.png b/character/unused/Blue/Alpha/swim_2.png
deleted file mode 100644
index e80301a..0000000
Binary files a/character/unused/Blue/Alpha/swim_2.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/walk_1.png b/character/unused/Blue/Alpha/walk_1.png
deleted file mode 100644
index 36dffe9..0000000
Binary files a/character/unused/Blue/Alpha/walk_1.png and /dev/null differ
diff --git a/character/unused/Blue/Alpha/walk_2.png b/character/unused/Blue/Alpha/walk_2.png
deleted file mode 100644
index 80c081b..0000000
Binary files a/character/unused/Blue/Alpha/walk_2.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/badge_1.png b/character/unused/Blue/Beta/badge_1.png
deleted file mode 100644
index b21933c..0000000
Binary files a/character/unused/Blue/Beta/badge_1.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/badge_2.png b/character/unused/Blue/Beta/badge_2.png
deleted file mode 100644
index 2616265..0000000
Binary files a/character/unused/Blue/Beta/badge_2.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/climb_1.png b/character/unused/Blue/Beta/climb_1.png
deleted file mode 100644
index adf98a5..0000000
Binary files a/character/unused/Blue/Beta/climb_1.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/climb_2.png b/character/unused/Blue/Beta/climb_2.png
deleted file mode 100644
index 9bd4d6a..0000000
Binary files a/character/unused/Blue/Beta/climb_2.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/duck.png b/character/unused/Blue/Beta/duck.png
deleted file mode 100644
index 65fd320..0000000
Binary files a/character/unused/Blue/Beta/duck.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/hurt.png b/character/unused/Blue/Beta/hurt.png
deleted file mode 100644
index 7e20c36..0000000
Binary files a/character/unused/Blue/Beta/hurt.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/idle.png b/character/unused/Blue/Beta/idle.png
deleted file mode 100644
index 3f35c70..0000000
Binary files a/character/unused/Blue/Beta/idle.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/jump.png b/character/unused/Blue/Beta/jump.png
deleted file mode 100644
index 2337537..0000000
Binary files a/character/unused/Blue/Beta/jump.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/stand.png b/character/unused/Blue/Beta/stand.png
deleted file mode 100644
index da059ce..0000000
Binary files a/character/unused/Blue/Beta/stand.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/swim_1.png b/character/unused/Blue/Beta/swim_1.png
deleted file mode 100644
index b4720a3..0000000
Binary files a/character/unused/Blue/Beta/swim_1.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/swim_2.png b/character/unused/Blue/Beta/swim_2.png
deleted file mode 100644
index 3e1cee5..0000000
Binary files a/character/unused/Blue/Beta/swim_2.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/walk_1.png b/character/unused/Blue/Beta/walk_1.png
deleted file mode 100644
index bbef849..0000000
Binary files a/character/unused/Blue/Beta/walk_1.png and /dev/null differ
diff --git a/character/unused/Blue/Beta/walk_2.png b/character/unused/Blue/Beta/walk_2.png
deleted file mode 100644
index 505066c..0000000
Binary files a/character/unused/Blue/Beta/walk_2.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/badge_1.png b/character/unused/Blue/Delta/badge_1.png
deleted file mode 100644
index f895eb8..0000000
Binary files a/character/unused/Blue/Delta/badge_1.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/badge_2.png b/character/unused/Blue/Delta/badge_2.png
deleted file mode 100644
index 13eb277..0000000
Binary files a/character/unused/Blue/Delta/badge_2.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/climb_1.png b/character/unused/Blue/Delta/climb_1.png
deleted file mode 100644
index 697b6c4..0000000
Binary files a/character/unused/Blue/Delta/climb_1.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/climb_2.png b/character/unused/Blue/Delta/climb_2.png
deleted file mode 100644
index a5dcb2f..0000000
Binary files a/character/unused/Blue/Delta/climb_2.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/duck.png b/character/unused/Blue/Delta/duck.png
deleted file mode 100644
index a34d271..0000000
Binary files a/character/unused/Blue/Delta/duck.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/hurt.png b/character/unused/Blue/Delta/hurt.png
deleted file mode 100644
index 632f29e..0000000
Binary files a/character/unused/Blue/Delta/hurt.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/idle.png b/character/unused/Blue/Delta/idle.png
deleted file mode 100644
index ea19992..0000000
Binary files a/character/unused/Blue/Delta/idle.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/jump.png b/character/unused/Blue/Delta/jump.png
deleted file mode 100644
index e533edf..0000000
Binary files a/character/unused/Blue/Delta/jump.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/stand.png b/character/unused/Blue/Delta/stand.png
deleted file mode 100644
index 3ccdfbc..0000000
Binary files a/character/unused/Blue/Delta/stand.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/swim_1.png b/character/unused/Blue/Delta/swim_1.png
deleted file mode 100644
index 32fa555..0000000
Binary files a/character/unused/Blue/Delta/swim_1.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/swim_2.png b/character/unused/Blue/Delta/swim_2.png
deleted file mode 100644
index c55632b..0000000
Binary files a/character/unused/Blue/Delta/swim_2.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/walk_1.png b/character/unused/Blue/Delta/walk_1.png
deleted file mode 100644
index 8d0c3f8..0000000
Binary files a/character/unused/Blue/Delta/walk_1.png and /dev/null differ
diff --git a/character/unused/Blue/Delta/walk_2.png b/character/unused/Blue/Delta/walk_2.png
deleted file mode 100644
index be2ae9b..0000000
Binary files a/character/unused/Blue/Delta/walk_2.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/badge_1.png b/character/unused/Blue/Gamma/badge_1.png
deleted file mode 100644
index b77acc1..0000000
Binary files a/character/unused/Blue/Gamma/badge_1.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/badge_2.png b/character/unused/Blue/Gamma/badge_2.png
deleted file mode 100644
index 53ab45f..0000000
Binary files a/character/unused/Blue/Gamma/badge_2.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/climb_1.png b/character/unused/Blue/Gamma/climb_1.png
deleted file mode 100644
index 4badfae..0000000
Binary files a/character/unused/Blue/Gamma/climb_1.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/climb_2.png b/character/unused/Blue/Gamma/climb_2.png
deleted file mode 100644
index 8ddcee0..0000000
Binary files a/character/unused/Blue/Gamma/climb_2.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/duck.png b/character/unused/Blue/Gamma/duck.png
deleted file mode 100644
index 774fb8c..0000000
Binary files a/character/unused/Blue/Gamma/duck.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/hurt.png b/character/unused/Blue/Gamma/hurt.png
deleted file mode 100644
index 38266d9..0000000
Binary files a/character/unused/Blue/Gamma/hurt.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/idle.png b/character/unused/Blue/Gamma/idle.png
deleted file mode 100644
index 0049bc6..0000000
Binary files a/character/unused/Blue/Gamma/idle.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/jump.png b/character/unused/Blue/Gamma/jump.png
deleted file mode 100644
index 91af75d..0000000
Binary files a/character/unused/Blue/Gamma/jump.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/stand.png b/character/unused/Blue/Gamma/stand.png
deleted file mode 100644
index 68299cf..0000000
Binary files a/character/unused/Blue/Gamma/stand.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/swim_1.png b/character/unused/Blue/Gamma/swim_1.png
deleted file mode 100644
index 99ede6c..0000000
Binary files a/character/unused/Blue/Gamma/swim_1.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/swim_2.png b/character/unused/Blue/Gamma/swim_2.png
deleted file mode 100644
index aa63a38..0000000
Binary files a/character/unused/Blue/Gamma/swim_2.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/walk_1.png b/character/unused/Blue/Gamma/walk_1.png
deleted file mode 100644
index 063b89d..0000000
Binary files a/character/unused/Blue/Gamma/walk_1.png and /dev/null differ
diff --git a/character/unused/Blue/Gamma/walk_2.png b/character/unused/Blue/Gamma/walk_2.png
deleted file mode 100644
index 5cc7421..0000000
Binary files a/character/unused/Blue/Gamma/walk_2.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/badge_1.png b/character/unused/Blue/Zeta/badge_1.png
deleted file mode 100644
index c650326..0000000
Binary files a/character/unused/Blue/Zeta/badge_1.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/badge_2.png b/character/unused/Blue/Zeta/badge_2.png
deleted file mode 100644
index e388e4e..0000000
Binary files a/character/unused/Blue/Zeta/badge_2.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/climb_1.png b/character/unused/Blue/Zeta/climb_1.png
deleted file mode 100644
index a722913..0000000
Binary files a/character/unused/Blue/Zeta/climb_1.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/climb_2.png b/character/unused/Blue/Zeta/climb_2.png
deleted file mode 100644
index 33b76bd..0000000
Binary files a/character/unused/Blue/Zeta/climb_2.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/duck.png b/character/unused/Blue/Zeta/duck.png
deleted file mode 100644
index 14ead88..0000000
Binary files a/character/unused/Blue/Zeta/duck.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/hurt.png b/character/unused/Blue/Zeta/hurt.png
deleted file mode 100644
index f26e265..0000000
Binary files a/character/unused/Blue/Zeta/hurt.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/idle.png b/character/unused/Blue/Zeta/idle.png
deleted file mode 100644
index b29f5cb..0000000
Binary files a/character/unused/Blue/Zeta/idle.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/jump.png b/character/unused/Blue/Zeta/jump.png
deleted file mode 100644
index 71a302c..0000000
Binary files a/character/unused/Blue/Zeta/jump.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/stand.png b/character/unused/Blue/Zeta/stand.png
deleted file mode 100644
index 631b79e..0000000
Binary files a/character/unused/Blue/Zeta/stand.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/swim_1.png b/character/unused/Blue/Zeta/swim_1.png
deleted file mode 100644
index 395d541..0000000
Binary files a/character/unused/Blue/Zeta/swim_1.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/swim_2.png b/character/unused/Blue/Zeta/swim_2.png
deleted file mode 100644
index d8caa14..0000000
Binary files a/character/unused/Blue/Zeta/swim_2.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/walk_1.png b/character/unused/Blue/Zeta/walk_1.png
deleted file mode 100644
index e0b5ae2..0000000
Binary files a/character/unused/Blue/Zeta/walk_1.png and /dev/null differ
diff --git a/character/unused/Blue/Zeta/walk_2.png b/character/unused/Blue/Zeta/walk_2.png
deleted file mode 100644
index 1b23a01..0000000
Binary files a/character/unused/Blue/Zeta/walk_2.png and /dev/null differ
diff --git a/character/unused/Blue/blue_sheet.png b/character/unused/Blue/blue_sheet.png
deleted file mode 100644
index 4b2ebaa..0000000
Binary files a/character/unused/Blue/blue_sheet.png and /dev/null differ
diff --git a/character/unused/Blue/blue_vector.svg b/character/unused/Blue/blue_vector.svg
deleted file mode 100644
index bf8dc1b..0000000
--- a/character/unused/Blue/blue_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/unused/Green/Alpha/badge_1.png b/character/unused/Green/Alpha/badge_1.png
deleted file mode 100644
index 1d03d54..0000000
Binary files a/character/unused/Green/Alpha/badge_1.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/badge_2.png b/character/unused/Green/Alpha/badge_2.png
deleted file mode 100644
index 8101242..0000000
Binary files a/character/unused/Green/Alpha/badge_2.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/climb_1.png b/character/unused/Green/Alpha/climb_1.png
deleted file mode 100644
index 7181452..0000000
Binary files a/character/unused/Green/Alpha/climb_1.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/climb_2.png b/character/unused/Green/Alpha/climb_2.png
deleted file mode 100644
index 9b0e571..0000000
Binary files a/character/unused/Green/Alpha/climb_2.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/duck.png b/character/unused/Green/Alpha/duck.png
deleted file mode 100644
index 3684f3c..0000000
Binary files a/character/unused/Green/Alpha/duck.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/hurt.png b/character/unused/Green/Alpha/hurt.png
deleted file mode 100644
index 9c5d0f0..0000000
Binary files a/character/unused/Green/Alpha/hurt.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/idle.png b/character/unused/Green/Alpha/idle.png
deleted file mode 100644
index 5da8db1..0000000
Binary files a/character/unused/Green/Alpha/idle.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/jump.png b/character/unused/Green/Alpha/jump.png
deleted file mode 100644
index 7bf9938..0000000
Binary files a/character/unused/Green/Alpha/jump.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/stand.png b/character/unused/Green/Alpha/stand.png
deleted file mode 100644
index 4c3f0d1..0000000
Binary files a/character/unused/Green/Alpha/stand.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/swim_1.png b/character/unused/Green/Alpha/swim_1.png
deleted file mode 100644
index 2a74554..0000000
Binary files a/character/unused/Green/Alpha/swim_1.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/swim_2.png b/character/unused/Green/Alpha/swim_2.png
deleted file mode 100644
index d80fd30..0000000
Binary files a/character/unused/Green/Alpha/swim_2.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/walk_1.png b/character/unused/Green/Alpha/walk_1.png
deleted file mode 100644
index 5efa479..0000000
Binary files a/character/unused/Green/Alpha/walk_1.png and /dev/null differ
diff --git a/character/unused/Green/Alpha/walk_2.png b/character/unused/Green/Alpha/walk_2.png
deleted file mode 100644
index 916cc63..0000000
Binary files a/character/unused/Green/Alpha/walk_2.png and /dev/null differ
diff --git a/character/unused/Green/Beta/badge_1.png b/character/unused/Green/Beta/badge_1.png
deleted file mode 100644
index 6b2fde3..0000000
Binary files a/character/unused/Green/Beta/badge_1.png and /dev/null differ
diff --git a/character/unused/Green/Beta/badge_2.png b/character/unused/Green/Beta/badge_2.png
deleted file mode 100644
index 5af53bd..0000000
Binary files a/character/unused/Green/Beta/badge_2.png and /dev/null differ
diff --git a/character/unused/Green/Beta/climb_1.png b/character/unused/Green/Beta/climb_1.png
deleted file mode 100644
index adadd32..0000000
Binary files a/character/unused/Green/Beta/climb_1.png and /dev/null differ
diff --git a/character/unused/Green/Beta/climb_2.png b/character/unused/Green/Beta/climb_2.png
deleted file mode 100644
index 888c4ac..0000000
Binary files a/character/unused/Green/Beta/climb_2.png and /dev/null differ
diff --git a/character/unused/Green/Beta/duck.png b/character/unused/Green/Beta/duck.png
deleted file mode 100644
index c51639c..0000000
Binary files a/character/unused/Green/Beta/duck.png and /dev/null differ
diff --git a/character/unused/Green/Beta/hurt.png b/character/unused/Green/Beta/hurt.png
deleted file mode 100644
index edbb230..0000000
Binary files a/character/unused/Green/Beta/hurt.png and /dev/null differ
diff --git a/character/unused/Green/Beta/idle.png b/character/unused/Green/Beta/idle.png
deleted file mode 100644
index 9889622..0000000
Binary files a/character/unused/Green/Beta/idle.png and /dev/null differ
diff --git a/character/unused/Green/Beta/jump.png b/character/unused/Green/Beta/jump.png
deleted file mode 100644
index 0bf7ae4..0000000
Binary files a/character/unused/Green/Beta/jump.png and /dev/null differ
diff --git a/character/unused/Green/Beta/stand.png b/character/unused/Green/Beta/stand.png
deleted file mode 100644
index 7810252..0000000
Binary files a/character/unused/Green/Beta/stand.png and /dev/null differ
diff --git a/character/unused/Green/Beta/swim_1.png b/character/unused/Green/Beta/swim_1.png
deleted file mode 100644
index d816935..0000000
Binary files a/character/unused/Green/Beta/swim_1.png and /dev/null differ
diff --git a/character/unused/Green/Beta/swim_2.png b/character/unused/Green/Beta/swim_2.png
deleted file mode 100644
index 261b61d..0000000
Binary files a/character/unused/Green/Beta/swim_2.png and /dev/null differ
diff --git a/character/unused/Green/Beta/walk_1.png b/character/unused/Green/Beta/walk_1.png
deleted file mode 100644
index 90e45b1..0000000
Binary files a/character/unused/Green/Beta/walk_1.png and /dev/null differ
diff --git a/character/unused/Green/Beta/walk_2.png b/character/unused/Green/Beta/walk_2.png
deleted file mode 100644
index ab3e611..0000000
Binary files a/character/unused/Green/Beta/walk_2.png and /dev/null differ
diff --git a/character/unused/Green/Delta/badge_1.png b/character/unused/Green/Delta/badge_1.png
deleted file mode 100644
index 6137be4..0000000
Binary files a/character/unused/Green/Delta/badge_1.png and /dev/null differ
diff --git a/character/unused/Green/Delta/badge_2.png b/character/unused/Green/Delta/badge_2.png
deleted file mode 100644
index cb56d9c..0000000
Binary files a/character/unused/Green/Delta/badge_2.png and /dev/null differ
diff --git a/character/unused/Green/Delta/climb_1.png b/character/unused/Green/Delta/climb_1.png
deleted file mode 100644
index 344287c..0000000
Binary files a/character/unused/Green/Delta/climb_1.png and /dev/null differ
diff --git a/character/unused/Green/Delta/climb_2.png b/character/unused/Green/Delta/climb_2.png
deleted file mode 100644
index 2a957bd..0000000
Binary files a/character/unused/Green/Delta/climb_2.png and /dev/null differ
diff --git a/character/unused/Green/Delta/duck.png b/character/unused/Green/Delta/duck.png
deleted file mode 100644
index b02991f..0000000
Binary files a/character/unused/Green/Delta/duck.png and /dev/null differ
diff --git a/character/unused/Green/Delta/hurt.png b/character/unused/Green/Delta/hurt.png
deleted file mode 100644
index 63d7a37..0000000
Binary files a/character/unused/Green/Delta/hurt.png and /dev/null differ
diff --git a/character/unused/Green/Delta/idle.png b/character/unused/Green/Delta/idle.png
deleted file mode 100644
index 7520fce..0000000
Binary files a/character/unused/Green/Delta/idle.png and /dev/null differ
diff --git a/character/unused/Green/Delta/jump.png b/character/unused/Green/Delta/jump.png
deleted file mode 100644
index c97d392..0000000
Binary files a/character/unused/Green/Delta/jump.png and /dev/null differ
diff --git a/character/unused/Green/Delta/stand.png b/character/unused/Green/Delta/stand.png
deleted file mode 100644
index 09cfd74..0000000
Binary files a/character/unused/Green/Delta/stand.png and /dev/null differ
diff --git a/character/unused/Green/Delta/swim_1.png b/character/unused/Green/Delta/swim_1.png
deleted file mode 100644
index 248dafb..0000000
Binary files a/character/unused/Green/Delta/swim_1.png and /dev/null differ
diff --git a/character/unused/Green/Delta/swim_2.png b/character/unused/Green/Delta/swim_2.png
deleted file mode 100644
index aa59084..0000000
Binary files a/character/unused/Green/Delta/swim_2.png and /dev/null differ
diff --git a/character/unused/Green/Delta/walk_1.png b/character/unused/Green/Delta/walk_1.png
deleted file mode 100644
index 1bead8b..0000000
Binary files a/character/unused/Green/Delta/walk_1.png and /dev/null differ
diff --git a/character/unused/Green/Delta/walk_2.png b/character/unused/Green/Delta/walk_2.png
deleted file mode 100644
index deb93de..0000000
Binary files a/character/unused/Green/Delta/walk_2.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/badge_1.png b/character/unused/Green/Gamma/badge_1.png
deleted file mode 100644
index a664463..0000000
Binary files a/character/unused/Green/Gamma/badge_1.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/badge_2.png b/character/unused/Green/Gamma/badge_2.png
deleted file mode 100644
index aa7ed76..0000000
Binary files a/character/unused/Green/Gamma/badge_2.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/climb_1.png b/character/unused/Green/Gamma/climb_1.png
deleted file mode 100644
index 1fab230..0000000
Binary files a/character/unused/Green/Gamma/climb_1.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/climb_2.png b/character/unused/Green/Gamma/climb_2.png
deleted file mode 100644
index 400dfbe..0000000
Binary files a/character/unused/Green/Gamma/climb_2.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/duck.png b/character/unused/Green/Gamma/duck.png
deleted file mode 100644
index ef04e09..0000000
Binary files a/character/unused/Green/Gamma/duck.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/hurt.png b/character/unused/Green/Gamma/hurt.png
deleted file mode 100644
index f307897..0000000
Binary files a/character/unused/Green/Gamma/hurt.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/idle.png b/character/unused/Green/Gamma/idle.png
deleted file mode 100644
index f05d6cd..0000000
Binary files a/character/unused/Green/Gamma/idle.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/jump.png b/character/unused/Green/Gamma/jump.png
deleted file mode 100644
index da9cdc3..0000000
Binary files a/character/unused/Green/Gamma/jump.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/stand.png b/character/unused/Green/Gamma/stand.png
deleted file mode 100644
index 4a19ada..0000000
Binary files a/character/unused/Green/Gamma/stand.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/swim_1.png b/character/unused/Green/Gamma/swim_1.png
deleted file mode 100644
index e75bd2d..0000000
Binary files a/character/unused/Green/Gamma/swim_1.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/swim_2.png b/character/unused/Green/Gamma/swim_2.png
deleted file mode 100644
index 4dedbd0..0000000
Binary files a/character/unused/Green/Gamma/swim_2.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/walk_1.png b/character/unused/Green/Gamma/walk_1.png
deleted file mode 100644
index 38fced4..0000000
Binary files a/character/unused/Green/Gamma/walk_1.png and /dev/null differ
diff --git a/character/unused/Green/Gamma/walk_2.png b/character/unused/Green/Gamma/walk_2.png
deleted file mode 100644
index a1d4458..0000000
Binary files a/character/unused/Green/Gamma/walk_2.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/badge_1.png b/character/unused/Green/Zeta/badge_1.png
deleted file mode 100644
index ff8d745..0000000
Binary files a/character/unused/Green/Zeta/badge_1.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/badge_2.png b/character/unused/Green/Zeta/badge_2.png
deleted file mode 100644
index 2557505..0000000
Binary files a/character/unused/Green/Zeta/badge_2.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/climb_1.png b/character/unused/Green/Zeta/climb_1.png
deleted file mode 100644
index 68ca1c7..0000000
Binary files a/character/unused/Green/Zeta/climb_1.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/climb_2.png b/character/unused/Green/Zeta/climb_2.png
deleted file mode 100644
index 10f1360..0000000
Binary files a/character/unused/Green/Zeta/climb_2.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/duck.png b/character/unused/Green/Zeta/duck.png
deleted file mode 100644
index 912aaa5..0000000
Binary files a/character/unused/Green/Zeta/duck.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/hurt.png b/character/unused/Green/Zeta/hurt.png
deleted file mode 100644
index 20bfa85..0000000
Binary files a/character/unused/Green/Zeta/hurt.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/idle.png b/character/unused/Green/Zeta/idle.png
deleted file mode 100644
index 8bd63b9..0000000
Binary files a/character/unused/Green/Zeta/idle.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/jump.png b/character/unused/Green/Zeta/jump.png
deleted file mode 100644
index 45aac4e..0000000
Binary files a/character/unused/Green/Zeta/jump.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/stand.png b/character/unused/Green/Zeta/stand.png
deleted file mode 100644
index 1d8ca5e..0000000
Binary files a/character/unused/Green/Zeta/stand.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/swim_1.png b/character/unused/Green/Zeta/swim_1.png
deleted file mode 100644
index 40b4598..0000000
Binary files a/character/unused/Green/Zeta/swim_1.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/swim_2.png b/character/unused/Green/Zeta/swim_2.png
deleted file mode 100644
index e0b93ff..0000000
Binary files a/character/unused/Green/Zeta/swim_2.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/walk_1.png b/character/unused/Green/Zeta/walk_1.png
deleted file mode 100644
index 2bc5f38..0000000
Binary files a/character/unused/Green/Zeta/walk_1.png and /dev/null differ
diff --git a/character/unused/Green/Zeta/walk_2.png b/character/unused/Green/Zeta/walk_2.png
deleted file mode 100644
index cd42d32..0000000
Binary files a/character/unused/Green/Zeta/walk_2.png and /dev/null differ
diff --git a/character/unused/Green/green_sheet.png b/character/unused/Green/green_sheet.png
deleted file mode 100644
index 31fe388..0000000
Binary files a/character/unused/Green/green_sheet.png and /dev/null differ
diff --git a/character/unused/Green/green_vector.svg b/character/unused/Green/green_vector.svg
deleted file mode 100644
index a3cf022..0000000
--- a/character/unused/Green/green_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/unused/Purple/Alpha/badge_1.png b/character/unused/Purple/Alpha/badge_1.png
deleted file mode 100644
index 4d34d7f..0000000
Binary files a/character/unused/Purple/Alpha/badge_1.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/badge_2.png b/character/unused/Purple/Alpha/badge_2.png
deleted file mode 100644
index 4bf5d13..0000000
Binary files a/character/unused/Purple/Alpha/badge_2.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/climb_1.png b/character/unused/Purple/Alpha/climb_1.png
deleted file mode 100644
index 3392943..0000000
Binary files a/character/unused/Purple/Alpha/climb_1.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/climb_2.png b/character/unused/Purple/Alpha/climb_2.png
deleted file mode 100644
index e83428d..0000000
Binary files a/character/unused/Purple/Alpha/climb_2.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/duck.png b/character/unused/Purple/Alpha/duck.png
deleted file mode 100644
index c82dcb2..0000000
Binary files a/character/unused/Purple/Alpha/duck.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/hurt.png b/character/unused/Purple/Alpha/hurt.png
deleted file mode 100644
index 7780b50..0000000
Binary files a/character/unused/Purple/Alpha/hurt.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/idle.png b/character/unused/Purple/Alpha/idle.png
deleted file mode 100644
index 992acec..0000000
Binary files a/character/unused/Purple/Alpha/idle.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/jump.png b/character/unused/Purple/Alpha/jump.png
deleted file mode 100644
index 9fc9022..0000000
Binary files a/character/unused/Purple/Alpha/jump.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/stand.png b/character/unused/Purple/Alpha/stand.png
deleted file mode 100644
index 9bd2326..0000000
Binary files a/character/unused/Purple/Alpha/stand.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/swim_1.png b/character/unused/Purple/Alpha/swim_1.png
deleted file mode 100644
index 3b0948f..0000000
Binary files a/character/unused/Purple/Alpha/swim_1.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/swim_2.png b/character/unused/Purple/Alpha/swim_2.png
deleted file mode 100644
index 15c3be6..0000000
Binary files a/character/unused/Purple/Alpha/swim_2.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/walk_1.png b/character/unused/Purple/Alpha/walk_1.png
deleted file mode 100644
index 5ed4dcb..0000000
Binary files a/character/unused/Purple/Alpha/walk_1.png and /dev/null differ
diff --git a/character/unused/Purple/Alpha/walk_2.png b/character/unused/Purple/Alpha/walk_2.png
deleted file mode 100644
index 84a32c0..0000000
Binary files a/character/unused/Purple/Alpha/walk_2.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/badge_1.png b/character/unused/Purple/Beta/badge_1.png
deleted file mode 100644
index 396938e..0000000
Binary files a/character/unused/Purple/Beta/badge_1.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/badge_2.png b/character/unused/Purple/Beta/badge_2.png
deleted file mode 100644
index 5cddc31..0000000
Binary files a/character/unused/Purple/Beta/badge_2.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/climb_1.png b/character/unused/Purple/Beta/climb_1.png
deleted file mode 100644
index 935e5fb..0000000
Binary files a/character/unused/Purple/Beta/climb_1.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/climb_2.png b/character/unused/Purple/Beta/climb_2.png
deleted file mode 100644
index 27d4cc4..0000000
Binary files a/character/unused/Purple/Beta/climb_2.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/duck.png b/character/unused/Purple/Beta/duck.png
deleted file mode 100644
index 54ae910..0000000
Binary files a/character/unused/Purple/Beta/duck.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/hurt.png b/character/unused/Purple/Beta/hurt.png
deleted file mode 100644
index 0aac328..0000000
Binary files a/character/unused/Purple/Beta/hurt.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/idle.png b/character/unused/Purple/Beta/idle.png
deleted file mode 100644
index 7298f26..0000000
Binary files a/character/unused/Purple/Beta/idle.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/jump.png b/character/unused/Purple/Beta/jump.png
deleted file mode 100644
index 740c670..0000000
Binary files a/character/unused/Purple/Beta/jump.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/stand.png b/character/unused/Purple/Beta/stand.png
deleted file mode 100644
index e79f860..0000000
Binary files a/character/unused/Purple/Beta/stand.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/swim_1.png b/character/unused/Purple/Beta/swim_1.png
deleted file mode 100644
index 1b4c618..0000000
Binary files a/character/unused/Purple/Beta/swim_1.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/swim_2.png b/character/unused/Purple/Beta/swim_2.png
deleted file mode 100644
index e77e021..0000000
Binary files a/character/unused/Purple/Beta/swim_2.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/walk_1.png b/character/unused/Purple/Beta/walk_1.png
deleted file mode 100644
index aac12ea..0000000
Binary files a/character/unused/Purple/Beta/walk_1.png and /dev/null differ
diff --git a/character/unused/Purple/Beta/walk_2.png b/character/unused/Purple/Beta/walk_2.png
deleted file mode 100644
index feecde6..0000000
Binary files a/character/unused/Purple/Beta/walk_2.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/badge_1.png b/character/unused/Purple/Delta/badge_1.png
deleted file mode 100644
index 478575d..0000000
Binary files a/character/unused/Purple/Delta/badge_1.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/badge_2.png b/character/unused/Purple/Delta/badge_2.png
deleted file mode 100644
index 0fae5bb..0000000
Binary files a/character/unused/Purple/Delta/badge_2.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/climb_1.png b/character/unused/Purple/Delta/climb_1.png
deleted file mode 100644
index f01d1ca..0000000
Binary files a/character/unused/Purple/Delta/climb_1.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/climb_2.png b/character/unused/Purple/Delta/climb_2.png
deleted file mode 100644
index c66037c..0000000
Binary files a/character/unused/Purple/Delta/climb_2.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/duck.png b/character/unused/Purple/Delta/duck.png
deleted file mode 100644
index 5e7bfa4..0000000
Binary files a/character/unused/Purple/Delta/duck.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/hurt.png b/character/unused/Purple/Delta/hurt.png
deleted file mode 100644
index 399532b..0000000
Binary files a/character/unused/Purple/Delta/hurt.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/idle.png b/character/unused/Purple/Delta/idle.png
deleted file mode 100644
index b48d5e9..0000000
Binary files a/character/unused/Purple/Delta/idle.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/jump.png b/character/unused/Purple/Delta/jump.png
deleted file mode 100644
index a558cb9..0000000
Binary files a/character/unused/Purple/Delta/jump.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/stand.png b/character/unused/Purple/Delta/stand.png
deleted file mode 100644
index a28b63f..0000000
Binary files a/character/unused/Purple/Delta/stand.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/swim_1.png b/character/unused/Purple/Delta/swim_1.png
deleted file mode 100644
index 19360d3..0000000
Binary files a/character/unused/Purple/Delta/swim_1.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/swim_2.png b/character/unused/Purple/Delta/swim_2.png
deleted file mode 100644
index 45bd969..0000000
Binary files a/character/unused/Purple/Delta/swim_2.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/walk_1.png b/character/unused/Purple/Delta/walk_1.png
deleted file mode 100644
index ccd2256..0000000
Binary files a/character/unused/Purple/Delta/walk_1.png and /dev/null differ
diff --git a/character/unused/Purple/Delta/walk_2.png b/character/unused/Purple/Delta/walk_2.png
deleted file mode 100644
index abe00b6..0000000
Binary files a/character/unused/Purple/Delta/walk_2.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/badge_1.png b/character/unused/Purple/Gamma/badge_1.png
deleted file mode 100644
index 9782091..0000000
Binary files a/character/unused/Purple/Gamma/badge_1.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/badge_2.png b/character/unused/Purple/Gamma/badge_2.png
deleted file mode 100644
index 88efd44..0000000
Binary files a/character/unused/Purple/Gamma/badge_2.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/climb_1.png b/character/unused/Purple/Gamma/climb_1.png
deleted file mode 100644
index 1db32c4..0000000
Binary files a/character/unused/Purple/Gamma/climb_1.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/climb_2.png b/character/unused/Purple/Gamma/climb_2.png
deleted file mode 100644
index 09e3a03..0000000
Binary files a/character/unused/Purple/Gamma/climb_2.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/duck.png b/character/unused/Purple/Gamma/duck.png
deleted file mode 100644
index e338ec3..0000000
Binary files a/character/unused/Purple/Gamma/duck.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/hurt.png b/character/unused/Purple/Gamma/hurt.png
deleted file mode 100644
index 7b3ac55..0000000
Binary files a/character/unused/Purple/Gamma/hurt.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/idle.png b/character/unused/Purple/Gamma/idle.png
deleted file mode 100644
index 10d9724..0000000
Binary files a/character/unused/Purple/Gamma/idle.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/jump.png b/character/unused/Purple/Gamma/jump.png
deleted file mode 100644
index 3037bae..0000000
Binary files a/character/unused/Purple/Gamma/jump.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/stand.png b/character/unused/Purple/Gamma/stand.png
deleted file mode 100644
index d312936..0000000
Binary files a/character/unused/Purple/Gamma/stand.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/swim_1.png b/character/unused/Purple/Gamma/swim_1.png
deleted file mode 100644
index d73d184..0000000
Binary files a/character/unused/Purple/Gamma/swim_1.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/swim_2.png b/character/unused/Purple/Gamma/swim_2.png
deleted file mode 100644
index df3a414..0000000
Binary files a/character/unused/Purple/Gamma/swim_2.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/walk_1.png b/character/unused/Purple/Gamma/walk_1.png
deleted file mode 100644
index 116f9d9..0000000
Binary files a/character/unused/Purple/Gamma/walk_1.png and /dev/null differ
diff --git a/character/unused/Purple/Gamma/walk_2.png b/character/unused/Purple/Gamma/walk_2.png
deleted file mode 100644
index d9d74e9..0000000
Binary files a/character/unused/Purple/Gamma/walk_2.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/badge_1.png b/character/unused/Purple/Zeta/badge_1.png
deleted file mode 100644
index 3422634..0000000
Binary files a/character/unused/Purple/Zeta/badge_1.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/badge_2.png b/character/unused/Purple/Zeta/badge_2.png
deleted file mode 100644
index 90df94a..0000000
Binary files a/character/unused/Purple/Zeta/badge_2.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/climb_1.png b/character/unused/Purple/Zeta/climb_1.png
deleted file mode 100644
index b481a34..0000000
Binary files a/character/unused/Purple/Zeta/climb_1.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/climb_2.png b/character/unused/Purple/Zeta/climb_2.png
deleted file mode 100644
index 95c9b65..0000000
Binary files a/character/unused/Purple/Zeta/climb_2.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/duck.png b/character/unused/Purple/Zeta/duck.png
deleted file mode 100644
index 5285fcf..0000000
Binary files a/character/unused/Purple/Zeta/duck.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/hurt.png b/character/unused/Purple/Zeta/hurt.png
deleted file mode 100644
index ad2bbbd..0000000
Binary files a/character/unused/Purple/Zeta/hurt.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/idle.png b/character/unused/Purple/Zeta/idle.png
deleted file mode 100644
index fe38ed8..0000000
Binary files a/character/unused/Purple/Zeta/idle.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/jump.png b/character/unused/Purple/Zeta/jump.png
deleted file mode 100644
index 69245b8..0000000
Binary files a/character/unused/Purple/Zeta/jump.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/stand.png b/character/unused/Purple/Zeta/stand.png
deleted file mode 100644
index c518197..0000000
Binary files a/character/unused/Purple/Zeta/stand.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/swim_1.png b/character/unused/Purple/Zeta/swim_1.png
deleted file mode 100644
index cfdacc5..0000000
Binary files a/character/unused/Purple/Zeta/swim_1.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/swim_2.png b/character/unused/Purple/Zeta/swim_2.png
deleted file mode 100644
index ef8e309..0000000
Binary files a/character/unused/Purple/Zeta/swim_2.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/walk_1.png b/character/unused/Purple/Zeta/walk_1.png
deleted file mode 100644
index 081fb07..0000000
Binary files a/character/unused/Purple/Zeta/walk_1.png and /dev/null differ
diff --git a/character/unused/Purple/Zeta/walk_2.png b/character/unused/Purple/Zeta/walk_2.png
deleted file mode 100644
index efbfda2..0000000
Binary files a/character/unused/Purple/Zeta/walk_2.png and /dev/null differ
diff --git a/character/unused/Purple/purple_sheet.png b/character/unused/Purple/purple_sheet.png
deleted file mode 100644
index 49871de..0000000
Binary files a/character/unused/Purple/purple_sheet.png and /dev/null differ
diff --git a/character/unused/Purple/purple_vector.svg b/character/unused/Purple/purple_vector.svg
deleted file mode 100644
index 3e5f2b0..0000000
--- a/character/unused/Purple/purple_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/unused/Red/Alpha/badge_1.png b/character/unused/Red/Alpha/badge_1.png
deleted file mode 100644
index 5cfaea8..0000000
Binary files a/character/unused/Red/Alpha/badge_1.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/badge_2.png b/character/unused/Red/Alpha/badge_2.png
deleted file mode 100644
index 34cb2d0..0000000
Binary files a/character/unused/Red/Alpha/badge_2.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/climb_1.png b/character/unused/Red/Alpha/climb_1.png
deleted file mode 100644
index f92aa14..0000000
Binary files a/character/unused/Red/Alpha/climb_1.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/climb_2.png b/character/unused/Red/Alpha/climb_2.png
deleted file mode 100644
index ccfc9f2..0000000
Binary files a/character/unused/Red/Alpha/climb_2.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/duck.png b/character/unused/Red/Alpha/duck.png
deleted file mode 100644
index a5c1651..0000000
Binary files a/character/unused/Red/Alpha/duck.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/hurt.png b/character/unused/Red/Alpha/hurt.png
deleted file mode 100644
index 4f0f2d9..0000000
Binary files a/character/unused/Red/Alpha/hurt.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/idle.png b/character/unused/Red/Alpha/idle.png
deleted file mode 100644
index cf75799..0000000
Binary files a/character/unused/Red/Alpha/idle.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/jump.png b/character/unused/Red/Alpha/jump.png
deleted file mode 100644
index 4ea21e7..0000000
Binary files a/character/unused/Red/Alpha/jump.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/stand.png b/character/unused/Red/Alpha/stand.png
deleted file mode 100644
index e4d40db..0000000
Binary files a/character/unused/Red/Alpha/stand.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/swim_1.png b/character/unused/Red/Alpha/swim_1.png
deleted file mode 100644
index 67d4304..0000000
Binary files a/character/unused/Red/Alpha/swim_1.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/swim_2.png b/character/unused/Red/Alpha/swim_2.png
deleted file mode 100644
index 421ff36..0000000
Binary files a/character/unused/Red/Alpha/swim_2.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/walk_1.png b/character/unused/Red/Alpha/walk_1.png
deleted file mode 100644
index 79a5e48..0000000
Binary files a/character/unused/Red/Alpha/walk_1.png and /dev/null differ
diff --git a/character/unused/Red/Alpha/walk_2.png b/character/unused/Red/Alpha/walk_2.png
deleted file mode 100644
index 964277c..0000000
Binary files a/character/unused/Red/Alpha/walk_2.png and /dev/null differ
diff --git a/character/unused/Red/Beta/badge_1.png b/character/unused/Red/Beta/badge_1.png
deleted file mode 100644
index 27cb252..0000000
Binary files a/character/unused/Red/Beta/badge_1.png and /dev/null differ
diff --git a/character/unused/Red/Beta/badge_2.png b/character/unused/Red/Beta/badge_2.png
deleted file mode 100644
index 9587cdb..0000000
Binary files a/character/unused/Red/Beta/badge_2.png and /dev/null differ
diff --git a/character/unused/Red/Beta/climb_1.png b/character/unused/Red/Beta/climb_1.png
deleted file mode 100644
index 2d00593..0000000
Binary files a/character/unused/Red/Beta/climb_1.png and /dev/null differ
diff --git a/character/unused/Red/Beta/climb_2.png b/character/unused/Red/Beta/climb_2.png
deleted file mode 100644
index 39fc3d5..0000000
Binary files a/character/unused/Red/Beta/climb_2.png and /dev/null differ
diff --git a/character/unused/Red/Beta/duck.png b/character/unused/Red/Beta/duck.png
deleted file mode 100644
index 1593854..0000000
Binary files a/character/unused/Red/Beta/duck.png and /dev/null differ
diff --git a/character/unused/Red/Beta/hurt.png b/character/unused/Red/Beta/hurt.png
deleted file mode 100644
index 3d989ff..0000000
Binary files a/character/unused/Red/Beta/hurt.png and /dev/null differ
diff --git a/character/unused/Red/Beta/idle.png b/character/unused/Red/Beta/idle.png
deleted file mode 100644
index e885323..0000000
Binary files a/character/unused/Red/Beta/idle.png and /dev/null differ
diff --git a/character/unused/Red/Beta/jump.png b/character/unused/Red/Beta/jump.png
deleted file mode 100644
index 3befd93..0000000
Binary files a/character/unused/Red/Beta/jump.png and /dev/null differ
diff --git a/character/unused/Red/Beta/stand.png b/character/unused/Red/Beta/stand.png
deleted file mode 100644
index 17b6a7a..0000000
Binary files a/character/unused/Red/Beta/stand.png and /dev/null differ
diff --git a/character/unused/Red/Beta/swim_1.png b/character/unused/Red/Beta/swim_1.png
deleted file mode 100644
index a7368bc..0000000
Binary files a/character/unused/Red/Beta/swim_1.png and /dev/null differ
diff --git a/character/unused/Red/Beta/swim_2.png b/character/unused/Red/Beta/swim_2.png
deleted file mode 100644
index 0e6d5a2..0000000
Binary files a/character/unused/Red/Beta/swim_2.png and /dev/null differ
diff --git a/character/unused/Red/Beta/walk_1.png b/character/unused/Red/Beta/walk_1.png
deleted file mode 100644
index 2bf861d..0000000
Binary files a/character/unused/Red/Beta/walk_1.png and /dev/null differ
diff --git a/character/unused/Red/Beta/walk_2.png b/character/unused/Red/Beta/walk_2.png
deleted file mode 100644
index 7ce0c23..0000000
Binary files a/character/unused/Red/Beta/walk_2.png and /dev/null differ
diff --git a/character/unused/Red/Delta/badge_1.png b/character/unused/Red/Delta/badge_1.png
deleted file mode 100644
index 8e94757..0000000
Binary files a/character/unused/Red/Delta/badge_1.png and /dev/null differ
diff --git a/character/unused/Red/Delta/badge_2.png b/character/unused/Red/Delta/badge_2.png
deleted file mode 100644
index 28def12..0000000
Binary files a/character/unused/Red/Delta/badge_2.png and /dev/null differ
diff --git a/character/unused/Red/Delta/climb_1.png b/character/unused/Red/Delta/climb_1.png
deleted file mode 100644
index dc3e668..0000000
Binary files a/character/unused/Red/Delta/climb_1.png and /dev/null differ
diff --git a/character/unused/Red/Delta/climb_2.png b/character/unused/Red/Delta/climb_2.png
deleted file mode 100644
index 7b5376f..0000000
Binary files a/character/unused/Red/Delta/climb_2.png and /dev/null differ
diff --git a/character/unused/Red/Delta/duck.png b/character/unused/Red/Delta/duck.png
deleted file mode 100644
index 5641b5d..0000000
Binary files a/character/unused/Red/Delta/duck.png and /dev/null differ
diff --git a/character/unused/Red/Delta/hurt.png b/character/unused/Red/Delta/hurt.png
deleted file mode 100644
index 365a8cf..0000000
Binary files a/character/unused/Red/Delta/hurt.png and /dev/null differ
diff --git a/character/unused/Red/Delta/idle.png b/character/unused/Red/Delta/idle.png
deleted file mode 100644
index b39a409..0000000
Binary files a/character/unused/Red/Delta/idle.png and /dev/null differ
diff --git a/character/unused/Red/Delta/jump.png b/character/unused/Red/Delta/jump.png
deleted file mode 100644
index 1651646..0000000
Binary files a/character/unused/Red/Delta/jump.png and /dev/null differ
diff --git a/character/unused/Red/Delta/stand.png b/character/unused/Red/Delta/stand.png
deleted file mode 100644
index 3052847..0000000
Binary files a/character/unused/Red/Delta/stand.png and /dev/null differ
diff --git a/character/unused/Red/Delta/swim_1.png b/character/unused/Red/Delta/swim_1.png
deleted file mode 100644
index a96a9ca..0000000
Binary files a/character/unused/Red/Delta/swim_1.png and /dev/null differ
diff --git a/character/unused/Red/Delta/swim_2.png b/character/unused/Red/Delta/swim_2.png
deleted file mode 100644
index c275aa1..0000000
Binary files a/character/unused/Red/Delta/swim_2.png and /dev/null differ
diff --git a/character/unused/Red/Delta/walk_1.png b/character/unused/Red/Delta/walk_1.png
deleted file mode 100644
index 3c64b79..0000000
Binary files a/character/unused/Red/Delta/walk_1.png and /dev/null differ
diff --git a/character/unused/Red/Delta/walk_2.png b/character/unused/Red/Delta/walk_2.png
deleted file mode 100644
index 4d839f3..0000000
Binary files a/character/unused/Red/Delta/walk_2.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/badge_1.png b/character/unused/Red/Gamma/badge_1.png
deleted file mode 100644
index 0dcfc80..0000000
Binary files a/character/unused/Red/Gamma/badge_1.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/badge_2.png b/character/unused/Red/Gamma/badge_2.png
deleted file mode 100644
index 258cb9b..0000000
Binary files a/character/unused/Red/Gamma/badge_2.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/climb_1.png b/character/unused/Red/Gamma/climb_1.png
deleted file mode 100644
index b9d00e4..0000000
Binary files a/character/unused/Red/Gamma/climb_1.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/climb_2.png b/character/unused/Red/Gamma/climb_2.png
deleted file mode 100644
index 79128af..0000000
Binary files a/character/unused/Red/Gamma/climb_2.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/duck.png b/character/unused/Red/Gamma/duck.png
deleted file mode 100644
index bf62354..0000000
Binary files a/character/unused/Red/Gamma/duck.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/hurt.png b/character/unused/Red/Gamma/hurt.png
deleted file mode 100644
index 60e4127..0000000
Binary files a/character/unused/Red/Gamma/hurt.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/idle.png b/character/unused/Red/Gamma/idle.png
deleted file mode 100644
index 3911d10..0000000
Binary files a/character/unused/Red/Gamma/idle.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/jump.png b/character/unused/Red/Gamma/jump.png
deleted file mode 100644
index 9baad21..0000000
Binary files a/character/unused/Red/Gamma/jump.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/stand.png b/character/unused/Red/Gamma/stand.png
deleted file mode 100644
index 0142686..0000000
Binary files a/character/unused/Red/Gamma/stand.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/swim_1.png b/character/unused/Red/Gamma/swim_1.png
deleted file mode 100644
index 03fa96b..0000000
Binary files a/character/unused/Red/Gamma/swim_1.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/swim_2.png b/character/unused/Red/Gamma/swim_2.png
deleted file mode 100644
index 1bb1fa9..0000000
Binary files a/character/unused/Red/Gamma/swim_2.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/walk_1.png b/character/unused/Red/Gamma/walk_1.png
deleted file mode 100644
index fe0d644..0000000
Binary files a/character/unused/Red/Gamma/walk_1.png and /dev/null differ
diff --git a/character/unused/Red/Gamma/walk_2.png b/character/unused/Red/Gamma/walk_2.png
deleted file mode 100644
index 6563417..0000000
Binary files a/character/unused/Red/Gamma/walk_2.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/badge_1.png b/character/unused/Red/Zeta/badge_1.png
deleted file mode 100644
index a02fbc1..0000000
Binary files a/character/unused/Red/Zeta/badge_1.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/badge_2.png b/character/unused/Red/Zeta/badge_2.png
deleted file mode 100644
index c562cc9..0000000
Binary files a/character/unused/Red/Zeta/badge_2.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/climb_1.png b/character/unused/Red/Zeta/climb_1.png
deleted file mode 100644
index f4cda7c..0000000
Binary files a/character/unused/Red/Zeta/climb_1.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/climb_2.png b/character/unused/Red/Zeta/climb_2.png
deleted file mode 100644
index 3937926..0000000
Binary files a/character/unused/Red/Zeta/climb_2.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/duck.png b/character/unused/Red/Zeta/duck.png
deleted file mode 100644
index 8efc97d..0000000
Binary files a/character/unused/Red/Zeta/duck.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/hurt.png b/character/unused/Red/Zeta/hurt.png
deleted file mode 100644
index 00436ae..0000000
Binary files a/character/unused/Red/Zeta/hurt.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/idle.png b/character/unused/Red/Zeta/idle.png
deleted file mode 100644
index cc6e2b3..0000000
Binary files a/character/unused/Red/Zeta/idle.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/jump.png b/character/unused/Red/Zeta/jump.png
deleted file mode 100644
index d3b918c..0000000
Binary files a/character/unused/Red/Zeta/jump.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/stand.png b/character/unused/Red/Zeta/stand.png
deleted file mode 100644
index 1599884..0000000
Binary files a/character/unused/Red/Zeta/stand.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/swim_1.png b/character/unused/Red/Zeta/swim_1.png
deleted file mode 100644
index c49a67b..0000000
Binary files a/character/unused/Red/Zeta/swim_1.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/swim_2.png b/character/unused/Red/Zeta/swim_2.png
deleted file mode 100644
index b39d405..0000000
Binary files a/character/unused/Red/Zeta/swim_2.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/walk_1.png b/character/unused/Red/Zeta/walk_1.png
deleted file mode 100644
index 3d76f8d..0000000
Binary files a/character/unused/Red/Zeta/walk_1.png and /dev/null differ
diff --git a/character/unused/Red/Zeta/walk_2.png b/character/unused/Red/Zeta/walk_2.png
deleted file mode 100644
index 4e1b563..0000000
Binary files a/character/unused/Red/Zeta/walk_2.png and /dev/null differ
diff --git a/character/unused/Red/red_sheet.png b/character/unused/Red/red_sheet.png
deleted file mode 100644
index 08207a1..0000000
Binary files a/character/unused/Red/red_sheet.png and /dev/null differ
diff --git a/character/unused/Red/red_vector.svg b/character/unused/Red/red_vector.svg
deleted file mode 100644
index dc0d966..0000000
--- a/character/unused/Red/red_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/unused/Yellow/Alpha/badge_1.png b/character/unused/Yellow/Alpha/badge_1.png
deleted file mode 100644
index e3f3672..0000000
Binary files a/character/unused/Yellow/Alpha/badge_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/badge_2.png b/character/unused/Yellow/Alpha/badge_2.png
deleted file mode 100644
index 68383ca..0000000
Binary files a/character/unused/Yellow/Alpha/badge_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/climb_1.png b/character/unused/Yellow/Alpha/climb_1.png
deleted file mode 100644
index 64962ca..0000000
Binary files a/character/unused/Yellow/Alpha/climb_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/climb_2.png b/character/unused/Yellow/Alpha/climb_2.png
deleted file mode 100644
index b37abf2..0000000
Binary files a/character/unused/Yellow/Alpha/climb_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/duck.png b/character/unused/Yellow/Alpha/duck.png
deleted file mode 100644
index a2f76dc..0000000
Binary files a/character/unused/Yellow/Alpha/duck.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/hurt.png b/character/unused/Yellow/Alpha/hurt.png
deleted file mode 100644
index b67d03b..0000000
Binary files a/character/unused/Yellow/Alpha/hurt.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/idle.png b/character/unused/Yellow/Alpha/idle.png
deleted file mode 100644
index 56e423b..0000000
Binary files a/character/unused/Yellow/Alpha/idle.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/jump.png b/character/unused/Yellow/Alpha/jump.png
deleted file mode 100644
index aeecbc6..0000000
Binary files a/character/unused/Yellow/Alpha/jump.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/stand.png b/character/unused/Yellow/Alpha/stand.png
deleted file mode 100644
index 2590b3d..0000000
Binary files a/character/unused/Yellow/Alpha/stand.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/swim_1.png b/character/unused/Yellow/Alpha/swim_1.png
deleted file mode 100644
index 4624b18..0000000
Binary files a/character/unused/Yellow/Alpha/swim_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/swim_2.png b/character/unused/Yellow/Alpha/swim_2.png
deleted file mode 100644
index 2a55133..0000000
Binary files a/character/unused/Yellow/Alpha/swim_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/walk_1.png b/character/unused/Yellow/Alpha/walk_1.png
deleted file mode 100644
index 1188b2e..0000000
Binary files a/character/unused/Yellow/Alpha/walk_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Alpha/walk_2.png b/character/unused/Yellow/Alpha/walk_2.png
deleted file mode 100644
index 91f13a1..0000000
Binary files a/character/unused/Yellow/Alpha/walk_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/badge_1.png b/character/unused/Yellow/Beta/badge_1.png
deleted file mode 100644
index 753190e..0000000
Binary files a/character/unused/Yellow/Beta/badge_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/badge_2.png b/character/unused/Yellow/Beta/badge_2.png
deleted file mode 100644
index 8c9db0b..0000000
Binary files a/character/unused/Yellow/Beta/badge_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/climb_1.png b/character/unused/Yellow/Beta/climb_1.png
deleted file mode 100644
index 58291c3..0000000
Binary files a/character/unused/Yellow/Beta/climb_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/climb_2.png b/character/unused/Yellow/Beta/climb_2.png
deleted file mode 100644
index 7d9a6f1..0000000
Binary files a/character/unused/Yellow/Beta/climb_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/duck.png b/character/unused/Yellow/Beta/duck.png
deleted file mode 100644
index f3e6570..0000000
Binary files a/character/unused/Yellow/Beta/duck.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/hurt.png b/character/unused/Yellow/Beta/hurt.png
deleted file mode 100644
index ced9e59..0000000
Binary files a/character/unused/Yellow/Beta/hurt.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/idle.png b/character/unused/Yellow/Beta/idle.png
deleted file mode 100644
index 5de3e9b..0000000
Binary files a/character/unused/Yellow/Beta/idle.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/jump.png b/character/unused/Yellow/Beta/jump.png
deleted file mode 100644
index e2b50af..0000000
Binary files a/character/unused/Yellow/Beta/jump.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/stand.png b/character/unused/Yellow/Beta/stand.png
deleted file mode 100644
index 3ae44d7..0000000
Binary files a/character/unused/Yellow/Beta/stand.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/swim_1.png b/character/unused/Yellow/Beta/swim_1.png
deleted file mode 100644
index 07090fe..0000000
Binary files a/character/unused/Yellow/Beta/swim_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/swim_2.png b/character/unused/Yellow/Beta/swim_2.png
deleted file mode 100644
index 9eb9d46..0000000
Binary files a/character/unused/Yellow/Beta/swim_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/walk_1.png b/character/unused/Yellow/Beta/walk_1.png
deleted file mode 100644
index 77302a5..0000000
Binary files a/character/unused/Yellow/Beta/walk_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Beta/walk_2.png b/character/unused/Yellow/Beta/walk_2.png
deleted file mode 100644
index 0365f32..0000000
Binary files a/character/unused/Yellow/Beta/walk_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/badge_1.png b/character/unused/Yellow/Delta/badge_1.png
deleted file mode 100644
index 7938916..0000000
Binary files a/character/unused/Yellow/Delta/badge_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/badge_2.png b/character/unused/Yellow/Delta/badge_2.png
deleted file mode 100644
index 422df2c..0000000
Binary files a/character/unused/Yellow/Delta/badge_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/climb_1.png b/character/unused/Yellow/Delta/climb_1.png
deleted file mode 100644
index 3255abd..0000000
Binary files a/character/unused/Yellow/Delta/climb_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/climb_2.png b/character/unused/Yellow/Delta/climb_2.png
deleted file mode 100644
index 5e6bce4..0000000
Binary files a/character/unused/Yellow/Delta/climb_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/duck.png b/character/unused/Yellow/Delta/duck.png
deleted file mode 100644
index 030fb7c..0000000
Binary files a/character/unused/Yellow/Delta/duck.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/hurt.png b/character/unused/Yellow/Delta/hurt.png
deleted file mode 100644
index 0ea2f69..0000000
Binary files a/character/unused/Yellow/Delta/hurt.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/idle.png b/character/unused/Yellow/Delta/idle.png
deleted file mode 100644
index b83f47d..0000000
Binary files a/character/unused/Yellow/Delta/idle.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/jump.png b/character/unused/Yellow/Delta/jump.png
deleted file mode 100644
index 8860d58..0000000
Binary files a/character/unused/Yellow/Delta/jump.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/stand.png b/character/unused/Yellow/Delta/stand.png
deleted file mode 100644
index 12d0734..0000000
Binary files a/character/unused/Yellow/Delta/stand.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/swim_1.png b/character/unused/Yellow/Delta/swim_1.png
deleted file mode 100644
index 4120ea0..0000000
Binary files a/character/unused/Yellow/Delta/swim_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/swim_2.png b/character/unused/Yellow/Delta/swim_2.png
deleted file mode 100644
index a0374ea..0000000
Binary files a/character/unused/Yellow/Delta/swim_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/walk_1.png b/character/unused/Yellow/Delta/walk_1.png
deleted file mode 100644
index 5925e29..0000000
Binary files a/character/unused/Yellow/Delta/walk_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Delta/walk_2.png b/character/unused/Yellow/Delta/walk_2.png
deleted file mode 100644
index 3baef0a..0000000
Binary files a/character/unused/Yellow/Delta/walk_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/badge_1.png b/character/unused/Yellow/Gamma/badge_1.png
deleted file mode 100644
index 40e3f64..0000000
Binary files a/character/unused/Yellow/Gamma/badge_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/badge_2.png b/character/unused/Yellow/Gamma/badge_2.png
deleted file mode 100644
index 1703acd..0000000
Binary files a/character/unused/Yellow/Gamma/badge_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/climb_1.png b/character/unused/Yellow/Gamma/climb_1.png
deleted file mode 100644
index 0580668..0000000
Binary files a/character/unused/Yellow/Gamma/climb_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/climb_2.png b/character/unused/Yellow/Gamma/climb_2.png
deleted file mode 100644
index 3c8bdbb..0000000
Binary files a/character/unused/Yellow/Gamma/climb_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/duck.png b/character/unused/Yellow/Gamma/duck.png
deleted file mode 100644
index 21da1de..0000000
Binary files a/character/unused/Yellow/Gamma/duck.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/hurt.png b/character/unused/Yellow/Gamma/hurt.png
deleted file mode 100644
index b34e93d..0000000
Binary files a/character/unused/Yellow/Gamma/hurt.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/idle.png b/character/unused/Yellow/Gamma/idle.png
deleted file mode 100644
index ed981c0..0000000
Binary files a/character/unused/Yellow/Gamma/idle.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/jump.png b/character/unused/Yellow/Gamma/jump.png
deleted file mode 100644
index 4767ca5..0000000
Binary files a/character/unused/Yellow/Gamma/jump.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/stand.png b/character/unused/Yellow/Gamma/stand.png
deleted file mode 100644
index cb9441c..0000000
Binary files a/character/unused/Yellow/Gamma/stand.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/swim_1.png b/character/unused/Yellow/Gamma/swim_1.png
deleted file mode 100644
index b4394b8..0000000
Binary files a/character/unused/Yellow/Gamma/swim_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/swim_2.png b/character/unused/Yellow/Gamma/swim_2.png
deleted file mode 100644
index f1723f9..0000000
Binary files a/character/unused/Yellow/Gamma/swim_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/walk_1.png b/character/unused/Yellow/Gamma/walk_1.png
deleted file mode 100644
index 5199211..0000000
Binary files a/character/unused/Yellow/Gamma/walk_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Gamma/walk_2.png b/character/unused/Yellow/Gamma/walk_2.png
deleted file mode 100644
index ba2cfe1..0000000
Binary files a/character/unused/Yellow/Gamma/walk_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/badge_1.png b/character/unused/Yellow/Zeta/badge_1.png
deleted file mode 100644
index 52a2211..0000000
Binary files a/character/unused/Yellow/Zeta/badge_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/badge_2.png b/character/unused/Yellow/Zeta/badge_2.png
deleted file mode 100644
index 65e9a47..0000000
Binary files a/character/unused/Yellow/Zeta/badge_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/climb_1.png b/character/unused/Yellow/Zeta/climb_1.png
deleted file mode 100644
index b8264b3..0000000
Binary files a/character/unused/Yellow/Zeta/climb_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/climb_2.png b/character/unused/Yellow/Zeta/climb_2.png
deleted file mode 100644
index 7078592..0000000
Binary files a/character/unused/Yellow/Zeta/climb_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/duck.png b/character/unused/Yellow/Zeta/duck.png
deleted file mode 100644
index bb6703a..0000000
Binary files a/character/unused/Yellow/Zeta/duck.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/hurt.png b/character/unused/Yellow/Zeta/hurt.png
deleted file mode 100644
index 78666e1..0000000
Binary files a/character/unused/Yellow/Zeta/hurt.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/idle.png b/character/unused/Yellow/Zeta/idle.png
deleted file mode 100644
index e59e2db..0000000
Binary files a/character/unused/Yellow/Zeta/idle.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/jump.png b/character/unused/Yellow/Zeta/jump.png
deleted file mode 100644
index 747b1a4..0000000
Binary files a/character/unused/Yellow/Zeta/jump.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/stand.png b/character/unused/Yellow/Zeta/stand.png
deleted file mode 100644
index c8f7ba1..0000000
Binary files a/character/unused/Yellow/Zeta/stand.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/swim_1.png b/character/unused/Yellow/Zeta/swim_1.png
deleted file mode 100644
index ed8421c..0000000
Binary files a/character/unused/Yellow/Zeta/swim_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/swim_2.png b/character/unused/Yellow/Zeta/swim_2.png
deleted file mode 100644
index 0e5b541..0000000
Binary files a/character/unused/Yellow/Zeta/swim_2.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/walk_1.png b/character/unused/Yellow/Zeta/walk_1.png
deleted file mode 100644
index d522d4b..0000000
Binary files a/character/unused/Yellow/Zeta/walk_1.png and /dev/null differ
diff --git a/character/unused/Yellow/Zeta/walk_2.png b/character/unused/Yellow/Zeta/walk_2.png
deleted file mode 100644
index c57ec11..0000000
Binary files a/character/unused/Yellow/Zeta/walk_2.png and /dev/null differ
diff --git a/character/unused/Yellow/yellow_sheet.png b/character/unused/Yellow/yellow_sheet.png
deleted file mode 100644
index 9112675..0000000
Binary files a/character/unused/Yellow/yellow_sheet.png and /dev/null differ
diff --git a/character/unused/Yellow/yellow_vector.svg b/character/unused/Yellow/yellow_vector.svg
deleted file mode 100644
index 6789cab..0000000
--- a/character/unused/Yellow/yellow_vector.svg
+++ /dev/null
@@ -1,2350 +0,0 @@
-
-
diff --git a/character/unused/front.bmp b/character/unused/front.bmp
deleted file mode 100644
index c26e184..0000000
Binary files a/character/unused/front.bmp and /dev/null differ
diff --git a/character/unused/jump_left.bmp b/character/unused/jump_left.bmp
deleted file mode 100644
index 20a0366..0000000
Binary files a/character/unused/jump_left.bmp and /dev/null differ
diff --git a/character/unused/jump_right.bmp b/character/unused/jump_right.bmp
deleted file mode 100644
index 59c4378..0000000
Binary files a/character/unused/jump_right.bmp and /dev/null differ
diff --git a/character/unused/license.txt b/character/unused/license.txt
deleted file mode 100644
index 8b342ff..0000000
--- a/character/unused/license.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-
-###############################################################################
-
- Platformer Art (Xeno Diversity) by Arsonide
-
- ------------------------------
-
- License (CC0)
- http://creativecommons.org/publicdomain/zero/1.0/
-
- You may use these graphics in personal and commercial projects.
- Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
- Credit Arsonide would also be nice but is not mandatory.
-
-###############################################################################
\ No newline at end of file
diff --git a/character/unused/master_sheet.png b/character/unused/master_sheet.png
deleted file mode 100644
index a7d25c5..0000000
Binary files a/character/unused/master_sheet.png and /dev/null differ
diff --git a/character/unused/p1_spritesheet.png b/character/unused/p1_spritesheet.png
deleted file mode 100644
index 6dc17f2..0000000
Binary files a/character/unused/p1_spritesheet.png and /dev/null differ
diff --git a/character/unused/p1_spritesheet.txt b/character/unused/p1_spritesheet.txt
deleted file mode 100644
index 73387e3..0000000
--- a/character/unused/p1_spritesheet.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-p1_duck = 365 98 69 71
-p1_front = 0 196 66 92
-p1_hurt = 438 0 69 92
-p1_jump = 438 93 67 94
-p1_stand = 67 196 66 92
-p1_walk01 = 0 0 72 97
-p1_walk02 = 73 0 72 97
-p1_walk03 = 146 0 72 97
-p1_walk04 = 0 98 72 97
-p1_walk05 = 73 98 72 97
-p1_walk06 = 146 98 72 97
-p1_walk07 = 219 0 72 97
-p1_walk08 = 292 0 72 97
-p1_walk09 = 219 98 72 97
-p1_walk10 = 365 0 72 97
-p1_walk11 = 292 98 72 97
diff --git a/character/unused/p2_spritesheet.png b/character/unused/p2_spritesheet.png
deleted file mode 100644
index d2dfa8b..0000000
Binary files a/character/unused/p2_spritesheet.png and /dev/null differ
diff --git a/character/unused/p2_spritesheet.txt b/character/unused/p2_spritesheet.txt
deleted file mode 100644
index 1649947..0000000
--- a/character/unused/p2_spritesheet.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-p2_duck = 355 95 67 72
-p2_front = 0 190 66 92
-p2_hurt = 426 0 67 92
-p2_jump = 423 95 66 94
-p2_stand = 67 190 66 92
-p2_walk01 = 0 0 70 94
-p2_walk02 = 71 0 70 94
-p2_walk03 = 142 0 70 94
-p2_walk04 = 0 95 70 94
-p2_walk05 = 71 95 70 94
-p2_walk06 = 142 95 70 94
-p2_walk07 = 213 0 70 94
-p2_walk08 = 284 0 70 94
-p2_walk09 = 213 95 70 94
-p2_walk10 = 355 0 70 94
-p2_walk11 = 284 95 70 94
diff --git a/character/unused/p3_spritesheet.png b/character/unused/p3_spritesheet.png
deleted file mode 100644
index 9e09eeb..0000000
Binary files a/character/unused/p3_spritesheet.png and /dev/null differ
diff --git a/character/unused/p3_spritesheet.txt b/character/unused/p3_spritesheet.txt
deleted file mode 100644
index 3be97ff..0000000
--- a/character/unused/p3_spritesheet.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-p3_duck = 365 98 69 71
-p3_front = 0 196 66 92
-p3_hurt = 438 0 69 92
-p3_jump = 438 93 67 94
-p3_stand = 67 196 66 92
-p3_walk01 = 0 0 72 97
-p3_walk02 = 73 0 72 97
-p3_walk03 = 146 0 72 97
-p3_walk04 = 0 98 72 97
-p3_walk05 = 73 98 72 97
-p3_walk06 = 146 98 72 97
-p3_walk07 = 219 0 72 97
-p3_walk08 = 292 0 72 97
-p3_walk09 = 219 98 72 97
-p3_walk10 = 365 0 72 97
-p3_walk11 = 292 98 72 97
diff --git a/character/unused/preview.png b/character/unused/preview.png
deleted file mode 100644
index 71a2849..0000000
Binary files a/character/unused/preview.png and /dev/null differ
diff --git a/character/unused/sample.png b/character/unused/sample.png
deleted file mode 100644
index 808c9ce..0000000
Binary files a/character/unused/sample.png and /dev/null differ
diff --git a/character/unused/walk0001.bmp b/character/unused/walk0001.bmp
deleted file mode 100644
index b447f77..0000000
Binary files a/character/unused/walk0001.bmp and /dev/null differ
diff --git a/character/unused/walk0002.bmp b/character/unused/walk0002.bmp
deleted file mode 100644
index b5570a5..0000000
Binary files a/character/unused/walk0002.bmp and /dev/null differ
diff --git a/character/unused/walk0003.bmp b/character/unused/walk0003.bmp
deleted file mode 100644
index cf490dc..0000000
Binary files a/character/unused/walk0003.bmp and /dev/null differ
diff --git a/character/unused/walk0004.bmp b/character/unused/walk0004.bmp
deleted file mode 100644
index e5b1f92..0000000
Binary files a/character/unused/walk0004.bmp and /dev/null differ
diff --git a/character/unused/walk0005.bmp b/character/unused/walk0005.bmp
deleted file mode 100644
index 2db12f1..0000000
Binary files a/character/unused/walk0005.bmp and /dev/null differ
diff --git a/character/unused/walk0006.bmp b/character/unused/walk0006.bmp
deleted file mode 100644
index 6dc49b4..0000000
Binary files a/character/unused/walk0006.bmp and /dev/null differ
diff --git a/character/unused/walk0007.bmp b/character/unused/walk0007.bmp
deleted file mode 100644
index e45fa57..0000000
Binary files a/character/unused/walk0007.bmp and /dev/null differ
diff --git a/character/unused/walk0008.bmp b/character/unused/walk0008.bmp
deleted file mode 100644
index 041f7e1..0000000
Binary files a/character/unused/walk0008.bmp and /dev/null differ
diff --git a/character/unused/walk0009.bmp b/character/unused/walk0009.bmp
deleted file mode 100644
index 759744c..0000000
Binary files a/character/unused/walk0009.bmp and /dev/null differ
diff --git a/character/unused/walk0010.bmp b/character/unused/walk0010.bmp
deleted file mode 100644
index bc25026..0000000
Binary files a/character/unused/walk0010.bmp and /dev/null differ
diff --git a/character/unused/walk0011.bmp b/character/unused/walk0011.bmp
deleted file mode 100644
index b447f77..0000000
Binary files a/character/unused/walk0011.bmp and /dev/null differ
diff --git a/data/__init__.py b/data/__init__.py
deleted file mode 100644
index 5812bfa..0000000
--- a/data/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__author__ = 'Kenneth_2'
diff --git a/data/aicharacter.py b/data/aicharacter.py
deleted file mode 100644
index 04dc6f7..0000000
--- a/data/aicharacter.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# coding=utf-8
-from random import randint
-import pygame, math
-from character import *
-
-class AICharacter(Character):
-
- def __init__(self, x, y, Vx, Vy, properties=('slime', -1, -1)):
- # Properties should be a tuple of the form (STRING mobName, INT leftLimit,
- # INT rightLimit) where leftLimit and rightLimit can be -1 to remove the limit
- self.mobType = properties[0]
- self.limit = [properties[1], properties[2]]
-
- # Call base class implementation
- Character.__init__(self, x, y, Vx, Vy)
-
- # Decide colour if slime
- self.colour = 'Blue'
- if self.mobType == 'slime' and randint(0, 1) == 0:
- self.colour = 'Green'
-
- # Load images
- # slime
- self.slimeDL = pygame.image.load('enemies'+os.sep+'slime'+os.sep+'slime' + self.colour +'_squashed.png').convert_alpha()
- self.slimeDR = pygame.image.load('enemies'+os.sep+'slime'+os.sep+'slime' + self.colour + '_squashedR.png').convert_alpha()
- self.slimeL = pygame.image.load('enemies'+os.sep+'slime'+os.sep+'slime' + self.colour + '_walk.png').convert_alpha()
- self.slimeR = pygame.image.load('enemies'+os.sep+'slime'+os.sep+'slime' + self.colour + '_walkR.png').convert_alpha()
- # fly
- self.flyDL = pygame.image.load('enemies'+os.sep+'fly'+os.sep+'fly_dead.png').convert_alpha()
- self.flyDR = pygame.image.load('enemies'+os.sep+'fly'+os.sep+'fly_dead_r.png').convert_alpha()
- self.flyL = pygame.image.load('enemies'+os.sep+'fly'+os.sep+'fly_fly.png').convert_alpha()
- self.flyR = pygame.image.load('enemies'+os.sep+'fly'+os.sep+'fly_fly_r.png').convert_alpha()
- # fish
- self.fishDL = pygame.image.load('enemies'+os.sep+'other'+os.sep+'fishGreen_dead.png').convert_alpha()
- self.fishDR = pygame.image.load('enemies'+os.sep+'other'+os.sep+'fishGreen_dead_r.png').convert_alpha()
- self.fishL = pygame.image.load('enemies'+os.sep+'other'+os.sep+'fishGreen_swim.png').convert_alpha()
- self.fishR = pygame.image.load('enemies'+os.sep+'other'+os.sep+'fishGreen_swim_r.png').convert_alpha()
- # snail
- self.snailL1 = pygame.image.load('enemies'+os.sep+'other'+os.sep+'snailWalk1.png').convert_alpha()
- self.snailL2 = pygame.image.load('enemies'+os.sep+'other'+os.sep+'snailWalk2.png').convert_alpha()
- self.snailR1 = pygame.image.load('enemies'+os.sep+'other'+os.sep+'snailWalk1R.png').convert_alpha()
- self.snailR2 = pygame.image.load('enemies'+os.sep+'other'+os.sep+'snailWalk2R.png').convert_alpha()
- self.snailDL = pygame.image.load('enemies'+os.sep+'other'+os.sep+'snailShell.png').convert_alpha()
- self.snailDR = pygame.image.load('enemies'+os.sep+'other'+os.sep+'snailShellR.png').convert_alpha()
- # general image properties
- self.imageL1, self.imageL2, self.imageR1, self.imageR2, self.imageDL, self.imageDR = [None] * 6
- self.deadWidth, self.deadHeight = [None] * 2
-
- # Other control variables
- self.originalHeight = y
- self.alive = True
- self.health = 1
- self.gravity = 1
- self.runSpeed = abs(self.Vx)
- self.currentStep = 0
- self.takenAction = False
- self.updateFrequency = 2
-
- # -----------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def distance(p0, p1):
- return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def updateAI(self, platforms, mainChar, blocks):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Determine direction for draw() method
- if self.Vx > 0:
- self.direction = 1
- elif self.Vx < 0:
- self.direction = 0
-
- # Check if character is still alive
- if self.health <= 0:
- self.alive = False
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0].height - 5
- if not self.onGround and self.Vy >= platforms[0].height - 15 and self.y > platforms[self.lowestPlatform][1]:
- self.dispose()
-
- # Apply gravity if necessary
- if self.onGround:
- self.Vy = 0
- elif ((self.mobType == 'fly' and not self.alive) or self.mobType != 'fly') and (self.mobType != 'fish' or
- (self.mobType == 'fish' and not self.alive)):
- self.Vy += self.gravity
-
- # Keep character within bounds
- if self.limit[0] != -1 and self.x <= self.limit[0]:
- self.x += self.runSpeed
- self.Vx = abs(self.Vx)
- if self.limit[1] != -1 and self.x >= self.limit[1]:
- self.x -= self.runSpeed
- self.Vx = -abs(self.Vx)
-
- # Switch to a dead state if close to explosion
- explosionRadius = 400
- for block in blocks:
- distanceFromBlock = self.distance((self.x + 0.5 * self.width, self.y + 0.5 * self.height),
- (block.x + 0.5 * block.width, block.y + 0.5 * block.height))
- if block.disabled and block.willExplode and block.explosionStep == 1 and \
- distanceFromBlock < explosionRadius:
- self.health = 0
-
- # Prevent AI from falling off the lowest platform
- if self.mobType == 'slime' or self.mobType == 'snail':
- testXLeft = self.x - 25
- testXRight = self.x + 25 + self.width
- lowestPlatLeft = platforms[self.lowestPlatform][0]
- lowestPlatRight = platforms[self.lowestPlatform][2]
- onLowestPlatform = self.currentPlatform == self.lowestPlatform
- if onLowestPlatform and testXLeft <= lowestPlatLeft and self.Vx < 0:
- self.x += self.runSpeed
- self.Vx *= -1
- elif onLowestPlatform and testXRight >= lowestPlatRight and self.Vx > 0:
- self.x -= self.runSpeed
- self.Vx *= -1
-
- # Implement simple AI
- if self.mobType == 'slime' or self.mobType == 'snail' and randint(0, 10 - self.updateFrequency) == 0:
- platformsBelowSelf = []
- currentPlatformHeight = platforms[self.currentPlatform][1]
- limitBackup = [self.limit[0], self.limit[1]]
- self.limit[0] = platforms[self.currentPlatform][0] + 5
- self.limit[1] = platforms[self.currentPlatform][2] - 40
- safePlatformDropLeft, safePlatformDropRight = False, False
- for i in range(0, len(platforms)):
- if platforms[i][1] > currentPlatformHeight:
- platformsBelowSelf.append(platforms[i])
- for platform in platformsBelowSelf:
- if platform[0] < platforms[self.currentPlatform][0] < platform[2]:
- safePlatformDropLeft = True
- if platform[0] < platforms[self.currentPlatform][2] and platform[2] > platforms[self.currentPlatform][
- 2]:
- safePlatformDropRight = True
- if safePlatformDropLeft:
- self.limit[0] = limitBackup[0]
- if safePlatformDropRight:
- self.limit[1] = limitBackup[1]
- elif self.mobType == 'fly' and self.alive and randint(0, 10 - self.updateFrequency) == 0:
- self.limit[0] = platforms[0][0]
- for i in range(0, len(platforms)):
- if self.x + self.width + 5 >= platforms[i][0] and self.x <= platforms[i][2] and \
- platforms[i][1] <= self.y <= platforms[i][3]:
- self.limit[1] = platforms[i][0]
- self.Vx *= -1
- self.x -= self.runSpeed
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool, surface, FPS, torches=None):
- # Collide with other objects
- Character.collide(self, platforms, blocks, aiCharacters, pool, torches)
-
- # Update motion and AI actions
- self.updateAI(platforms, mainChar, blocks)
-
- # Draw correct character
- self.draw(surface, FPS)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, surface, fps=60):
- # Return immediately if mob is invisibile
- if not self.visible:
- return
-
- # Determine the correct image to use
- if self.mobType == 'slime' and not self.imageL1:
- self.imageL1 = self.imageL2 = self.slimeL
- self.imageR1 = self.imageR2 = self.slimeR
- self.imageDL = self.slimeDL
- self.imageDR = self.slimeDR
- elif self.mobType == 'fly' and not self.imageL1:
- self.imageL1 = self.imageL2 = self.flyL
- self.imageR1 = self.imageR2 = self.flyR
- self.imageDL = self.flyDL
- self.imageDR = self.flyDR
- elif self.mobType == 'fish' and not self.imageL1:
- self.imageL1 = self.fishL
- self.imageL2 = self.fishL
- self.imageR1 = self.fishR
- self.imageR2 = self.fishR
- self.imageDL = self.fishDL
- self.imageDR = self.fishDR
- elif self.mobType == 'snail' and not self.imageL1:
- self.imageL1 = self.snailL1
- self.imageL2 = self.snailL2
- self.imageR1 = self.snailR1
- self.imageR2 = self.snailR2
- self.imageDL = self.snailDL
- self.imageDR = self.snailDR
-
- # Get image widths and heights
- self.width = pygame.Surface.get_width(self.imageL1)
- self.height = pygame.Surface.get_height(self.imageL1)
- self.deadWidth = pygame.Surface.get_width(self.imageDL)
- self.deadHeight = pygame.Surface.get_height(self.imageDL)
-
- # Increment the walking/moving frame
- footstepRarity = 1
- if pygame.time.get_ticks() % footstepRarity == 0:
- self.walkFrame += 1
- if self.walkFrame > 1:
- self.walkFrame = 0
-
- if self.direction == 1 and self.alive and self.walkFrame == 0:
- surface.blit(self.imageR1, (self.x, self.y))
- elif self.direction == 0 and self.alive and self.walkFrame == 0:
- surface.blit(self.imageL1, (self.x, self.y))
- elif self.direction == 1 and self.alive and self.walkFrame == 1:
- surface.blit(self.imageR2, (self.x, self.y))
- elif self.direction == 0 and self.alive and self.walkFrame == 1:
- surface.blit(self.imageL2, (self.x, self.y))
- elif self.direction == 1 and not self.alive:
- surface.blit(self.imageDR, (self.x, self.y))
- elif self.direction == 0 and not self.alive:
- surface.blit(self.imageDL, (self.x, self.y))
-
- # Recalculate the image width and height, and stop horizontal motion if the AI char is dead
- if not self.alive:
- self.width = self.deadWidth
- self.height = self.deadHeight
- self.Vx = 0
-
- # -----------------------------------------------------------------------------------------------------------------
diff --git a/data/background.py b/data/background.py
deleted file mode 100644
index ac22a39..0000000
--- a/data/background.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# coding=utf-8
-import math, pygame
-
-class Background(object):
-
- def __init__(self, img, scrW, scrH, imgInv=None, defaultPosition=(0, 0)):
- self.image = img
- self.invertedImage = imgInv
- self.targetWidth = scrW
- self.targetHeight = scrH
- self.correctMissingInvertedImage()
-
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
-
- self.x, self.y = defaultPosition
-
- self.scaleImages(False)
- self.invertedX = self.x + self.width
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def correctMissingInvertedImage(self):
- if not self.invertedImage:
- self.invertedImage = pygame.transform.flip(self.image, 1, 0).convert()
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def scaleImages(self, precise=True):
- badImageSize = self.width < self.targetWidth or self.height < self.targetHeight
- if precise and badImageSize:
- # Uses bilinear filtering to expand images that are too small
- widthScaleFactor = int(math.ceil(self.targetWidth / self.width))
- heightScaleFactor = int(math.ceil(self.targetHeight / self.height))
- scaleFactor = max(widthScaleFactor, heightScaleFactor)
- self.image = pygame.transform.smoothscale(self.image, (self.width * scaleFactor, self.height * scaleFactor))
- self.invertedImage = pygame.transform.smoothscale(self.invertedImage, (self.width * scaleFactor,
- self.height * scaleFactor))
- elif badImageSize:
- while self.height < self.targetHeight:
- self.image = pygame.transform.scale2x(self.image)
- self.invertedImage = pygame.transform.scale2x(self.invertedImage)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def update(self, surface):
- # Swap background positions as needed
- if self.x < -self.width:
- self.x = self.width
- elif self.x > self.width:
- self.x = -self.width
- if self.invertedX < -self.width:
- self.invertedX = self.width
- elif self.invertedX > self.width:
- self.invertedX = -self.width
-
- # Verify corrent positioning of the backgrounds
- if self.x > self.invertedX:
- self.x = self.invertedX + self.width
- elif self.invertedX > self.x:
- self.invertedX = self.x + self.width
-
- # Draw the background image onto the input surface
- surface.blit(self.image, (self.x, 0))
- surface.blit(self.invertedImage, (self.invertedX, 0))
-
- # -----------------------------------------------------------------------------------------------------------------
\ No newline at end of file
diff --git a/data/backgroundfoliage.py b/data/backgroundfoliage.py
deleted file mode 100644
index 6a9baca..0000000
--- a/data/backgroundfoliage.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# coding=utf-8
-from random import randint, choice
-import pygame
-import os
-
-class BackgroundFoliage(object):
-
- def __init__(self, x, y):
- self.x = x
- self.y = y
-
- # Images
- self.images = [pygame.image.load('items'+os.sep+'rock.png').convert_alpha(),
- pygame.image.load('environment'+os.sep+'main'+os.sep+'hill_smallAlt.png').convert_alpha(),
- pygame.image.load('items'+os.sep+'plant.png').convert_alpha(),
- pygame.image.load('items'+os.sep+'bush.png').convert_alpha()]
- self.image = choice(self.images)
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
-
-# -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, surface):
- surface.blit(self.image, (self.x, self.y))
diff --git a/data/block.py b/data/block.py
deleted file mode 100644
index 7400290..0000000
--- a/data/block.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# coding=utf-8
-from random import randint
-from game import *
-
-class Block(object):
-
- def __init__(self, x, y, form):
- # The argument for the "form" parameter should be one of the following strings:
- # 'locked'/'coin'/'regular'/'explosive'
- self.form = form
-
- # Initialize position
- self.x = x
- self.y = y
-
- # Load images
- self.lockedImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'lock_blue.png').convert_alpha()
- self.coinBlockImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'boxCoin.png').convert_alpha()
- self.coinBlockUsedImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'boxCoin_disabled.png').convert_alpha()
- self.explosiveImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'boxExplosive.png').convert_alpha()
- self.explosiveUsedImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'boxExplosive_disabled.png').convert_alpha()
- self.regularImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'boxItem.png').convert_alpha()
- self.regularUsedImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'boxItem_disabled.png').convert_alpha()
- self.explosion = []
- for i in range(0, 3):
- explosionImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'explosion' + str(i) + '.png').convert_alpha()
- explosionImage = pygame.transform.scale2x(explosionImage)
- self.explosion.append(explosionImage)
- self.width = pygame.Surface.get_width(self.regularImage)
- self.height = pygame.Surface.get_height(self.regularImage)
-
- # Load sounds
- self.explosionSfx = pygame.mixer.Sound('sounds'+os.sep+'synthetic_explosion_1.ogg')
-
- # Coin images and variables
- self.coinImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'coinGold.png').convert_alpha()
- self.coinWidth = pygame.Surface.get_width(self.coinImage)
- self.coinHeight = pygame.Surface.get_height(self.coinImage)
- self.coinPos = [self.x - 15, self.y - self.coinHeight + 10,
- self.x + self.coinWidth - 15, self.y + 10]
- self.coinVisible = False
-
- # Other images and related variables
- self.starImage = pygame.image.load('items'+os.sep+'star.png').convert_alpha()
- self.starWidth = pygame.Surface.get_width(self.starImage)
- self.starHeight = pygame.Surface.get_height(self.starImage)
-
- # Other variables to track state of block
- self.disabled = False
- self.willExplode = False
- self.yieldsStar = False
- if self.form == 'explosive':
- self.willExplode = True
- self.explosionStep = 0
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def __getitem__(self, i):
- if i == 0:
- return self.x, self.y, self.x + self.width, self.y + self.height
- else:
- return self.coinPos[i - 1]
-
- # -----------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def distance(p0, p1):
- return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def update(self, keys, surface):
- self.updateState()
- self.draw(keys, surface)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def updateState(self):
- self.coinPos = [self.x - 15, self.y - self.coinHeight + 10,
- self.x + self.coinWidth - 15, self.y + 10]
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def disable(self):
- self.coinVisible = True
- self.disabled = True
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def killcoin(self):
- self.coinVisible = False
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, keys, surface):
-
- # Draw the correct type of block
- if self.form == 'locked':
- image = self.lockedImage
- elif self.form == 'coin' and self.disabled:
- image = self.coinBlockUsedImage
- elif self.form == 'coin' and not self.disabled:
- image = self.coinBlockImage
- elif self.form == 'regular' and self.disabled:
- image = self.regularUsedImage
- elif self.form == 'regular' and not self.disabled:
- image = self.regularImage
- elif self.form == 'explosive' and self.disabled:
- image = self.explosiveUsedImage
- elif self.form == 'explosive' and not self.disabled:
- image = self.explosiveImage
- else:
- image = self.regularImage
- surface.blit(image, (self.x, self.y))
-
- # Draw any coins or other objects that may be present
- if self.form == 'coin':
- for i in range(0, len(self.coinPos)):
- if self.coinVisible:
- surface.blit(self.coinImage, (self.coinPos[0], self.coinPos[1]))
- if self.form == 'regular':
- for key in keys:
- if self.coinVisible and self.disabled and self.distance((self.x, self.y), (key.x, key.y)) < \
- 1.5 * key.height:
- key.visible = True
- self.coinVisible = False
- if self.willExplode and self.disabled:
- if randint(0, 2) == 0 and self.explosionStep < len(self.explosion):
- self.explosionStep += 1
- if self.explosionStep < len(self.explosion):
- surface.blit(self.explosion[self.explosionStep], (self.x - 65, self.y - 135))
- self.explosionSfx.play()
- if self.yieldsStar and self.disabled and self.coinVisible:
- surface.blit(self.starImage, (self.coinPos[0] + 20, self.coinPos[1] + 30))
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def getRect(self):
- return pygame.Rect(self.x, self.y, self.width, self.height)
diff --git a/data/character.py b/data/character.py
deleted file mode 100644
index 8dc7fca..0000000
--- a/data/character.py
+++ /dev/null
@@ -1,340 +0,0 @@
-# coding=utf-8
-from random import randint
-import math
-import pygame
-import os
-
-class Character(object):
-
- def __init__(self, x, y, Vx=0, Vy=0, whichChar=1):
- # Initialize motion variables
- self.x = x
- self.y = y
- self.Vx = Vx
- self.Vy = Vy
-
- # Hard-code the gravity acceleration, jumping speed, and run speed
- self.gravity = 2.5
- self.jumpSpeed = 30
- self.runSpeed = 5
-
- # Initialize variables related to drawing and motion to zero/false
- self.walkFrame = 0
- self.mobJumping = False
- self.underwater = False
- self.movingLaterally = False
- self.jumping = False
- self.canJump = False
- self.onGround = False
- self.hasKey = False
- self.direction = 0
- self.currentPlatform = 0
- self.lowestPlatform = 0
-
- # Score and coins
- if whichChar == 1:
- self.health = 4
- elif whichChar == 2:
- self.health = 6
- else:
- self.health = 10
- self.recoveryHealth = self.health
- self.flashing = False
- self.flashTimer = 0
- self.coins = 0
-
- # Load images and save the height and width of the character
- filePrefix = 'character'+os.sep+'main'+os.sep+'p' + str(whichChar)
- self.standingImage = pygame.image.load(filePrefix + '_front.png').convert_alpha()
- self.jumpingImageL = pygame.image.load(filePrefix + '_jump_l.png').convert_alpha()
- self.jumpingImageR = pygame.image.load(filePrefix + '_jump.png').convert_alpha()
- self.duckL = pygame.image.load(filePrefix + '_duck_l.png').convert_alpha()
- self.duckR = pygame.image.load(filePrefix + '_duck.png').convert_alpha()
- self.duckHeight = pygame.Surface.get_height(self.duckL)
- self.ducking = False
- self.width = pygame.Surface.get_width(self.standingImage)
- self.height = pygame.Surface.get_height(self.standingImage)
- self.walkImagesR = [] * 11
- self.walkImagesL = [] * 11
- for i in range(1, 11):
- walkImage = pygame.image.load(filePrefix + '_walk'+os.sep+'PNG'+os.sep+'p' + str(whichChar) + '_walk' + str(i) +
- ".png").convert_alpha()
- self.walkImagesR.append(walkImage)
- walkImageL = pygame.transform.flip(walkImage, True, False)
- self.walkImagesL.append(walkImageL)
-
- # Use 2D kinematics to determine maximum jump height and length
- self.jumpTime = float(self.jumpSpeed) / self.gravity
- self.maxJumpHeight = int(0.5 * self.jumpSpeed * self.jumpTime)
- self.maxJumpLength = int(self.runSpeed * self.jumpTime)
-
- # Save the character ID
- self.whichChar = whichChar
-
- # Visibility
- self.visible = True
-
- # Other variables
- self.platformTolerance = 15
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def platformInit(self, platforms):
- self.determineLowestPlatform(platforms)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool, surface, FPS, torches=None):
- if self.visible:
- self.updateMotion(platforms)
- self.collide(platforms, blocks, aiCharacters, pool, torches)
- self.draw(surface, FPS)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def determineLowestPlatform(self, platforms):
- for platform in range(0, len(platforms)):
- if platforms[platform].y > platforms[self.lowestPlatform].y:
- self.lowestPlatform = platform
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def jump(self, intensity=1.0):
- # Generic jump method that does not check if jumping is feasible
- self.Vy = math.floor(-intensity * self.jumpSpeed)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def updateMotion(self, platforms):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Use 2D kinematics to update maximum jump height and length
- self.maxJumpHeight = math.floor(0.5 * self.jumpSpeed * self.jumpTime)
- self.maxJumpLength = math.floor(self.runSpeed * self.jumpTime)
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0].height - 5
-
- # Dispose if falling off screen
- if not self.onGround and self.Vy >= platforms[0].height - 5:
- self.dispose()
-
- # Apply gravity if necessary
- if self.onGround:
- self.Vy = 0
- self.mobJumping = False
- else:
- self.Vy += self.gravity
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def blockCollide(self, blocks):
- # Local variables for player position
- left = self.x + 10
- right = self.x + self.width - 10
- top = self.y
- bottom = self.y + self.height
-
- for block in blocks:
- if 0 <= block.x <= 2000 and 0 <= block.y <= 2000:
- # Local variables for block position
- blockLeft = block.x
- blockRight = block.x + block.width
- blockTop = block.y
- blockBottom = block.y + block.height
- blockMiddleX = int(0.5 * blockLeft + 0.5 * blockRight)
- blockMiddleY = int(0.5 * blockBottom + 0.5 * blockTop)
-
- # Booleans for player position relative to block
- belowBlock = right >= blockLeft and left <= blockRight and blockMiddleY - 20 <= top <= blockBottom
- leftOfBlock = blockLeft <= right < blockMiddleX and bottom > blockTop and top < blockBottom
- rightOfBlock = blockRight >= left > blockMiddleX and bottom > blockTop and top < blockBottom
- aboveBlock = right >= blockLeft + 10 and left <= blockRight - 10 and blockBottom > bottom >= blockTop
-
- hitBlock = False
- if belowBlock and self.Vy <= 0:
- self.y = block.y + block.height + 1
- self.Vy = 0
- hitBlock = True
- elif leftOfBlock:
- self.x = blockLeft - self.width
- self.Vx *= -1
- return True
- elif rightOfBlock:
- self.x = blockRight
- self.Vx *= -1
- return True
- elif aboveBlock and self.Vy >= 0:
- self.y = blockTop - self.height
- self.onGround = True
- if not block.disabled and hitBlock:
- block.disable()
- if block.willExplode and not self.flashing:
- self.health -= 1
- self.flashing = True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def coinCollide(self, blocks):
- selfRect = self.getRect()
- for block in blocks:
- if 0 <= block.x <= 2000 and 0 <= block.y <= 2000:
- coin = block.coinPos
- coinRect = pygame.Rect(coin[0], coin[1], block.coinWidth, block.coinHeight)
- starRect = pygame.Rect(coin[0], coin[1], block.starWidth, block.starHeight)
- if block.coinVisible and selfRect.colliderect(coinRect) and not block.yieldsStar:
- # Coin effect
- self.coins += 1
- block.killcoin()
- elif block.coinVisible and selfRect.colliderect(starRect):
- # Star effect
- self.coins += 10
- self.health += 2
- block.killcoin()
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def platformCollide(self, platforms, pool):
- # Check for collision with platforms
- for i in range(0, len(platforms)):
- if self.x + self.width >= platforms[i][0] + self.platformTolerance and self.x <= platforms[i][2] - \
- self.platformTolerance and platforms[i][1] <= self.y + self.height <= platforms[i][3] + 35 and \
- self.Vy >= 0:
- self.y = platforms[i][1] - self.height
- self.onGround = True
- self.currentPlatform = i
- if self.x + self.width >= platforms[i][0] + self.platformTolerance and self.x <= platforms[i][2] - \
- self.platformTolerance and platforms[i][3] >= self.y >= platforms[i][1] - \
- self.platformTolerance and self.Vy < 0:
- if self.x + self.width >= platforms[i][0] + platforms[i].tileWidth and \
- self.x <= platforms[i][2] - platforms[i].tileWidth:
- self.y = platforms[i][3]
- self.Vy = 0
- elif self.y <= platforms[i][1] + self.platformTolerance + 30:
- self.y = platforms[i][3]
- self.Vy = 0
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def aiCollide(self, aiCharacters):
- if not self in aiCharacters:
- for aiCharacter in aiCharacters:
- if 0 <= aiCharacter.x <= 2000 and 0 <= aiCharacter.y <= 2000:
- aiCharacterRect = aiCharacter.getRect()
- selfRect = self.getRect()
- if selfRect.colliderect(aiCharacterRect) and aiCharacter.alive:
- if self.Vy > 0 and aiCharacter.mobType != 'fly':
- aiCharacter.health -= 5 - self.whichChar
- self.jump(0.75)
- self.mobJumping = True
- self.onGround = False
- elif self.Vy > 0:
- self.jump(0.8)
- self.onGround = False
- aiCharacter.alive = False
- elif not self.mobJumping and self.flashTimer == 0:
- self.health -= 1
- self.flashing = True
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def poolCollide(self, platforms, pool):
- if pool and self.x not in range(int(platforms[self.currentPlatform][0]),
- int(platforms[self.currentPlatform][2])):
- PlayerLeftX = self.x
- PlayerRightX = self.x + self.width
- PlayerBottomY = self.y + self.height
- if pool.y <= PlayerBottomY <= pool.y + pool.tileWidth and ((PlayerRightX - 10 >= pool.x and PlayerLeftX + 10
- <= pool.poolStartX + pool.tileWidth) or (PlayerRightX - 10 >= pool.poolEndX and PlayerLeftX + 10
- <= pool.x + pool.width)) and self.Vy >= 0:
- self.onGround = True
- self.y = pool.y - self.height
- if PlayerLeftX + 10 >= pool.poolStartX and PlayerRightX - 10 <= pool.poolEndX + pool.tileWidth and \
- pool.y + pool.height <= PlayerBottomY <= pool.y + pool.height + pool.tileWidth and self.Vy >= 0:
- self.onGround = True
- self.y = pool.y + pool.height - self.height
- if pool.poolStartX + pool.tileWidth >= PlayerLeftX >= pool.poolStartX and \
- pool.y < PlayerBottomY <= pool.y + pool.height:
- self.x = pool.poolStartX + pool.tileWidth
- self.Vx *= -1
- if pool.poolEndX <= PlayerRightX <= pool.poolEndX + pool.tileWidth and \
- pool.y < PlayerBottomY <= pool.y + pool.height:
- self.x = pool.poolEndX - self.width
- self.Vx *= -1
- if PlayerRightX >= pool.poolStartX and PlayerLeftX <= pool.poolEndX and \
- pool.y + pool.height >= PlayerBottomY > pool.y:
- self.underwater = True
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def prepCollisionDetection(self):
- self.onGround = False
- self.underwater = False
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def torchCollide(self, torches):
- if torches:
- for torch in torches:
- if self.getRect().colliderect(torch.getRect()):
- torch.burning = True
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def collide(self, platforms, blocks, aiCharacters, pool, torches):
- self.prepCollisionDetection()
- self.blockCollide(blocks)
- self.coinCollide(blocks)
- self.platformCollide(platforms, pool)
- self.aiCollide(aiCharacters)
- self.poolCollide(platforms, pool)
- self.torchCollide(torches)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, surface, FPS=60):
-
- # Increment the current frame of the player walking animation
- footstepRarity = 1
- if pygame.time.get_ticks() % footstepRarity == 0:
- self.walkFrame += 1
- if self.walkFrame >= 10:
- self.walkFrame = 0
-
- # Correctly display the current action of the player
- totalFlashTime = 4
- if self.flashing:
- self.flashTimer += 1
- else:
- self.flashTimer = 0
- if self.flashTimer >= (FPS * totalFlashTime):
- self.flashing = False
- if self.flashTimer == 0 or self.flashTimer % FPS < (FPS * 0.75):
- if self.ducking and self.direction == 0:
- surface.blit(self.duckL, (self.x, self.y + self.height - self.duckHeight))
- elif self.ducking:
- surface.blit(self.duckR, (self.x, self.y + self.height - self.duckHeight))
- elif self.jumping and self.direction == 1:
- surface.blit(self.jumpingImageR, (self.x, self.y))
- elif self.jumping and self.direction == 0:
- surface.blit(self.jumpingImageL, (self.x, self.y))
- elif self.onGround and self.movingLaterally and self.direction == 1:
- surface.blit(self.walkImagesR[self.walkFrame], (self.x, self.y))
- elif self.onGround and self.movingLaterally and self.direction == 0:
- surface.blit(self.walkImagesL[self.walkFrame], (self.x, self.y))
- else:
- surface.blit(self.standingImage, (self.x, self.y))
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def getRect(self):
- return pygame.Rect(self.x + 10, self.y + 5, self.width - 10, self.height - 5)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def dispose(self):
- self.visible = False
diff --git a/data/checkpoint.py b/data/checkpoint.py
deleted file mode 100644
index 73f2a9c..0000000
--- a/data/checkpoint.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# coding=utf-8
-import pygame
-import os
-
-class Checkpoint(object):
-
- def __init__(self, x, y, isBroken=False):
- self.x = x; self.y = y
- self.image = pygame.image.load('environment'+os.sep+'main'+os.sep+'fence.png').convert_alpha()
- self.imageBroken = pygame.image.load('environment'+os.sep+'main'+os.sep+'fenceBroken.png').convert_alpha()
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
- self.broken = isBroken
-
- def draw(self, surface):
- if self.broken:
- surface.blit(self.imageBroken, (self.x, self.y))
- else:
- surface.blit(self.image, (self.x, self.y))
-
- def getRect(self):
- return pygame.Rect(self.x, self.y, self.width, self.height)
diff --git a/data/checkpointManager.py b/data/checkpointManager.py
deleted file mode 100644
index 3597991..0000000
--- a/data/checkpointManager.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# coding=utf-8
-import pygame
-
-class CheckpointManager(object):
-
- def __init__(self, platforms, blocks, character):
- # Initialize lists for the co-ordinates for every checkpoint and the direction needed to get there
- self.checkpointsLeft, self.checkpointsRight = [] * 2
- self.checkpointDirectionsL, self.checkpointDirectionsR = [] * 2
- self.indexLevel(platforms, blocks, character)
-
- def indexLevel(self, platforms, blocks, char):
- # This method obtains all of the level information necessary to pathfind
-
- # Gather information about the character
- maxW = char.maxJumpLength
- maxH = char.maxJumpWidth
- charRect = pygame.Rect(char.x, char.y, char.width, char.height)
- charW = char.width
-
- # Fill in the checkpoint coordinates and directions
- for platform in platforms:
- self.checkpointsLeft.append(platform.x + 5)
- self.checkpointsRight.append(platform.x + platform.width - charW - 5)
diff --git a/data/door.py b/data/door.py
deleted file mode 100644
index 01c1433..0000000
--- a/data/door.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# coding=utf-8
-from game import *
-
-
-class Door(object):
- def __init__(self, x, y):
- self.x = x
- self.y = y
- self.locked = True
-
- # Load images
- self.imageBottom = pygame.image.load('environment'+os.sep+'main'+os.sep+'door_openMid.png').convert_alpha()
- self.imageTop = pygame.image.load('environment'+os.sep+'main'+os.sep+'door_openTop.png').convert_alpha()
- self.imageBottomLocked = pygame.image.load('environment'+os.sep+'main'+os.sep+'door_closedMid.png').convert_alpha()
- self.imageTopLocked = pygame.image.load('environment'+os.sep+'main'+os.sep+'door_closedTop.png').convert_alpha()
- self.bottomHeight = pygame.Surface.get_height(self.imageBottom)
- self.topHeight = pygame.Surface.get_height(self.imageTop)
- self.topBlankSpace = 30
- self.height = self.bottomHeight + self.topHeight - self.topBlankSpace
- self.width = pygame.Surface.get_width(self.imageBottom)
- self.y -= self.bottomHeight + self.topHeight
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, mainChar, surface, unlockable=True):
- charRect = pygame.Rect(mainChar.x, mainChar.y, mainChar.width, mainChar.height)
- selfRect = self.getRect()
- inDoor = charRect.colliderect(selfRect)
- hasKey = mainChar.hasKey
- if (inDoor and hasKey) or not unlockable:
- self.locked = False
- if self.locked:
- surface.blit(self.imageTopLocked, (self.x, self.y))
- surface.blit(self.imageBottomLocked, (self.x, self.y + self.topHeight))
- else:
- surface.blit(self.imageTop, (self.x, self.y))
- surface.blit(self.imageBottom, (self.x, self.y + self.topHeight))
- if not self.locked and inDoor and unlockable:
- return True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
- def getRect(self):
- return pygame.Rect(self.x, self.y + self.topBlankSpace, self.width, self.height)
diff --git a/data/game.py b/data/game.py
deleted file mode 100644
index 367a89f..0000000
--- a/data/game.py
+++ /dev/null
@@ -1,1585 +0,0 @@
-# coding=utf-8
-import sys, math, pygame, os.path, keymap as k, random as r
-from pygame.locals import *
-from data.aicharacter import AICharacter
-from data.background import Background
-from data.backgroundfoliage import BackgroundFoliage
-from data.block import Block
-from data.checkpoint import Checkpoint
-from data.door import Door
-from data.key import Key
-from data.platform import Platform
-from data.playablecharacter import PlayableCharacter
-from data.pool import Pool
-from data.spike import FallingSpike
-from data.torch import Torch
-
-# Colour constants
-white = (255, 255, 255)
-grey = (185, 185, 185)
-black = (0, 0, 0)
-red = (155, 0, 0)
-brightred = (175, 20, 20)
-green = (0, 155, 0)
-brightgreen = (20, 175, 20)
-blue = (0, 0, 155)
-brightblue = (20, 20, 175)
-yellow = (255, 255, 0)
-
-# FPS constants
-SLOWFPS = 25
-VSYNCFPS = 60
-SMOOTHFPS = 65
-UNLIMITEDFPS = 800
-
-
-class Game(object):
-
- def __init__(self, fps=65, fullscreen=True, numlevels=10):
- pygame.init()
-
- # Initialize control variables for the game instance
- self.developerMode = True
- self.antialiasing = True
- self.stableFPS = True
- self.decorations = True
- self.fpsClock = pygame.time.Clock()
- self.desiredFPS = fps
- self.fps, self.measuredFPS = self.desiredFPS, self.desiredFPS
- self.screenW = pygame.display.list_modes()[0][0]
- self.screenH = pygame.display.list_modes()[0][1]
- self.originalDimensions = [self.screenW, self.screenH]
- self.caption = 'Exit Dash - Hyperion'
- self.fullscreen = fullscreen
- self.flags = None
- self.displaysurf = None
- self.updateDisplayState()
- self.resDict = self.getResolutionDict()
- self.allMovableObjects, self.enemies = [], []
- self.defaultValue = -999
- self.levelDelay = 50
- self.devInfoX = self.screenW - 350
- self.devInfoY = 50
- self.devSpacing = 19
- self.mousex, self.mousey, self.mousex_hover, self.mousey_hover = 0, 0, 0, 0
- self.currLevel = 0
- self.doPlayMusic = True
- self.volume = 0.5
- self.autoscroll = False
- self.topmostPlatform, self.lowestPlatform, self.shortestPlatform, self.longestPlatform, \
- self.farthestPlatform = 0, 0, 0, 0, 0
- self.seed = None
- self.allowKillBonus = False
- self.receivingKillBonus = False
- self.firstCharX = 100
- self.secondCharX = self.screenW // 2 - 10
- self.thirdCharX = self.screenW - 220
- self.charY = math.floor(self.screenH / 2) - 50
- self.firstChar = PlayableCharacter(self.firstCharX, self.charY)
- self.secondChar = PlayableCharacter(self.secondCharX, self.charY, whichChar=2)
- self.thirdChar = PlayableCharacter(self.thirdCharX, self.charY, whichChar=3)
- self.clicking = False
- self.editorResult = False
- self.currentResolution = str(self.screenH) + 'p'
- self.recentKeyboardKeys = ''
- self.keyPressEvent = KEYDOWN
- self.maxKeyMemoryLength = 15
- self.levelDark = False
- self.levelHint = ''
- self.torches = []
- self.overwriteLevels = True
- self.numLevels = numlevels
-
- # Get game directory size
- self.totalSize = self.getGameDirSize()
-
- # Other file vars
- self.configExtension = '.cfg'
- self.levelExtension = '.dat'
-
- # Load settings from file
- self.loadGameSettings()
-
- # Game objects
- self.mainChar, self.platforms, self.pool, self.blocks, self.keys, self.door, self.fakedoor, self.icicles, \
- self.foliage, self.mobs, self.enemies, self.gameStart, self.fences = [None] * 13
- self.textTimers = [0] * 10
-
- # Music
- self.themeSong = 'music'+os.sep+'waking_devil.mp3'
- self.mainMusic = 'music'+os.sep+'char1_3.ogg'
- self.gameOverMusic = 'music'+os.sep+'gameover.mp3'
-
- # Fonts
- self.genericFont = pygame.font.Font('fonts'+os.sep+'2lines.ttf', 48)
- self.medFont = pygame.font.Font('fonts'+os.sep+'jetset.ttf', 24)
- self.smlFont = pygame.font.Font('fonts'+os.sep+'atari.ttf', 16)
- self.smoothFont = pygame.font.Font('fonts'+os.sep+'source.otf', 18)
-
- # Level theme
- self.theme = 'stone'
- self.backgroundTheme = 'castle'
-
- # Backgrounds
- self.origin = (0, 0)
- self.bgrdTitle = pygame.image.load('backgrounds'+os.sep+'main'+os.sep+'title_bgrd_compressed.png').convert()
- self.bgrdGloomy = pygame.image.load('backgrounds'+os.sep+'main'+os.sep+'red_sky.jpg').convert()
- self.bgrdYellowSky = pygame.image.load('backgrounds'+os.sep+'main'+os.sep+'yellow-sky.jpg').convert()
- self.bgrdCastle = pygame.image.load('backgrounds'+os.sep+'main'+os.sep+'bg_castle.png').convert()
- self.bgrdCastle = pygame.transform.smoothscale(self.bgrdCastle, (3 * pygame.Surface.get_width(self.bgrdCastle),
- 3 * pygame.Surface.get_height(self.bgrdCastle)))
- self.bgrdDesert = pygame.image.load('backgrounds'+os.sep+'main'+os.sep+'bg_desert.png').convert()
- self.bgrd = None
- self.activeBackground = None
-
- # Cursor
- self.prevCursorVisibleState = pygame.mouse.set_visible(False) # Hide existing cursor
- self.cursorImage = pygame.image.load('hud'+os.sep+'pointer.png').convert_alpha()
- self.cursorImage = pygame.transform.scale2x(self.cursorImage)
- self.cursorClickedImage = pygame.image.load('hud'+os.sep+'pointerClicked.png').convert_alpha()
- self.cursorClickedImage = pygame.transform.scale2x(self.cursorClickedImage)
-
- # Options UI Images
- self.slider = pygame.image.load('ui'+os.sep+'grey_sliderHorizontal.png').convert_alpha()
- self.sliderPointer = pygame.image.load('ui'+os.sep+'grey_sliderDown.png').convert_alpha()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def reinit(self):
- """ Performs a reinitialization of position-sensitive calculations. Can be called anytime after init. """
- self.devInfoX = self.screenW - 350
- self.secondCharX = self.screenW // 2 - 10
- self.thirdCharX = self.screenW - 220
- self.charY = math.floor(self.screenH / 2) - 50
- self.firstChar = PlayableCharacter(self.firstCharX, self.charY, 0, 0, 1)
- self.secondChar = PlayableCharacter(self.secondCharX, self.charY, 0, 0, 2)
- self.thirdChar = PlayableCharacter(self.thirdCharX, self.charY, 0, 0, 3)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def refreshDisplay(self):
- pygame.display.init()
- self.displaysurf = pygame.display.set_mode((self.screenW, self.screenH), self.flags, 0)
- pygame.display.set_caption(self.caption)
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def quitGame():
- pygame.quit()
- print('Game closing...')
- sys.exit()
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def toBool(x):
- return 'True' in x
-
- # --------------------------------------------------------------------------------------------------------------
-
- def getGameDirSize(self):
- parentDirectory = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
- return self.getSize(parentDirectory)
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def getSize(startPath='.'):
- size = 0
- bytesInMegabyte = 1048576.0
- for dirpath, dirnames, filenames in os.walk(startPath):
- for f in filenames:
- fp = os.path.join(dirpath, f)
- size += os.path.getsize(fp)
- size /= bytesInMegabyte
- return round(size, 2)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def updateDisplayState(self, windowedConstant=0.82):
- """ Updates the fullscreen status of the display surface
-
- Args:
- windowedConstant (float, optional): Ratio between windows screen dimensions and fullscreen dimensions
-
- """
- if self.fullscreen:
- self.flags = FULLSCREEN | HWACCEL | ASYNCBLIT
- self.screenW, self.screenH = self.originalDimensions
- else:
- self.flags = HWACCEL | ASYNCBLIT
- self.screenW = int(windowedConstant * self.originalDimensions[0])
- self.screenH = int(windowedConstant * self.originalDimensions[1])
- self.refreshDisplay()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def getRecentKeys(self, events, restrictToAlphabet=True):
- for event in events:
- if event.type == self.keyPressEvent and (len(pygame.key.name(event.key)) == 1 or not restrictToAlphabet):
- self.recentKeyboardKeys += pygame.key.name(event.key)
- while len(self.recentKeyboardKeys) > self.maxKeyMemoryLength:
- self.recentKeyboardKeys = self.recentKeyboardKeys[1:]
-
- # --------------------------------------------------------------------------------------------------------------
-
- def printText(self, text, font, colour, coords, center=False):
- """ Prints the input string onto the display surface with the given settings
-
- Args:
- text (str): String to display on screen
- font (pygame.font.Font): Cached font to use for the text
- colour (tuple of int): RGB constant for the desired text colour
- coords (tuple of int): X and y coordinates for text display
- center (bool, optional): Whether the given coords act as the center or top left of the displayed text
-
- Returns:
- pygame.Rect object representing the rectangle boundaries of the text
-
- """
-
- textSurf = font.render(text, self.antialiasing, colour)
- textRect = textSurf.get_rect()
- if center:
- textRect.center = coords
- else:
- textRect.topleft = coords
- self.displaysurf.blit(textSurf, textRect)
- return textRect
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def getAngle(pointA, pointB):
- # Determines the angle between a line (defined by points A and B) and the positive x-axis
- Ax, Ay = pointA
- Bx, By = pointB
- return math.atan2(By - Ay, Bx - Ax) * (180 / math.pi)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def checkForQuit(self):
- keys = pygame.key.get_pressed()
- if keys[k.EXIT]:
- self.quitGame()
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def distance(p0, p1):
- return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawTempText(self, text, font, colour, coords, time, index, events):
- # Set timer
- if self.textTimers[index] == 0:
- pygame.time.set_timer(USEREVENT + index, time)
- self.textTimers[index] = 1
-
- # Reset timer once finished
- for event in events:
- if event.type == USEREVENT + index:
- self.textTimers[index] = 2
-
- # Display text if the timer is working
- if self.textTimers[index] == 1:
- self.printText(text, font, colour, coords)
- return True
- return False
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawCursor(self):
- if not pygame.mouse.get_pressed()[0]:
- self.displaysurf.blit(self.cursorImage, (self.mousex_hover, self.mousey_hover))
- else:
- self.displaysurf.blit(self.cursorClickedImage, (self.mousex, self.mousey))
-
- # --------------------------------------------------------------------------------------------------------------
-
- def redrawAndProceedTick(self, mousex, mousey, mouseRegionUpdating=False):
- self.drawCursor()
- if mouseRegionUpdating:
- pygame.display.update(pygame.Rect(mousex - 300, mousey - 300, 600, 600))
- pygame.display.update()
- fpsTolerance = 4
- if self.measuredFPS < self.desiredFPS - fpsTolerance and self.fps < 2 * self.desiredFPS:
- self.fps += 0.1
- elif self.measuredFPS > self.desiredFPS + fpsTolerance and self.fps > 0:
- self.fps -= 0.1
- if self.stableFPS:
- self.fpsClock.tick_busy_loop(self.fps)
- else:
- self.fpsClock.tick(self.fps)
- self.measuredFPS = self.fpsClock.get_fps()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def showGameOverScreen(self, won):
- self.displaysurf.blit(self.bgrdTitle, self.origin)
- outcome = 'win' if won else 'lose'
- self.printText('Game Over! You ' + outcome + '.', self.genericFont, white, (50, 50))
- self.printText(str(self.mainChar.coins) + ' coins', self.medFont, white, (50, 100))
- self.printText(str(self.mainChar.lives) + ' lives left', self.medFont, white, (50, 150))
- self.printText(str(int(pygame.time.get_ticks() / 1000)) + ' seconds', self.medFont, white, (50, 200))
- self.printText('TOTAL SCORE: ' + str(int(self.mainChar.coins +
- 100 * self.mainChar.lives - 0.1 * pygame.time.get_ticks() / 1000)),
- self.medFont, white, (50, 250))
- self.printText('Esc to Quit', self.medFont, white, (50, 300))
- keys = pygame.key.get_pressed()
- while not keys[k.EXIT]:
- keys = pygame.key.get_pressed()
- self.redrawAndProceedTick(self.mousex_hover, self.mousey_hover)
- pygame.event.get()
- self.quitGame()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawToggle(self, name, coords, mousepos, mousehoverpos, on=True):
- # Draw the text for the toggle and save the rects
- mainText = self.printText(name, self.medFont, white, coords)
- onText = self.printText('ON', self.smlFont, white, (mainText.right + 50, coords[1] + 10))
- slash = self.printText(' / ', self.smlFont, white, (onText.right + 5, coords[1] + 10))
- offText = self.printText('OFF', self.smlFont, white, (slash.right + 5, coords[1] + 10))
-
- # Make the ON/OFF text yellow if it is the selected option or if the mouse hovers over it
- if onText.collidepoint(mousehoverpos[0], mousehoverpos[1]) or on:
- onText = self.printText('ON', self.smlFont, yellow, (mainText.right + 50, coords[1] + 10))
- if offText.collidepoint(mousehoverpos[0], mousehoverpos[1]) or not on:
- offText = self.printText('OFF', self.smlFont, yellow, (slash.right + 5, coords[1] + 10))
-
- # Return a toggle output
- if onText.collidepoint(mousepos[0], mousepos[1]) and self.clicking:
- return True
- elif offText.collidepoint(mousepos[0], mousepos[1]) and self.clicking:
- return False
- return self.defaultValue
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawSlider(self, label, coords, value, valueMax, unlockCondition=True):
- # Draw a title for the slider
- text = self.printText(label, self.medFont, white, coords)
-
- # Determine the coordinates relevant to the actual slider
- separation = 40
- startX = text.right + separation
- length = pygame.Surface.get_width(self.slider)
-
- # Draw the slider
- self.displaysurf.blit(self.slider, [startX, coords[1] + 10])
-
- # Determine the slider pointer position
- pointerX = startX + length * value / valueMax
- pointerWidth = pygame.Surface.get_width(self.sliderPointer)
- pointerHeight = pygame.Surface.get_height(self.sliderPointer)
- sliderRect = pygame.Rect(pointerX, coords[1], pointerWidth, pointerHeight)
- collisionBorder = 100
- collisionRect = pygame.Rect(pointerX - collisionBorder, coords[1], pointerWidth +
- 2 * collisionBorder, pointerHeight)
-
- # Move the slider pointer
- if collisionRect.collidepoint(self.mousex, self.mousey) and pygame.mouse.get_pressed()[0] and unlockCondition:
- pointerX = self.mousex - 0.5 * sliderRect.width
-
- # Ensure that the pointer is within bounds
- if pointerX + 0.5 * sliderRect.width >= startX + length:
- pointerX = startX + length - 0.5 * sliderRect.width
- if pointerX < startX:
- pointerX = startX
-
- # Draw the slider
- self.displaysurf.blit(self.sliderPointer, [pointerX, coords[1]])
-
- # Return the new value determined by the slider pointer position
- return valueMax * (pointerX - startX) / length
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def getDisplayResolutions():
- pygame.display.init()
- result = [pygame.display.list_modes()[0]]
- acceptableHeights = [2160, 1440, 1200, 1080, 900, 720, 600]
- for mode in pygame.display.list_modes():
- if mode[1] in acceptableHeights and len(result) < 5 and not mode in result:
- result.append(mode)
- return result
-
- # --------------------------------------------------------------------------------------------------------------
-
- def getResolutionDict(self):
- modes = self.getDisplayResolutions()
- result = {}
- for mode in modes:
- result[str(mode[1]) + 'p'] = mode
- return result
-
- # --------------------------------------------------------------------------------------------------------------
-
- def saveGameSettings(self):
- # Open file for writing
- fileName = 'settings' + self.configExtension
- permissions = 'w'
- dataFile = open(fileName, permissions)
-
- # Add a warning to the data file
- dataFile.write('Game Settings Configuration - DO NOT MODIFY THIS FILE! Change settings in-game!\n')
-
- # Save settings
- dataFile.write(str(self.developerMode) + '\n' + str(self.antialiasing) + '\n' + str(self.stableFPS) + '\n' +
- str(self.decorations) + '\n' + str(self.doPlayMusic) + '\n' + str(self.fullscreen) + '\n' +
- str(self.volume) + '\n' + str(self.currentResolution))
-
- dataFile.close()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def loadGameSettings(self):
- # Collect information
- fileName = 'settings' + self.configExtension
- if not os.path.isfile(fileName):
- return
- permissions = 'r'
- dataFile = open(fileName, permissions)
- uselessWarning = dataFile.readline()
- print uselessWarning
-
- # Read settings
- self.developerMode = self.toBool(dataFile.readline())
- self.antialiasing = self.toBool(dataFile.readline())
- self.stableFPS = self.toBool(dataFile.readline())
- self.decorations = self.toBool(dataFile.readline())
- self.doPlayMusic = self.toBool(dataFile.readline())
- self.fullscreen = self.toBool(dataFile.readline())
- self.volume = float(dataFile.readline())
- self.currentResolution = dataFile.readline()
-
- # Make sure that the resolution setting is valid
- if not self.currentResolution in self.resDict.keys():
- self.currentResolution = str(self.getDisplayResolutions()[0][1]) + 'p'
-
- dataFile.close()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawOptionsMenu(self):
- while True:
-
- # Fill screen with background
- self.displaysurf.fill(black)
- self.displaysurf.blit(self.bgrdTitle, self.origin)
-
- # Get mouse status
- self.getMousePos()
-
- # Draw title
- self.printText('Exit Dash: Hyperion | Options Menu', self.genericFont, white, [self.screenW // 2, 50], True)
-
- # Draw toggles
- devModeToggle = self.drawToggle('Debug Info', (math.ceil(0.2 * self.screenW), 150),
- (self.mousex, self.mousey), (self.mousex_hover, self.mousey_hover),
- self.developerMode)
- aaToggle = self.drawToggle('Anti-aliasing', (math.ceil(0.2 * self.screenW), 200), (self.mousex,
- self.mousey),
- (self.mousex_hover, self.mousey_hover), self.antialiasing)
- sFPSToggle = self.drawToggle('Stabilize Framerate', (math.ceil(0.55 * self.screenW), 150),
- (self.mousex, self.mousey), (self.mousex_hover, self.mousey_hover),
- self.stableFPS)
- decorationToggle = self.drawToggle('Visual Details', (math.ceil(0.55 * self.screenW), 200),
- (self.mousex, self.mousey), (self.mousex_hover, self.mousey_hover),
- self.decorations)
- musicToggle = self.drawToggle('Game Music', (math.ceil(0.2 * self.screenW), 250),
- (self.mousex, self.mousey),
- (self.mousex_hover, self.mousey_hover), self.doPlayMusic)
- fullscrToggle = self.drawToggle('Fullscreen', (math.ceil(0.55 * self.screenW), 250),
- (self.mousex, self.mousey),
- (self.mousex_hover, self.mousey_hover), self.fullscreen)
-
- # Draw volume slider
- self.volume = self.drawSlider('Music Volume', [math.ceil(0.2 * self.screenW), 300],
- self.volume, 1.0, self.doPlayMusic)
-
- # Draw resolution panel
- self.printText('Display Resolution:', self.medFont, white, [0.2 * self.screenW, 350])
- self.currentResolution = self.drawSelectionPanel([0.2 * self.screenW, 400], self.currentResolution,
- *self.resDict.keys())
- if self.screenH != int(self.resDict[self.currentResolution][1]):
- self.screenW, self.screenH = self.resDict[self.currentResolution]
- self.refreshDisplay()
- self.reinit()
-
- # Update game vars with the values from the toggles
- if devModeToggle != self.defaultValue:
- self.developerMode = devModeToggle
- if aaToggle != self.defaultValue:
- self.antialiasing = aaToggle
- if sFPSToggle != self.defaultValue:
- self.stableFPS = sFPSToggle
- if decorationToggle != self.defaultValue:
- self.decorations = decorationToggle
- if musicToggle != self.defaultValue:
- self.doPlayMusic = musicToggle
- # Set volume as necessary
- if self.doPlayMusic and self.volume == 0.0:
- self.volume = 1.0
- elif not self.doPlayMusic:
- self.volume = 0.0
- if fullscrToggle != self.defaultValue:
- self.fullscreen = fullscrToggle
- self.updateDisplayState()
- self.reinit()
-
- # Update volume
- pygame.mixer.music.set_volume(self.volume)
-
- # Draw quit button
- if self.drawButton('Return to Menu', [self.screenW // 2, self.screenH - 100]):
- self.saveGameSettings()
- break
-
- # Update display
- self.redrawAndProceedTick(self.mousex_hover, self.mousey_hover)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def getMousePos(self):
- self.clicking = False
- for event in pygame.event.get():
- if event.type == MOUSEBUTTONDOWN:
- self.mousex, self.mousey = event.pos
- self.clicking = True
- elif event.type == MOUSEMOTION:
- self.mousex, self.mousey = event.pos
- self.mousex_hover, self.mousey_hover = event.pos
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def leftmostPlatform(platforms):
- result = platforms[0]
- for platform in platforms:
- if platform.x <= result.x:
- result = platform
- return result
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def rightmostPlatform(platforms):
- result = platforms[0]
- for platform in platforms:
- if platform.x >= result.x:
- result = platform
- return result
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawChevron(self, x, y, targetX, targetY, thickness=6):
- # Create a new surface object with the size of the chevron
- length = 20
- height = 40
- colour = black
- chevronsurf = pygame.Surface([2 * length, height], SRCALPHA)
- # Draw two lines representing a chevron arrow
- if self.antialiasing:
- pygame.draw.aaline(chevronsurf, colour, [0, height], [length, 0])
- pygame.draw.aaline(chevronsurf, colour, [length, 0], [2 * length, height])
- else:
- pygame.draw.line(chevronsurf, colour, [0, height], [length, 0], thickness)
- pygame.draw.line(chevronsurf, colour, [length, 0], [2 * length, height], thickness)
- # Start the chevron facing the positive x-axis
- chevronsurf = pygame.transform.rotate(chevronsurf, -90)
- # Determine the angle the chevron needs to be
- angle = self.getAngle([targetX, y], [x, targetY]) - 180
- chevronsurf = pygame.transform.rotate(chevronsurf, angle)
- # Blit the chevron
- self.displaysurf.blit(chevronsurf, [x, y])
-
- # --------------------------------------------------------------------------------------------------------------
-
- def launchLevelEditor(self, theme='stone'):
- # Initialize editor variables
- movableObjects = []
- currentItem = 'Left platform'
- currentState = 'Platforms'
-
- # Platform variables
- numPlatforms = 25
- platformDataSize = 3
- currentPlatformIndex = 0
- platforms = []
- platformCoords = [[self.defaultValue] * platformDataSize for x in xrange(numPlatforms)]
- platformSample = Platform(self.defaultValue, self.defaultValue, 0, 0, 0, theme)
-
- # Block variables
- blockSample = Block(self.defaultValue, self.defaultValue, 'coin')
- numBlocks = 25
- blockDataSize = 3
- currentBlockIndex = 0
- blocks = []
- blockCoords = [[self.defaultValue] * blockDataSize for x in xrange(numBlocks)]
- key = Key(self.defaultValue, self.defaultValue, 'blue')
- coinID = 0
- mysteryID = 1
-
- # Pool variables
- poolDefWidth = 490
- poolDefHeight = 180
- poolSample = Pool(self.defaultValue, self.defaultValue, poolDefWidth, poolDefHeight, theme)
- poolSurf = pygame.Surface([0, 0], SRCALPHA)
- poolSample.draw(poolSurf)
- poolDataSize = 4
- poolCoords = [self.defaultValue] * poolDataSize
- pool = None
-
- # Design constants
- selPanelCoords = [self.screenW - 225, 30]
-
- while True:
- # Draw background
- self.activeBackground.update(self.displaysurf)
-
- # Get mouse position and state
- self.checkForQuit()
- self.getMousePos()
-
- # Define the current item using the current state
- if currentState != 'Platforms' and currentState != 'Pool':
- currentItem = currentState.lower()
- elif currentItem != 'Right platform' and currentState == 'Platforms':
- currentItem = 'Left platform'
- elif currentItem != 'Right pool edge' and currentState == 'Pool':
- currentItem = 'Left pool edge'
-
- # Allow horizontal motion
- keys = pygame.key.get_pressed()
- movementSpeed = 10
- if keys[k.RIGHT] or keys[k.RIGHT2]:
- self.activeBackground.x -= movementSpeed
- self.activeBackground.invertedX -= movementSpeed
- if movableObjects:
- for obj in movableObjects:
- obj.x -= movementSpeed
- elif keys[k.LEFT] or keys[k.LEFT2]:
- self.activeBackground.x += movementSpeed
- self.activeBackground.invertedX += movementSpeed
- if movableObjects:
- for obj in movableObjects:
- obj.x += movementSpeed
-
- # Allow vertical motion
- if keys[k.ACTION]:
- if movableObjects:
- for obj in movableObjects:
- obj.y += movementSpeed
- elif keys[k.DUCK] or keys[k.DUCK2]:
- if movableObjects:
- for obj in movableObjects:
- obj.y -= movementSpeed
-
- # Draw platforms
- for platform in platforms:
- platform.draw(self.displaysurf)
-
- # Draw pool
- if pool:
- pool.draw(self.displaysurf)
-
- # Draw blocks
- for block in blocks:
- block.draw([key], self.displaysurf)
-
- # Prevent excessive platforms or blocks
- if currentItem == 'Left platform' and currentPlatformIndex >= numPlatforms:
- currentItem = 'coin block'
- if (currentItem == 'coin block' or currentItem == 'mystery block') and currentBlockIndex >= numBlocks:
- currentItem = 'pool'
-
- # Display the current item next to the cursor and allow placement of any item
- mouseOnScreen = self.mousex < selPanelCoords[0]
- if currentItem == 'Left platform' and mouseOnScreen:
- self.displaysurf.blit(platformSample.leftImage, (self.mousex_hover - platformSample.tileWidth,
- self.mousey_hover - platformSample.tileWidth))
- if self.clicking:
- platformCoords[currentPlatformIndex][0] = self.mousex_hover - platformSample.tileWidth
- platformCoords[currentPlatformIndex][2] = self.mousey_hover - platformSample.tileWidth
- currentItem = 'Right platform'
- elif currentItem == 'Right platform' and mouseOnScreen:
- self.displaysurf.blit(platformSample.rightImage, (self.mousex_hover - platformSample.tileWidth,
- self.mousey_hover - platformSample.tileWidth))
- self.displaysurf.blit(platformSample.leftImage, (platformCoords[currentPlatformIndex][0],
- platformCoords[currentPlatformIndex][2]))
- for x in xrange(platformCoords[currentPlatformIndex][0] + platformSample.tileWidth, self.mousex_hover -
- 2 * platformSample.tileWidth, platformSample.tileWidth):
- self.displaysurf.blit(platformSample.image, (x, platformCoords[currentPlatformIndex][2]))
- if self.clicking:
- platformCoords[currentPlatformIndex][1] = self.mousex_hover - platformSample.tileWidth
- platform = Platform(platformCoords[currentPlatformIndex][0],
- platformCoords[currentPlatformIndex][2], 0, 0,
- platformCoords[currentPlatformIndex][1] -
- platformCoords[currentPlatformIndex][0], theme)
- platforms.append(platform)
- movableObjects.append(platform)
- currentItem = 'Left platform'
- currentPlatformIndex += 1
- elif currentItem == 'coin block' and mouseOnScreen:
- self.displaysurf.blit(blockSample.coinBlockImage, (self.mousex_hover - blockSample.width,
- self.mousey_hover - blockSample.width))
- if self.clicking:
- blockCoords[currentBlockIndex][0] = self.mousex_hover - blockSample.width
- blockCoords[currentBlockIndex][1] = self.mousey_hover - blockSample.width
- blockCoords[currentBlockIndex][2] = coinID
- block = Block(blockCoords[currentBlockIndex][0], blockCoords[currentBlockIndex][1], 'coin')
- blocks.append(block)
- movableObjects.append(block)
- currentBlockIndex += 1
- elif currentItem == 'mystery block' and mouseOnScreen:
- self.displaysurf.blit(blockSample.regularImage, (self.mousex_hover - blockSample.width,
- self.mousey_hover - blockSample.width))
- if self.clicking:
- blockCoords[currentBlockIndex][0] = self.mousex_hover - blockSample.width
- blockCoords[currentBlockIndex][1] = self.mousey_hover - blockSample.width
- blockCoords[currentBlockIndex][2] = mysteryID
- block = Block(blockCoords[currentBlockIndex][0], blockCoords[currentBlockIndex][1], 'regular')
- blocks.append(block)
- movableObjects.append(block)
- currentBlockIndex += 1
- elif currentItem == 'Left pool edge' and mouseOnScreen:
- poolSample = Pool(self.mousex_hover - poolSample.width, self.mousey_hover - poolSample.height,
- poolDefWidth, poolDefHeight, theme)
- poolSample.draw(self.displaysurf)
- if self.clicking:
- poolCoords[0] = self.mousex_hover - poolSample.width
- poolCoords[1] = self.mousey_hover - poolSample.height
- currentItem = 'Right pool edge'
- elif currentItem == 'Right pool edge' and mouseOnScreen:
- pool = Pool(poolCoords[0], poolCoords[1], self.mousex_hover - poolCoords[0],
- self.mousey_hover - poolCoords[1], theme)
- pool.draw(self.displaysurf)
- if self.clicking:
- poolCoords[2] = self.mousex_hover - poolCoords[0]
- poolCoords[3] = self.mousey_hover - poolCoords[1]
- movableObjects.append(pool)
- currentState = 'Platforms'
- elif currentItem == 'save and quit' and platforms:
- self.platforms = platforms
- self.blocks = blocks
- self.pool = pool
- self.door = Door(self.rightmostPlatform(self.platforms)[2] - 70,
- self.rightmostPlatform(self.platforms)[1])
- self.fakedoor = Door(self.leftmostPlatform(platforms)[0] + 70, self.leftmostPlatform(platforms)[1])
- self.saveLevel('custom')
- self.seed = 0
- return 1
- elif currentItem == 'save and quit':
- currentState = 'Platforms'
-
- # Check for quit
- if keys[k.EXIT2]:
- return 0
-
- # Print instructions
- self.printText('Left-click to place item, Q to exit without saving', self.medFont, white, (50, 50))
- self.printText('Platforms remaining: ' + str(numPlatforms - currentPlatformIndex),
- self.medFont, white, (50, 100))
- self.printText('Blocks remaining: ' + str(numBlocks - currentBlockIndex), self.medFont, white, (50, 150))
-
- # Draw chevron
- if platforms and (platforms[0][0] not in range(0, self.screenW) or
- platforms[0][1] not in range(0, self.screenH)):
- self.drawChevron(self.screenW // 2, 50, platforms[0].x, platforms[0].y)
-
- # Draw right section separator
- if self.antialiasing:
- pygame.draw.aaline(self.displaysurf, black, [selPanelCoords[0], 0], [selPanelCoords[0],
- self.screenH])
- else:
- pygame.draw.line(self.displaysurf, black, [selPanelCoords[0], 0], [selPanelCoords[0], self.screenH])
-
- # Allow the user to select which mode they want to be in
- currentState = self.drawSelectionPanel([selPanelCoords[0] + 25, selPanelCoords[1]], currentState,
- 'Platforms', 'Coin Block', 'Mystery Block', 'Pool', 'SAVE AND QUIT')
-
- self.redrawAndProceedTick(self.mousex, self.mousey)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def initializeLevel(self):
- self.textTimers = [0] * 10
- self.mobs, self.allMovableObjects, self.enemies, self.icicles, self.platforms = [], [], [], [], []
- self.blocks, self.keys, self.torches = [], [], []
- self.pool = None
- if not type(self.mainChar) is PlayableCharacter:
- self.mainChar = PlayableCharacter(int(0.5 * self.screenW), int(0.5 * self.screenH))
- self.mainChar.longestPlatform = None
- self.mainChar.respawnPoint = None
- self.mousex_hover, self.mousey_hover = self.defaultValue, self.defaultValue
- self.mainChar.hasKey, self.autoscroll = False, False
- self.measuredFPS, self.fps = self.desiredFPS, self.desiredFPS
-
- # --------------------------------------------------------------------------------------------------------------
-
- def finalizeBlocks(self):
- for block in self.blocks:
- if block.form == 'regular' and not self.keys and not block.yieldsStar:
- key = Key(block[0][0], block[0][1] - 80, 'blue')
- self.keys.append(key)
- self.allMovableObjects.append(key)
- elif block.form == 'regular' and r.randint(0, 2) == 0:
- block.willExplode = True
- elif block.form == 'regular':
- block.yieldsStar = True
- self.allMovableObjects.append(block)
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def illuminate(targetSurf, x, y):
- x, y = int(x), int(y)
- rad = r.randint(215, 245)
- transp = 255
- delta = 3
- clr = 0
- defclr = 0
- while rad > 50:
- pygame.draw.circle(targetSurf, (clr, clr, defclr, transp), (x, y), rad)
- rad -= delta; transp -= delta; clr += delta
- pygame.draw.circle(targetSurf, (clr, clr, defclr, transp), (x, y), rad)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def darken(self, surface, value):
- dark = pygame.Surface(surface.get_size(), 32)
- dark.set_alpha(value, pygame.RLEACCEL)
- for torch in self.torches:
- if torch.burning:
- self.illuminate(dark, torch.x + 0.5 * torch.width, torch.y + 5)
- surface.blit(dark, (0, 0))
-
- # --------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def interpretHintString(hint):
- try:
- hint = str(hint)
- except TypeError:
- return ''
- if hint == 'None':
- return ''
- openingBrace = '{'
- closingBrace = '}'
- if not openingBrace in hint:
- return hint
- keymap = k.SUMMARY
- startSlice = 0
- endSlice = 0
- for letterIndex in range(len(hint)):
- if hint[letterIndex] == openingBrace:
- startSlice = letterIndex + 1
- for letterIndex in range(startSlice, len(hint)):
- if hint[letterIndex] == closingBrace:
- endSlice = letterIndex
- return hint[:startSlice - 1] + '"' + pygame.key.name(keymap[hint[startSlice:endSlice]]) + '"' + \
- hint[endSlice + 1:]
-
- # --------------------------------------------------------------------------------------------------------------
-
- def isPlatformCollision(self, obj):
- try:
- testrect = obj.getRect()
- except AttributeError:
- testrect = pygame.Surface.get_rect(obj.image)
- for platform in self.platforms:
- platrect = platform.getRect()
- if testrect.colliderect(platrect):
- return True
- return False
-
- # --------------------------------------------------------------------------------------------------------------
-
- def generateMobs(self, longestPlatform, farthestPlatform):
- quantityMobs = len(self.platforms) - 1
- mainMobType = 'slime'
- sampleMob = AICharacter(0, 0, 0, 0, (mainMobType, -1, -1))
- self.mobs = []
- for i in range(0, quantityMobs):
- whichPlatform = r.randint(1, len(self.platforms) - 1)
- while self.platforms[whichPlatform][0] == longestPlatform[0]:
- whichPlatform = r.randint(1, len(self.platforms) - 1)
- if r.randint(0, 1) == 0:
- self.mobs.append(AICharacter(r.randint(self.platforms[whichPlatform][0],
- self.platforms[whichPlatform][2]),
- self.platforms[whichPlatform][3] - sampleMob.height,
- int(0.7 * self.mainChar.runSpeed), 0, (mainMobType, -1, -1)))
- else:
- self.mobs.append(AICharacter(r.randint(self.platforms[whichPlatform][0],
- self.platforms[whichPlatform][2]),
- self.platforms[whichPlatform][3] - sampleMob.height,
- int(0.7 * self.mainChar.runSpeed), 0, ('snail', -1, -1)))
- self.mobs.append(AICharacter(70, self.platforms[0][1] - 750, 5, 0, ('fly', self.platforms[0][0],
- farthestPlatform[2])))
- if self.pool:
- self.mobs.append(AICharacter(self.pool.poolStartX + self.pool.tileWidth, self.pool.y +
- self.pool.tileWidth, 5, 0, ('fish', -1, -1)))
- self.enemies.extend(self.mobs)
- self.allMovableObjects.extend(self.mobs)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def generateFences(self):
- sampleFence = Checkpoint(self.defaultValue, self.defaultValue)
- self.fences = []
- for platformIndex in xrange(1, len(self.platforms), 5):
- if self.platforms[platformIndex].width >= 2 * sampleFence.width and not self.autoscroll:
- fenceX = self.platforms[platformIndex][0] + 20
- fenceY = self.platforms[platformIndex][1] - sampleFence.height
- self.fences.append(Checkpoint(fenceX, fenceY))
- self.allMovableObjects.extend(self.fences)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def generateFoliage(self):
- self.foliage = []
- for platform in self.platforms:
- for x in xrange(int(platform.x), int(platform.x + platform.width - 100), 100):
- if r.randint(0, 10) == 0 and self.decorations:
- decoration = BackgroundFoliage(x, platform.y)
- decoration.y -= decoration.height
- self.allMovableObjects.append(decoration)
- self.foliage.append(decoration)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def generateTorches(self):
- if not self.levelDark:
- return
- for block in self.blocks:
- newTorch = Torch(block.x, block.y - self.firstChar.height - 25)
- if not self.isPlatformCollision(newTorch) and newTorch.x <= self.farthestPlatform[2]:
- self.torches.append(newTorch)
- maxDistBwTorches = 490
- for torch1 in self.torches:
- for torch2 in self.torches:
- if self.distance([torch1.x, torch1.y], [torch2.x, torch2.y]) < maxDistBwTorches:
- self.torches.remove(torch2)
- self.allMovableObjects.extend(self.torches)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def finalizeLevel(self, farthestPlatform):
- for key in self.keys:
- key.visible = False
- if not self.keys or self.autoscroll:
- key = Key(int(0.5 * (farthestPlatform[0] + farthestPlatform[2])), farthestPlatform[1] - 80, 'blue')
- key.visible = True
- self.keys.append(key)
- self.allMovableObjects.append(key)
- self.mainChar.x = self.platforms[0][0] + 20
- self.mainChar.y = self.platforms[0][1] - self.mainChar.height
- self.mainChar.Vx = 5
- self.mainChar.cpuControlled = True
- for c in [self.mainChar] + self.mobs:
- c.platformInit(self.platforms)
- self.mainChar.setMapObjX(self.enemies, self.allMovableObjects, self.platforms, self.screenW - 100)
- self.allMovableObjects.append(self.activeBackground)
- self.decideDark()
- self.generateTorches()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def decideDark(self):
- self.levelDark = False
- if (r.randint(0, 2) == 0 and self.currLevel > 2) or self.currLevel == 2:
- self.levelDark = True
-
- # --------------------------------------------------------------------------------------------------------------
-
- def gatherPlatformInfo(self):
- self.topmostPlatform, self.lowestPlatform, self.shortestPlatform, self.longestPlatform, \
- self.farthestPlatform = self.platforms[1], self.platforms[1], self.platforms[1], \
- self.platforms[1], self.platforms[1]
- for platform in self.platforms:
- if platform[1] < self.topmostPlatform[1]:
- self.topmostPlatform = platform
- if platform[1] > self.lowestPlatform[1]:
- self.lowestPlatform = platform
- if platform.width > self.longestPlatform.width and platform[0] != self.platforms[0][0]:
- self.longestPlatform = platform
- if platform[2] - platform[0] < self.shortestPlatform[2] - self.shortestPlatform[0]:
- self.shortestPlatform = platform
- if platform[2] > self.farthestPlatform[2]:
- self.farthestPlatform = platform
-
- # --------------------------------------------------------------------------------------------------------------
-
- def generateRandomLevel(self, theme, numberofplatforms, lvl, levelSeed=None):
-
- # Step 0: Clear all data from the previous level and initialize the random number generator
- self.initializeLevel()
- r.seed(levelSeed)
-
- # Step 1: Generate the necessary number of platforms using an iterative strategy
- firstPlatform = Platform(r.randint(-300, 500), r.randint(self.screenH - 200, self.screenH - 50),
- 0, 0, r.randint(800, 1500), theme)
- overlap = True
- attempts = 3 * numberofplatforms # Reduce number of attempts for slower computers
- maxHeightDifference = self.mainChar.maxJumpHeight - 10
- maxWidthDifference = self.mainChar.maxJumpLength * 2
- while overlap and attempts >= 0:
- overlap = False
- attempts -= 1
- self.platforms = [firstPlatform]
- for i in range(1, numberofplatforms):
- randomDirection = [1, r.randint(0, 1)]
- platformWidth = r.randint(400, 2000)
- prevPlatform = self.platforms[i - 1]
- if randomDirection[0] == 0 and randomDirection[1] == 0:
- platformRight = prevPlatform[0] - r.randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformLeft = platformRight - platformWidth
- platformTop = prevPlatform[1] + r.randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- elif randomDirection[0] == 0 and randomDirection[1] == 1:
- platformRight = prevPlatform[0] - r.randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformLeft = platformRight - platformWidth
- platformTop = prevPlatform[1] - r.randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- elif randomDirection[0] == 1 and randomDirection[1] == 1:
- platformLeft = prevPlatform[2] + r.randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformTop = prevPlatform[1] - r.randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- else:
- platformLeft = prevPlatform[2] + r.randint(int(1.2 * self.mainChar.width), maxWidthDifference)
- platformTop = prevPlatform[1] + r.randint(int(0.5 * maxHeightDifference), int(0.4 * self.screenH))
- self.platforms.append(Platform(platformLeft, platformTop, 0, 0, platformWidth, theme))
- overlap = self.isPlatformCollision(self.platforms[i])
- for platform in self.platforms:
- self.allMovableObjects.append(platform)
-
- # Step 2: Gather platform info
- self.gatherPlatformInfo()
- focusHeight = self.longestPlatform[1] - 324
-
- # Step 3: Generate rare pool platform
- self.pool = None
- if r.randint(0, 2) == 0 or self.currLevel <= 1:
- poolX = self.farthestPlatform[2] + int(0.9 * self.mainChar.maxJumpLength)
- poolY = self.farthestPlatform[1]
- poolWidth = r.randint(700, 900)
- poolHeight = 4 * self.mainChar.height
- self.pool = Pool(poolX, poolY, poolWidth, poolHeight, theme)
- self.allMovableObjects.append(self.pool)
- elif r.randint(0, 1) == 0:
- self.autoscroll = True
-
- # Step 4: Generate blocks
- quantityBlocks = numberofplatforms
- sampleBlock = Block(0, 0, 'bonus')
- blockHeight = math.floor(1.3 * self.mainChar.height + sampleBlock.height)
- self.blocks = [Block(r.randint(self.platforms[0][0] + 50, self.platforms[0][2] - 50),
- self.platforms[0][1] - blockHeight, 'coin')]
- blockplatform = [0]
- self.keys = []
- for i in range(1, quantityBlocks):
- y = self.platforms[i][1] - blockHeight
- if self.platforms[i].x != self.longestPlatform.x and r.randint(0, 3) != 0:
- x = 0.5 * self.platforms[i][0] + 0.5 * self.platforms[i][2] + r.randint\
- (int(-0.4 * self.platforms[i].width), int(0.4 * self.platforms[i].width))
- self.blocks.append(Block(x, y, 'coin'))
- blockplatform.append(i)
- elif self.platforms[i].x != self.longestPlatform.x and not self.keys:
- x = 0.5 * self.platforms[i][0] + 0.5 * self.platforms[i][2] + \
- r.randint(int(-0.4 * self.platforms[i].width), int(0.4 * self.platforms[i].width))
- self.blocks.append(Block(x, y, 'regular'))
- blockplatform.append(i)
- # Check for block-platform collisions
- for block in self.blocks:
- blockRect = block.getRect()
- for platform in self.platforms:
- platformRect = platform.getRect()
- if blockRect.colliderect(platformRect):
- block.x += 550
- # Add a block to the pool platform if present
- if self.pool:
- poolBlock = Block(self.pool.poolStartX + self.pool.tileWidth,
- self.pool.y + self.pool.height - blockHeight, 'regular')
- poolBlock.yieldsStar = True
- poolBlock.willExplode = False
- self.blocks.append(poolBlock)
- r.shuffle(self.blocks)
- # Add all blocks to the movable objects list
- self.finalizeBlocks()
-
- # Step 5: Generate icicles if necessary by first creating a platform to use as a ledge
- self.icicles = []
- shouldCreateLedge = self.longestPlatform.y != self.platforms[0].y and (lvl == 1 or r.randint(0, 1) == 0)
- if shouldCreateLedge:
- ledge = Platform(self.longestPlatform[0], focusHeight, 0, 0, self.longestPlatform.width, 'snow')
- # Move the ledge out of the visible area if it overlaps with another platform
- for platform in self.platforms:
- if platform.getRect().colliderect(ledge.getRect()):
- ledge.x, ledge.y = self.defaultValue, self.defaultValue
- self.platforms.append(ledge), self.allMovableObjects.append(ledge)
- for i in range(ledge[0] + ledge.tileWidth * 2, ledge[2] - ledge.tileWidth * 2, 40):
- self.icicles.append(FallingSpike(i, ledge[3]))
- self.allMovableObjects.extend(self.icicles)
-
- # Step 6: Add foliage to enhance the atmosphere
- self.generateFoliage()
-
- # Step 7: Generate mobs
- self.generateMobs(self.longestPlatform, self.farthestPlatform)
-
- # Step 8: Place a door
- doorX = self.farthestPlatform[2] - 100
- doorY = self.farthestPlatform[1]
- self.door = Door(doorX, doorY)
- self.allMovableObjects.append(self.door)
- self.fakedoor = Door(self.platforms[0].x + 10, self.platforms[0].y)
- self.allMovableObjects.append(self.fakedoor)
-
- # Step 9: Place fences as respawn points
- self.generateFences()
-
- # Step 10: Finalize level details and set player and camera position
- self.loadLevelHint(lvl)
- self.finalizeLevel(self.farthestPlatform)
-
- # Step 11: Save level to disk
- self.saveLevel(lvl)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def setupBgrd(self, environment):
- if environment == 'gloomy':
- self.bgrd = self.bgrdGloomy
- elif environment == 'yellow':
- self.bgrd = self.bgrdYellowSky
- elif environment == 'castle':
- self.bgrd = self.bgrdCastle
- elif environment == 'desert':
- self.bgrd = self.bgrdDesert
- self.activeBackground = Background(self.bgrd, self.screenW, self.screenH)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawButton(self, text, coords, center=True):
- btnRect = self.printText(text, self.genericFont, white, coords, center)
- if btnRect.collidepoint(self.mousex, self.mousey) and self.clicking:
- return True
- if btnRect.collidepoint(self.mousex_hover, self.mousey_hover):
- self.printText(text, self.genericFont, yellow, coords, center)
- return False
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawSelectionPanel(self, topLeftCoords, currentlySelected, *args):
- for index in range(len(args)):
- buttonRect = self.printText(args[index], self.medFont, white, (topLeftCoords[0], topLeftCoords[1] +
- 60 * index))
- hovering = buttonRect.collidepoint(self.mousex_hover, self.mousey_hover)
- clickingThis = pygame.mouse.get_pressed()[0] and buttonRect.collidepoint(self.mousex, self.mousey)
- selected = args[index] == currentlySelected
- if hovering or clickingThis or selected:
- self.printText(args[index], self.medFont, yellow, (topLeftCoords[0], topLeftCoords[1] + 60 * index))
- if clickingThis:
- currentlySelected = args[index]
- return currentlySelected
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawTitleScreen(self):
- whichChar = 0
-
- # Check for quit events
- self.checkForQuit()
- self.getMousePos()
-
- # Fill screen with background
- self.displaysurf.blit(self.bgrdTitle, self.origin)
-
- # Print static text
- self.printText('Stranded in a monster-infested space centre on the moon HYPERION. One goal: Find an exit.',
- self.medFont, white, (self.screenW // 2, 120), True)
- self.printText('Welcome to Exit Dash: Hyperion!', self.genericFont, white, (self.screenW // 2, 50), True)
- self.printText('Choose a character to begin:', self.genericFont, white, (self.screenW // 2, 250), True)
-
- # Draw three characters to choose from
- firstCharRect = pygame.Rect(self.firstChar.x, self.firstChar.y, self.firstChar.width, self.firstChar.height)
- secondCharRect = pygame.Rect(self.secondChar.x, self.secondChar.y, self.secondChar.width,
- self.secondChar.height)
- thirdCharRect = pygame.Rect(self.thirdChar.x, self.thirdChar.y, self.thirdChar.width, self.thirdChar.height)
- self.displaysurf.blit(self.firstChar.standingImage, (self.firstCharX, self.charY))
- self.displaysurf.blit(self.secondChar.standingImage, (self.secondCharX, self.charY))
- self.displaysurf.blit(self.thirdChar.standingImage, (self.thirdCharX, self.charY))
- if firstCharRect.collidepoint(self.mousex_hover, self.mousey_hover):
- pygame.draw.rect(self.displaysurf, white, firstCharRect, 3)
- self.printText('Flight Commander ALEX', self.medFont, yellow, (self.firstCharX - 95, self.charY +
- self.firstChar.height + 15))
- else:
- self.printText('Flight Commander ALEX', self.medFont, white, (self.firstCharX - 95, self.charY +
- self.firstChar.height + 15))
- if secondCharRect.collidepoint(self.mousex_hover, self.mousey_hover):
- pygame.draw.rect(self.displaysurf, white, secondCharRect, 3)
- self.printText('Astronaut ALLAN', self.medFont, yellow, (self.secondCharX - 70,
- self.charY + self.secondChar.height + 15))
- else:
- self.printText('Astronaut ALLAN', self.medFont, white, (self.secondCharX - 70,
- self.charY + self.secondChar.height + 15))
- if thirdCharRect.collidepoint(self.mousex_hover, self.mousey_hover):
- pygame.draw.rect(self.displaysurf, white, thirdCharRect, 3)
- self.printText('Medical Specialist LISA', self.medFont, yellow, (self.thirdCharX - 95,
- self.charY + self.thirdChar.height + 15))
- else:
- self.printText('Medical Specialist LISA', self.medFont, white, (self.thirdCharX - 95,
- self.charY + self.thirdChar.height + 15))
- firstCharacterChosen = firstCharRect.collidepoint(self.mousex, self.mousey) and self.clicking
- secondCharacterChosen = secondCharRect.collidepoint(self.mousex, self.mousey) and self.clicking
- thirdCharacterChosen = thirdCharRect.collidepoint(self.mousex, self.mousey) and self.clicking
- if firstCharacterChosen:
- whichChar = 1
- elif secondCharacterChosen:
- whichChar = 2
- elif thirdCharacterChosen:
- whichChar = 3
-
- # Draw quit button
- if self.drawButton('Exit', [self.screenW // 2, self.screenH - 50]):
- self.quitGame()
-
- # Draw editor button
- if self.drawButton('Editor', [self.screenW // 2, self.screenH - 230]):
- self.editorResult = self.launchLevelEditor()
- if self.editorResult:
- self.printText('Level saved to levels'+os.sep+'lvl_custom' + self.levelExtension +
- '. Change name to lvl_{desiredLevelNum}' + self.levelExtension + 'to replace existing level',
- self.smoothFont, white, [20, self.screenH - 25])
-
- # Draw settings button
- if self.drawButton('Options', [self.screenW // 2, self.screenH - 140]):
- self.editorResult = False
- self.drawOptionsMenu()
-
- # Enter game if a character is chosen
- if firstCharacterChosen or secondCharacterChosen or thirdCharacterChosen:
- self.mainChar = PlayableCharacter(0, 0, 0, 0, whichChar)
- self.currLevel = 1
- self.seed = pygame.time.get_ticks() % 1000000
- if self.overwriteLevels:
- self.generateRandomLevel('stone', 10, 1, self.seed)
- else:
- self.loadLevel(self.currLevel, self.theme)
- pygame.mixer.music.load(self.mainMusic)
- pygame.mixer.music.set_volume(self.volume)
- pygame.mixer.music.play(-1)
-
- self.redrawAndProceedTick(self.mousex_hover, self.mousey_hover, True)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def updateAll(self):
-
- # Draw background
- self.activeBackground.update(self.displaysurf)
-
- # Draw prop door
- self.fakedoor.update(self.mainChar, self.displaysurf, False)
-
- # Let player control the main character when ready
- if self.mainChar.x >= self.platforms[0][0] + 0.5 * self.platforms[0].width:
- self.mainChar.Vx = 0
- self.mainChar.cpuControlled = False
-
- # Handle events
- events = pygame.event.get()
-
- # Get recent key presses
- self.getRecentKeys(events)
-
- # Blit and update all objects
- result = self.door.update(self.mainChar, self.displaysurf)
- if self.pool:
- self.pool.update(self.displaysurf)
- if self.fences:
- for fence in self.fences:
- fence.draw(self.displaysurf)
- for f in self.foliage:
- f.draw(self.displaysurf)
- for torch in self.torches:
- torch.draw(self.displaysurf)
- for i in range(0, len(self.platforms)):
- self.platforms[i].update((0, 0, self.screenW, self.screenH), self.displaysurf)
- for i in range(0, len(self.blocks)):
- self.blocks[i].update(self.keys, self.displaysurf)
- for enemy in self.enemies:
- enemy.update(self.platforms, events, self.allMovableObjects, self.blocks, self.enemies,
- self.mainChar, self.pool, self.displaysurf,
- self.measuredFPS)
- for spike in self.icicles:
- spike.update(self.platforms, [self.mainChar], self.blocks, self.displaysurf)
- if not self.mainChar.update(self.platforms, events, self.allMovableObjects, self.blocks,
- self.enemies, self.mainChar, self.pool, self.displaysurf,
- self.screenW, self.screenH, int(self.measuredFPS), self.autoscroll, self.fences,
- self.torches):
- self.showGameOverScreen(False)
- for key in self.keys:
- key.update(self.mainChar, self.displaysurf)
-
- # Give the player a multi-kill bonus
- if self.mainChar.mobJumping and self.allowKillBonus:
- self.allowKillBonus = False
- self.mainChar.coins += 2
- self.receivingKillBonus = True
- elif not self.mainChar.mobJumping:
- self.allowKillBonus = True
- if self.receivingKillBonus:
- self.receivingKillBonus = self.drawTempText('Kill Bonus! +2 Coins',
- self.medFont, white, (self.screenW / 2 - 50, 50), 4000, 1, events)
-
- # Draw level numer and hint
- self.drawTempText('Level ' + str(self.currLevel), self.medFont, white, (self.screenW - 150, 50),
- 15000, 0, events)
- self.drawTempText(self.levelHint, self.smlFont, white, (250, 200), 13000, 3, events)
-
- # Check for quit events
- self.checkForQuit()
-
- # Display developer mode info
- if self.developerMode:
- videoInfo = pygame.display.Info()
- hardwareAccel = 'True' if videoInfo.hw else 'False'
- vram = str(videoInfo.video_mem) if videoInfo.video_mem != 0 else 'Unknown'
-
- self.printText('x = ' + str(round(self.mainChar.x, 2)), self.smoothFont, white, (self.devInfoX,
- self.devInfoY))
- self.printText('y = ' + str(round(self.mainChar.y, 2)), self.smoothFont, white,
- (self.devInfoX, self.devInfoY + self.devSpacing))
- self.printText('dx = ' + str(round(self.mainChar.Vx, 2)), self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 2 * self.devSpacing))
- self.printText('dy = ' + str(round(self.mainChar.Vy, 2)), self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 3 * self.devSpacing))
- self.printText('fps = ' + str(round(self.measuredFPS, 2)) +
- (' (stable)' if self.stableFPS else ' (unstable)'),
- self.smoothFont, white, (self.devInfoX, self.devInfoY + 4 * self.devSpacing))
- self.printText('vol = ' + str(100 * round(pygame.mixer.music.get_volume(), 2)) + '%', self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 5 * self.devSpacing))
- self.printText('onground = True' if self.mainChar.onGround else 'onground = False', self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 6 * self.devSpacing))
- self.printText('hw accel = ' + hardwareAccel, self.smoothFont, white, (self.devInfoX, self.devInfoY +
- 7 * self.devSpacing))
- self.printText('vram (MB) = ' + vram, self.smoothFont, white, (self.devInfoX, self.devInfoY + 8 *
- self.devSpacing))
- self.printText('health = ' + str(self.mainChar.health), self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 9 * self.devSpacing))
- self.printText('seed = ' + str(int(self.seed)), self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 10 * self.devSpacing))
- self.printText('dirsize = ' + str(self.totalSize) + ' MB', self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 11 * self.devSpacing))
- self.printText('recent keys = ' + self.recentKeyboardKeys, self.smoothFont, white,
- (self.devInfoX, self.devInfoY + 12 * self.devSpacing))
- self.printText('esc to quit', self.smoothFont, white, (self.devInfoX, self.devInfoY + 13 * self.devSpacing))
-
- # Darken level if necessary
- if self.levelDark:
- self.darken(self.displaysurf, 130)
-
- # Update screen and enforce maximum fps
- self.redrawAndProceedTick(self.mousex_hover, self.mousey_hover)
-
- return result
-
- # --------------------------------------------------------------------------------------------------------------
-
- def loadLevelHint(self, level):
- fileName = 'levels'+os.sep+'lvlhints' + self.levelExtension
- if not os.path.isfile(fileName):
- self.levelHint = self.interpretHintString('None')
- permissions = 'r'
- dataFile = open(fileName, permissions)
- data = []
- for ln in dataFile:
- data.append(ln)
- try:
- self.levelHint = self.interpretHintString(data[level - 1])
- except IndexError:
- self.levelHint = self.interpretHintString('None')
-
- # --------------------------------------------------------------------------------------------------------------
-
- def loadLevel(self, level, theme):
- # Collect information from the level data file
- fileName = 'levels/lvl_' + str(level) + self.levelExtension
- if not os.path.isfile(fileName) or self.overwriteLevels:
- # If the data file does not exist, generate a new random level instead
- self.seed = pygame.time.get_ticks() % 1000000
- self.generateRandomLevel(theme, 5 + 5 * level, level, self.seed)
- return
- permissions = 'r'
- dataFile = open(fileName, permissions)
- uselessWarning = dataFile.readline()
- print uselessWarning
- data = []
- line = 0
- for ln in dataFile:
- try:
- data.append(float(ln))
- except ValueError:
- data.append(ln)
-
- # Clear previous level cache
- self.initializeLevel()
-
- # Set up platforms
- maxNumPlatforms = 25
- platformDataSize = 3
- for i in xrange(line, platformDataSize * (maxNumPlatforms - 1) + 1, platformDataSize):
- if data[i] != self.defaultValue:
- self.platforms.append(Platform(data[i], data[i + 1], 0, 0, data[i + 2], theme))
- line += platformDataSize
- self.allMovableObjects.extend(self.platforms)
- self.gatherPlatformInfo()
-
- # Set up pool platform
- poolDataSize = 4
- if data[line] != self.defaultValue:
- self.pool = Pool(data[line], data[line + 1], data[line + 2], data[line + 3], theme)
- self.allMovableObjects.append(self.pool)
- line += poolDataSize
-
- # Set up bonus blocks
- maxNumBlocks = 25
- blockDataSize = 3
- for i in xrange(line, line + (blockDataSize * (maxNumBlocks - 1) + 1), blockDataSize):
- if data[i] != self.defaultValue and data[i + 2] == 0:
- self.blocks.append(Block(data[i], data[i + 1], 'coin'))
- elif data[i] != self.defaultValue:
- self.blocks.append(Block(data[i], data[i + 1], 'regular'))
- line += blockDataSize
- self.finalizeBlocks()
-
- # Initialize ledge and icicles
- ledgeDataSize = 3
- if data[line] != self.defaultValue:
- ledge = Platform(data[line], data[line + 1], 0, 0, data[line + 2], 'snow')
- self.platforms.append(ledge)
- self.allMovableObjects.append(ledge)
- for i in xrange(int(ledge[0] + ledge.tileWidth * 2), int(ledge[2] - ledge.tileWidth * 2), 40):
- self.icicles.append(FallingSpike(i, ledge[3]))
- self.allMovableObjects.extend(self.icicles)
- line += ledgeDataSize
-
- # Set up random mobs
- self.generateMobs(self.longestPlatform, self.farthestPlatform)
-
- # Place door
- doorDataSize = 2
- self.door = Door(data[line], data[line + 1])
- line += doorDataSize
- self.allMovableObjects.append(self.door)
- self.fakedoor = Door(self.platforms[0][0] + 10, self.platforms[0][1])
- self.allMovableObjects.append(self.fakedoor)
-
- # Generate fences
- if data[line] != 0:
- self.generateFences()
- self.autoscroll = False
- elif r.randint(0, 3) == 0:
- self.autoscroll = True
- line += 1
-
- # Generate foliage
- if data[line] != 0:
- self.generateFoliage()
- line += 1
-
- # Obtain the seed used to generate the saved level
- self.seed = data[line]
-
- # Load the level hint
- self.loadLevelHint(level)
-
- # Finalize the level details
- self.finalizeLevel(self.farthestPlatform)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def saveLevel(self, level):
- # Open file for writing
- fileName = 'levels/lvl_' + str(level) + self.levelExtension
- permissions = 'w'
- dataFile = open(fileName, permissions)
-
- # Add a warning to the data file
- dataFile.write('Position Data For Level ' + str(level) + ' - DO NOT MODIFY THIS FILE!\n')
-
- # Save data in the same order as the "loadLevel" method reads it
- blankLine = str(self.defaultValue) + '\n'
- maxNumPlatforms = 25
- platformDataSize = 3
- for i in xrange(maxNumPlatforms):
- if i < len(self.platforms):
- dataFile.write(str(self.platforms[i].x) + '\n' + str(self.platforms[i].y) + '\n' +
- str(self.platforms[i].width) + '\n')
- else:
- dataFile.write(blankLine * platformDataSize)
- poolDataSize = 4
- if self.pool:
- dataFile.write(str(self.pool.x) + '\n' + str(self.pool.y) + '\n' + str(self.pool.width) +
- '\n' + str(self.pool.height) + '\n')
- else:
- dataFile.write(blankLine * poolDataSize)
- maxNumBlocks = 25
- blockDataSize = 3
- for i in xrange(maxNumBlocks):
- if i < len(self.blocks):
- dataFile.write(str(self.blocks[i].x) + '\n' + str(self.blocks[i].y) + '\n')
- if self.blocks[i].form == 'coin':
- dataFile.write('0\n')
- else:
- dataFile.write('1\n')
- else:
- dataFile.write(blankLine * blockDataSize)
- if self.icicles:
- dataFile.write(str(self.platforms[len(self.platforms) - 1].x) + '\n' +
- str(self.platforms[len(self.platforms) - 1].y) + '\n' +
- str(self.platforms[len(self.platforms) - 1].width) + '\n')
- else:
- dataFile.write(blankLine * 3)
- dataFile.write(str(self.door.x) + '\n' + str(self.door.y + self.door.height + self.door.topBlankSpace) + '\n')
- if self.autoscroll:
- dataFile.write('0\n')
- else:
- dataFile.write('1\n')
- dataFile.write('1\n' + str(self.seed))
-
- # --------------------------------------------------------------------------------------------------------------
-
- def loopThroughLevel(self, lvl=0):
- if lvl == 0:
- self.gameStart = False
- pygame.mixer.music.load(self.themeSong)
- pygame.mixer.music.set_volume(self.volume)
- pygame.mixer.music.play(-1)
- self.setupBgrd(self.backgroundTheme)
- while self.currLevel == 0:
- self.drawTitleScreen()
- else:
- while self.currLevel == lvl:
- shouldAdvanceLevel = self.updateAll()
- if shouldAdvanceLevel:
- self.printText('Loading Level ' + str(self.currLevel + 1), self.medFont, white,
- (50, self.screenH - 50))
- self.currLevel += 1
- self.redrawAndProceedTick(self.mousex_hover, self.mousey_hover)
- pygame.time.wait(self.levelDelay)
- self.loadLevel(self.currLevel, self.theme)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def executeLevels(self, finalLevel=2):
- for level in xrange(finalLevel + 1):
- self.loopThroughLevel(level)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def executeGameLoop(self):
- self.executeLevels(self.numLevels)
diff --git a/data/key.py b/data/key.py
deleted file mode 100644
index 5e5e700..0000000
--- a/data/key.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# coding=utf-8
-from data.game import *
-import os
-
-
-class Key(object):
- def __init__(self, x, y, colour):
- self.x = x
- self.y = y
- self.visible = False
-
- # Load image
- self.image = pygame.image.load('environment'+os.sep+'main'+os.sep+'key' + colour + '.png').convert_alpha()
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, mainChar, surface):
- if self.visible:
- surface.blit(self.image, (self.x, self.y))
- keyRect = pygame.Rect(self.x, self.y, self.width, self.height)
- charRect = pygame.Rect(mainChar.x, mainChar.y, mainChar.width, mainChar.height)
- if keyRect.colliderect(charRect):
- mainChar.hasKey = True
- self.visible = False
diff --git a/data/keymap.py b/data/keymap.py
deleted file mode 100644
index 81cdb2f..0000000
--- a/data/keymap.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# coding=utf-8
-
-from pygame.locals import *
-
-PLACEHOLDER = K_EURO
-
-ACTION = K_UP
-ACTION2 = K_SPACE
-
-LEFT = K_LEFT
-LEFT2 = PLACEHOLDER
-
-RIGHT = K_RIGHT
-RIGHT2 = PLACEHOLDER
-
-DUCK = K_DOWN
-DUCK2 = PLACEHOLDER
-
-EXIT = K_ESCAPE
-EXIT2 = K_q
-
-SUMMARY = {'PLACEHOLDER': PLACEHOLDER, 'ACTION': ACTION, 'ACTION2': ACTION2, 'LEFT': LEFT, 'LEFT2': LEFT2,
- 'RIGHT': RIGHT, 'RIGHT2': RIGHT2, 'DUCK': DUCK, 'DUCK2': DUCK, 'EXIT': EXIT, 'EXIT2': EXIT2}
diff --git a/data/platform.py b/data/platform.py
deleted file mode 100644
index 1202e5e..0000000
--- a/data/platform.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# coding=utf-8
-import pygame
-import os
-
-class Platform(object):
-
- def __init__(self, x, y, Vx, Vy, width, style='grass'):
- self.x = x
- self.y = y
- self.Vx = Vx
- self.Vy = Vy
- self.style = style
- self.width = width
- self.correctReversedCoords()
-
- # Load platform image
- self.image = pygame.image.load('environment'+os.sep+'main'+os.sep+'' + style + 'Mid.png').convert_alpha()
- self.tileWidth = pygame.Surface.get_width(self.image)
- self.width -= self.width % self.tileWidth
- self.height = pygame.Surface.get_height(self.image)
-
- # Load platform edge images
- self.leftImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'' + style + 'CliffLeft.png').convert_alpha()
- self.rightImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'' + style + 'CliffRight.png').convert_alpha()
-
- # Cache the entire platform image to improve FPS
- self.imageCache = pygame.Surface([self.width, self.height], pygame.SRCALPHA)
- self.imageCache.blit(self.leftImage, (0, 0))
- self.imageCache.blit(self.rightImage, (self.width - self.tileWidth, 0))
- for i in range(self.tileWidth, int(self.width - self.tileWidth), self.tileWidth):
- self.imageCache.blit(self.image, (i, 0))
-
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def __getitem__(self, i):
- # This method allows iteration of platform objects
- # From [0] to [3], it returns the left X, top Y,
- # rightX, and bottom Y, respectively
- if i == 0:
- return self.x
- elif i == 1:
- return self.y
- elif i == 2:
- return self.x + self.width
- elif i == 3:
- return self.y + self.height
- else:
- return i
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def __setitem__(self, k, v):
- if k == 0:
- self.x = v
- elif k == 1:
- self.y = v
- elif k == 2:
- self.x = v - self.width
- elif k == 3:
- self.y = v - self.height
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def correctReversedCoords(self):
- if self.width < 0:
- self.x += self.width
- self.width *= -1
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def update(self, levelBorders, surface):
- self.updateMotion(levelBorders)
- self.draw(surface)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def updateMotion(self, levelBorders):
- # Increment the position of the platform by the velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Wrap the motion of the platform around the level edges
- if self.x >= levelBorders[2] and self.Vx > 0:
- self.x = levelBorders[0] - self.width
- elif (self.x - self.width) <= levelBorders[0] and self.Vx < 0:
- self.x = levelBorders[2]
- elif self.y >= levelBorders[3] and self.Vy > 0:
- self.y = levelBorders[1] - self.height
- elif (self.y + self.height) <= levelBorders[1] and self.Vy < 0:
- self.y = levelBorders[3]
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, surface):
- surface.blit(self.imageCache, (self.x, self.y))
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def getRect(self):
- return pygame.Rect(self.x, self.y, self.width, self.height)
diff --git a/data/playablecharacter.py b/data/playablecharacter.py
deleted file mode 100644
index f7bd83c..0000000
--- a/data/playablecharacter.py
+++ /dev/null
@@ -1,318 +0,0 @@
-# coding=utf-8
-import math, sys, pygame, keymap as k
-from random import randint
-from pygame.locals import *
-from character import Character
-import os
-
-
-class PlayableCharacter(Character):
-
- def __init__(self, x, y, Vx=0, Vy=0, whichChar=1):
- Character.__init__(self, x, y, Vx, Vy, whichChar)
-
- # HUD images
- self.whichChar = whichChar
- self.heartEmpty = pygame.image.load('hud'+os.sep+'hud_heartEmpty.png').convert_alpha()
- self.heartHalf = pygame.image.load('hud'+os.sep+'hud_heartHalf.png').convert_alpha()
- self.heartFull = pygame.image.load('hud'+os.sep+'hud_heartFull.png').convert_alpha()
- self.heartWidth = pygame.Surface.get_width(self.heartFull)
- self.heartHeight = pygame.Surface.get_height(self.heartFull)
- self.coin = pygame.image.load('hud'+os.sep+'hud_coins.png').convert_alpha()
- self.coinWidth = pygame.Surface.get_width(self.coin)
- self.coinsMultiplier = pygame.image.load('hud'+os.sep+'hud_x.png').convert_alpha()
- self.hudNumber = []
- for i in range(0, 10):
- numberImage = pygame.image.load('hud'+os.sep+'hud_' + str(i) + '.png').convert_alpha()
- self.hudNumber.append(numberImage)
- self.hudTextWidth = pygame.Surface.get_width(self.hudNumber[0])
- self.playerCoins = []
- for i in range(0, 3):
- playerCoinImage = pygame.image.load('hud'+os.sep+'hud_p' + str(self.whichChar) + '.png').convert_alpha()
- self.playerCoins.append(playerCoinImage)
- self.key = pygame.image.load('hud'+os.sep+'hud_keyBlue.png').convert_alpha()
- self.noKey = pygame.image.load('hud'+os.sep+'hud_keyBlue_disabled.png').convert_alpha()
-
- # HUD variables
- self.spacing = 10
- self.coins = 0
- self.playerCoinCoords = (self.spacing, self.spacing)
- self.healthStart = (pygame.Surface.get_width(self.playerCoins[0]) + 2 * self.spacing, 10)
- self.healthInterval = self.spacing + self.heartWidth
-
- # Other variables
- if whichChar == 1:
- self.jumpSpeed = 35
- self.runSpeed = 8.5
- self.lives = 9
- else:
- self.jumpSpeed = 36
- self.runSpeed = 9.0
- self.lives = 4
- self.worldShiftCoefficient = 1.5
- self.cpuControlled = False
- self.longestPlatform = None
- self.respawnPoint = None
- self.keys = pygame.key.get_pressed() # Keyboard key state
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool, surface,
- scrW=0, scrH=0, FPS=75, autoscroll=False, checkpoints=None, torches=None):
- self.collide(platforms, blocks, aiCharacters, pool, torches)
- self.collideCheckpoint(checkpoints)
- self.draw(surface, FPS)
- if self.move(ev, platforms, movableObjects, aiCharacters, scrW, scrH, autoscroll):
- return True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def collideCheckpoint(self, checkpoints):
- if checkpoints:
- for fence in checkpoints:
- if self.getRect().colliderect(fence.getRect()) and not fence.broken:
- self.respawnPoint = [fence.x + 20, fence.y - 70]
- fence.broken = True
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def incrementMapH(self, aiCharacters, movableObjects, amount, doMoveSelf=True):
- # Moves all of the map details left or right by the specified amount
- if doMoveSelf:
- self.x += amount
- if self.respawnPoint:
- self.respawnPoint[0] += amount
- for obj in movableObjects:
- obj.x += amount
- if hasattr(obj, 'invertedX'):
- obj.invertedX += amount
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] += amount
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] += amount
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def incrementMapV(self, movableObjects, amount, doMoveSelf=True):
- # Moves all of the map details up or down by the specified amoun
- if doMoveSelf:
- self.y += amount
- if self.respawnPoint:
- self.respawnPoint[1] += amount
- for obj in movableObjects:
- obj.y += amount
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def setMapObjX(self, aiCharacters, movableObjects, platforms, newX):
- # Shifts all of the map details
- shift = newX - platforms[0][0]
- self.x += shift
- if self.respawnPoint:
- self.respawnPoint[0] += shift
- for obj in movableObjects:
- obj.x += shift
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] += shift
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] += shift
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def getNextPlatform(self, platforms):
- currX = platforms[self.currentPlatform].x
- longX = platforms[self.longestPlatform].x
- if currX == longX and self.longestPlatform + 1 < len(platforms):
- return platforms[self.longestPlatform + 1]
- elif self.currentPlatform >= len(platforms) - 1:
- return platforms[self.currentPlatform]
- else:
- return platforms[self.currentPlatform + 1]
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def initSpawnpoint(self, autoscroll, platforms, nextPlatform):
- if not autoscroll and not self.respawnPoint:
- self.respawnPoint = [0.5 * platforms[0][0] + 0.5 * platforms[0][2], platforms[0][1] - self.height - 10]
- elif autoscroll:
- self.respawnPoint = [nextPlatform[0] + 0.5 * nextPlatform.width, nextPlatform[1] - self.height - 10]
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def respawn(self, x, y, loseLife=True):
- self.x = int(x)
- self.y = int(y)
- self.Vx, self.Vy = 0, 0
- self.health = self.recoveryHealth
- if loseLife:
- self.flashing = True
- self.lives -= 1
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def allowJumping(self):
- if self.jumping and self.onGround:
- self.jumping = False
- if (self.keys[k.ACTION] or self.keys[k.ACTION2]) and self.canJump and self.onGround:
- Character.jump(self)
- self.jumping = True
- self.canJump = False
- self.onGround = False
- if not self.keys[k.ACTION] and not self.keys[k.ACTION2] and self.onGround:
- self.canJump = True
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def scanWorld(self, aiCharacters, autoscroll, movableObjects, nextPlatform, scrH, scrW):
- rightEdge = int(0.5 * scrW) + 2
- leftEdge = int(0.5 * scrW) - 2
- bottomEdge = int(0.25 * scrH) if self.ducking else int(0.7 * scrH) + 5
- topEdge = int(0.3 * scrH) - 5
- if self.y <= scrH and not autoscroll:
- self.incrementMapH(aiCharacters, movableObjects, -self.Vx, doMoveSelf=False)
- if self.x >= rightEdge:
- self.incrementMapH(aiCharacters, movableObjects, -int(self.worldShiftCoefficient * self.runSpeed))
- if self.x <= leftEdge:
- self.incrementMapH(aiCharacters, movableObjects, int(self.worldShiftCoefficient * self.runSpeed))
- if self.y <= scrH:
- if self.y <= topEdge:
- self.incrementMapV(movableObjects, int(self.worldShiftCoefficient * self.runSpeed))
- if self.y >= bottomEdge or nextPlatform[3] >= scrH:
- self.incrementMapV(movableObjects, -int(self.worldShiftCoefficient * self.runSpeed))
- elif randint(0, 10) == 0:
- self.health -= 1
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def determineLongestPlatform(self, platforms):
- if not self.longestPlatform:
- self.longestPlatform = 0
- for platformIndex in xrange(1, len(platforms)):
- if platforms[platformIndex].width > platforms[self.longestPlatform].width:
- self.longestPlatform = platformIndex
- for platformIndex in xrange(0, len(platforms)):
- if platforms[platformIndex][0] == platforms[self.longestPlatform][0] and \
- platforms[platformIndex][1] >= platforms[self.longestPlatform][1]:
- self.longestPlatform = platformIndex
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def enableHorizMovement(self):
- pressingLeft = self.keys[k.LEFT] or self.keys[k.LEFT2]
- pressingRight = self.keys[k.RIGHT] or self.keys[k.RIGHT2]
- pressingDown = self.keys[k.DUCK] or self.keys[k.DUCK2]
- movable = not self.cpuControlled
- if pressingLeft and movable:
- self.Vx = -self.runSpeed
- if pressingRight and movable:
- self.Vx = self.runSpeed
- if not pressingLeft and not pressingRight and movable:
- self.Vx = 0
- self.movingLaterally = False
- if self.Vx > 0:
- self.direction = 1
- self.movingLaterally = True
- elif self.Vx < 0:
- self.direction = 0
- self.movingLaterally = True
- else:
- self.direction = 2
- if pressingDown and movable:
- self.ducking = True
- self.Vx = 0
- else:
- self.ducking = False
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def handleWorldScrolling(self, aiCharacters, autoscroll, movableObjects, scrW):
- if autoscroll and 0 <= self.x + self.width:
- self.incrementMapH(aiCharacters, movableObjects, -0.5 * self.runSpeed)
- self.x += self.Vx
- elif autoscroll and self.health > 0:
- self.health -= 0.5
- # Scroll faster if the player is off screen
- if self.x <= 0 or self.x >= scrW:
- self.worldShiftCoefficient = 20
- else:
- self.worldShiftCoefficient = 1.5
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def move(self, events, platforms, movableObjects, aiCharacters, scrW, scrH, autoscroll):
- # Call base class implementation and cancel the position increment
- Character.updateMotion(self, platforms)
- self.x -= self.Vx
-
- # Get keyboard state
- self.keys = pygame.key.get_pressed()
-
- # Enable horizontal motion
- self.enableHorizMovement()
-
- # Determine the longest platform and the next platform
- self.determineLongestPlatform(platforms)
- nextPlatform = self.getNextPlatform(platforms)
-
- # Move world horizontally and vertically to follow player
- self.scanWorld(aiCharacters, autoscroll, movableObjects, nextPlatform, scrH, scrW)
-
- # Autoscroll as necessary
- self.handleWorldScrolling(aiCharacters, autoscroll, movableObjects, scrW)
-
- # Allow jumping
- self.allowJumping()
-
- # If necessary, initialize the respawn point
- self.initSpawnpoint(autoscroll, platforms, nextPlatform)
-
- # Respawn if the health reaches zero
- if self.health <= 0:
- self.respawn(self.respawnPoint[0], self.respawnPoint[1])
-
- # Show game over screen if no lives are remaining
- if self.lives <= 0 and self.x != 0:
- return False
-
- # Check for any other I/O events
- for event in events:
- if event.type == QUIT or self.keys[k.EXIT]:
- pygame.quit(); sys.exit()
- return True
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, surface, FPS=75):
- Character.draw(self, surface)
-
- # DRAW HUD:
-
- # Player symbol
- surface.blit(self.playerCoins[self.whichChar - 1], self.playerCoinCoords)
- surface.blit(self.coinsMultiplier, (self.spacing + self.heartWidth, int(2.5 * self.spacing)))
- surface.blit(self.hudNumber[self.lives], (5 * self.spacing + self.heartWidth, int(1.5 * self.spacing)))
- # Health
- health = self.health / 2.0
- for filledHearts in range(1, int(math.floor(health)) + 1):
- if health >= 0:
- surface.blit(self.heartFull, (self.healthInterval * filledHearts - 55, 7 * self.spacing))
- if math.floor(health) != health and health >= 0:
- surface.blit(self.heartHalf, (self.healthInterval * math.ceil(health) - 55, 7 * self.spacing))
- # Coins
- surface.blit(self.coin, (self.spacing, 8 * self.spacing + self.heartHeight))
- surface.blit(self.coinsMultiplier, (self.spacing + self.heartWidth,
- 8 * self.spacing + self.heartHeight + 15))
- coinsAsList = []
- for i in str(self.coins):
- coinsAsList.append(int(i))
- for i in range(0, len(coinsAsList)):
- surface.blit(self.hudNumber[coinsAsList[i]], (3 * self.spacing + self.coinWidth + self.hudTextWidth *
- (i + 1), 7 * self.spacing + self.heartHeight + 15))
- # Key
- if self.hasKey:
- surface.blit(self.key, (self.spacing, 13 * self.spacing + self.heartHeight + 15))
- else:
- surface.blit(self.noKey, (self.spacing, 13 * self.spacing + self.heartHeight + 15))
diff --git a/data/pool.py b/data/pool.py
deleted file mode 100644
index adae486..0000000
--- a/data/pool.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# coding=utf-8
-from game import *
-import os
-
-class Pool(object):
-
- def __init__(self, x, y, width, height, style='grass'):
- self.x, self.y = x, y
- self.Vx, self.Vy = 0, 0
- self.width, self.height = width, height
-
- # Platform images
- self.image = pygame.image.load('environment'+os.sep+'main'+os.sep+'' + style + 'Mid.png').convert_alpha()
- self.plainImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'' + style + 'Center.png')
- self.leftImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'' + style + 'CliffLeft.png').convert_alpha()
- self.rightImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'' + style + 'CliffRight.png').convert_alpha()
- self.tileWidth = pygame.Surface.get_width(self.image)
-
- # Water images
- self.waterFilled = pygame.image.load('environment'+os.sep+'main'+os.sep+'liquidWater.png').convert_alpha()
- self.waterTop = pygame.image.load('environment'+os.sep+'main'+os.sep+'liquidWaterTop_mid.png').convert_alpha()
-
- # Update coordinates
- self.width -= self.width % self.tileWidth
- self.height -= self.height % self.tileWidth
- self.poolStartX = int(self.x + 2 * self.tileWidth)
- self.poolEndX = int(self.x + self.width - 2 * self.tileWidth)
-
- # Other control variables
- self.tilesOnEitherSide = 2
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def update(self, surface):
- self.updateMotion()
- self.draw(surface)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def updateMotion(self):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, surface):
- # Draw edge platforms
- surface.blit(self.leftImage, (self.x, self.y))
- surface.blit(self.rightImage, (self.x + self.width - self.tileWidth, self.y))
-
- # Draw platform tiles on either side of the pool
- self.poolStartX = int(self.x + self.tilesOnEitherSide * self.tileWidth)
- self.poolEndX = int(self.x + self.width - (1 + self.tilesOnEitherSide) * self.tileWidth)
- for x in range(int(self.x) + self.tileWidth, self.poolStartX + self.tileWidth, self.tileWidth):
- surface.blit(self.image, (x, self.y))
- for x in range(self.poolEndX, int(self.x + self.width - self.tileWidth), self.tileWidth):
- surface.blit(self.image, (x, self.y))
-
- # Draw pool side columns
- for y in range(int(self.y + self.tileWidth), int(self.y + self.height), self.tileWidth):
- surface.blit(self.plainImage, (self.poolStartX, y))
- surface.blit(self.plainImage, (self.poolEndX, y))
-
- # Draw bottom of pool
- for x in range(self.poolStartX, self.poolEndX + self.tileWidth, self.tileWidth):
- surface.blit(self.plainImage, (x, self.y + self.height))
-
- # Fill with water
- for y in range(int(self.y + self.tileWidth), int(self.y + self.height), self.tileWidth):
- for x in range(self.poolStartX + self.tileWidth, self.poolEndX, self.tileWidth):
- surface.blit(self.waterFilled, (x, y))
- for x in range(self.poolStartX + self.tileWidth, self.poolEndX, self.tileWidth):
- surface.blit(self.waterTop, (x, self.y))
diff --git a/data/spike.py b/data/spike.py
deleted file mode 100644
index 41db96e..0000000
--- a/data/spike.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# coding=utf-8
-from data.game import *
-import os
-
-class FallingSpike(object):
- def __init__(self, x, y):
- # Initialize motion variables, "x" represents the x co-ordinate of the center of the spike
- self.x = x
- self.y = y
- self.Vx = 0
- self.Vy = 0
-
- # Initialize image
- self.image = pygame.image.load('environment'+os.sep+'main'+os.sep+'spikeTop.png')
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
- self.x -= int(0.5 * self.width)
-
- # Other control variables
- self.visible = True
- self.gravityAcceleration = 1.5
- self.dislodged = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, chars, blocks, surface):
- self.updateMotion(chars, platforms)
- self.collide(chars, platforms)
- self.draw(platforms, blocks, surface)
-
- # -----------------------------------------------------------------------------------------------------------------
- def collide(self, chars, platforms):
- for char in chars:
- spikeCentre = (int(self.x + self.width / 2), self.y + int(0.5 * self.height))
- charRect = pygame.Rect(char.x, char.y, char.width, char.height)
- if charRect.collidepoint(spikeCentre) and self.visible and not char.flashing:
- char.health -= 1
- char.flashing = True
- self.visible = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, chars, platforms):
- # Increment position by velocity
- self.x += self.Vx
- self.y += int(self.Vy)
-
- # Only update motion if the spike is in view
- if 0 <= self.x <= 2000 and 0 <= self.y <= 2000:
-
- # Check if spike should be dislodged
- for char in chars:
- if char.x + char.width >= self.x and char.x <= self.x + self.width and char.y >= self.y:
- self.dislodged = True
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0][3] - platforms[0][1] - 5
-
- # Apply gravity if dislodged
- if self.dislodged:
- self.Vy += self.gravityAcceleration
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, platforms, blocks, surface):
- # Only draw if icicle is either stationary or falling and not yet hit an object
- if self.visible:
- surface.blit(self.image, (self.x, self.y))
- if self.visible and self.dislodged and 0 <= self.x <= 2000 and 0 <= self.y <= 2000:
- for platform in platforms:
- if self.y + 0.5 * self.height >= platform[1] > self.y and platform[0] <= self.x <= platform[2]:
- self.visible = False
- for block in blocks:
- if self.y + 0.5 * self.height >= block[0][1] and self.x + \
- self.width >= block[0][0] and self.x <= block[0][2]:
- self.visible = False
diff --git a/data/torch.py b/data/torch.py
deleted file mode 100644
index 50fbc4e..0000000
--- a/data/torch.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# coding=utf-8
-import pygame, random, os
-
-
-class Torch(object):
-
- def __init__(self, x, y):
- self.x = x
- self.y = y
- self.burning = False
- self.onImage1 = pygame.image.load('environment'+os.sep+'main'+os.sep+'torchLit.png').convert_alpha()
- self.onImage2 = pygame.image.load('environment'+os.sep+'main'+os.sep+'torchLit2.png').convert_alpha()
- self.offImage = pygame.image.load('environment'+os.sep+'main'+os.sep+'torch.png').convert_alpha()
- self.width = pygame.Surface.get_width(self.offImage)
- self.height = pygame.Surface.get_height(self.offImage)
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def draw(self, surface):
- if not self.burning:
- surface.blit(self.offImage, [self.x, self.y])
- elif random.randint(0, 1) == 1:
- surface.blit(self.onImage1, [self.x, self.y])
- else:
- surface.blit(self.onImage2, [self.x, self.y])
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def getRect(self):
- return pygame.Rect(self.x, self.y, self.width, self.height)
diff --git a/door.py b/door.py
deleted file mode 100644
index 0a2e830..0000000
--- a/door.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# coding=utf-8
-import pygame
-from game import *
-
-
-class Door(object):
- def __init__(self, x, y):
- self.x = x
- self.y = y
- self.locked = True
-
- # Load images
- self.imageBottom = pygame.image.load('environment\\main\\door_openMid.png').convert_alpha()
- self.imageTop = pygame.image.load('environment\\main\\door_openTop.png').convert_alpha()
- self.imageBottomLocked = pygame.image.load('environment\\main\\door_closedMid.png').convert_alpha()
- self.imageTopLocked = pygame.image.load('environment\\main\\door_closedTop.png').convert_alpha()
- self.bottomHeight = pygame.Surface.get_height(self.imageBottom)
- self.topHeight = pygame.Surface.get_height(self.imageTop)
- self.topBlankSpace = 30
- self.height = self.bottomHeight + self.topHeight - self.topBlankSpace
- self.width = pygame.Surface.get_width(self.imageBottom)
- self.y -= self.bottomHeight + self.topHeight
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, mainChar, surface, unlockable=True):
- charRect = pygame.Rect(mainChar.x, mainChar.y, mainChar.width, mainChar.height)
- selfRect = self.getRect()
- inDoor = charRect.colliderect(selfRect)
- hasKey = mainChar.hasKey
- if inDoor and hasKey and unlockable:
- self.locked = False
- if self.locked:
- surface.blit(self.imageTopLocked, (self.x, self.y))
- surface.blit(self.imageBottomLocked, (self.x, self.y + self.topHeight))
- elif unlockable:
- surface.blit(self.imageTop, (self.x, self.y))
- surface.blit(self.imageBottom, (self.x, self.y + self.topHeight))
- if not self.locked and inDoor and unlockable:
- return True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
- def getRect(self):
- return pygame.Rect(self.x, self.y + self.topBlankSpace, self.width, self.height)
\ No newline at end of file
diff --git a/enemies/fly/fly_dead.png b/enemies/fly/fly_dead.png
deleted file mode 100644
index 840b8f9..0000000
Binary files a/enemies/fly/fly_dead.png and /dev/null differ
diff --git a/enemies/fly/fly_dead_r.png b/enemies/fly/fly_dead_r.png
deleted file mode 100644
index 12828b7..0000000
Binary files a/enemies/fly/fly_dead_r.png and /dev/null differ
diff --git a/enemies/fly/fly_fly.png b/enemies/fly/fly_fly.png
deleted file mode 100644
index 35219b3..0000000
Binary files a/enemies/fly/fly_fly.png and /dev/null differ
diff --git a/enemies/fly/fly_fly_r.png b/enemies/fly/fly_fly_r.png
deleted file mode 100644
index 33f6103..0000000
Binary files a/enemies/fly/fly_fly_r.png and /dev/null differ
diff --git a/enemies/fly/fly_normal.png b/enemies/fly/fly_normal.png
deleted file mode 100644
index f198873..0000000
Binary files a/enemies/fly/fly_normal.png and /dev/null differ
diff --git a/enemies/other/barnacle.png b/enemies/other/barnacle.png
deleted file mode 100644
index 33b8d14..0000000
Binary files a/enemies/other/barnacle.png and /dev/null differ
diff --git a/enemies/other/barnacle_bite.png b/enemies/other/barnacle_bite.png
deleted file mode 100644
index 09a2e48..0000000
Binary files a/enemies/other/barnacle_bite.png and /dev/null differ
diff --git a/enemies/other/barnacle_dead.png b/enemies/other/barnacle_dead.png
deleted file mode 100644
index 9b201ff..0000000
Binary files a/enemies/other/barnacle_dead.png and /dev/null differ
diff --git a/enemies/other/barnacle_hit.png b/enemies/other/barnacle_hit.png
deleted file mode 100644
index b4ef7af..0000000
Binary files a/enemies/other/barnacle_hit.png and /dev/null differ
diff --git a/enemies/other/bat.png b/enemies/other/bat.png
deleted file mode 100644
index 0d66f96..0000000
Binary files a/enemies/other/bat.png and /dev/null differ
diff --git a/enemies/other/bat_dead.png b/enemies/other/bat_dead.png
deleted file mode 100644
index 62f8ad5..0000000
Binary files a/enemies/other/bat_dead.png and /dev/null differ
diff --git a/enemies/other/bat_fly.png b/enemies/other/bat_fly.png
deleted file mode 100644
index 29985f1..0000000
Binary files a/enemies/other/bat_fly.png and /dev/null differ
diff --git a/enemies/other/bat_hang.png b/enemies/other/bat_hang.png
deleted file mode 100644
index 756b315..0000000
Binary files a/enemies/other/bat_hang.png and /dev/null differ
diff --git a/enemies/other/bat_hit.png b/enemies/other/bat_hit.png
deleted file mode 100644
index f947382..0000000
Binary files a/enemies/other/bat_hit.png and /dev/null differ
diff --git a/enemies/other/bee.png b/enemies/other/bee.png
deleted file mode 100644
index 6243bc1..0000000
Binary files a/enemies/other/bee.png and /dev/null differ
diff --git a/enemies/other/bee_dead.png b/enemies/other/bee_dead.png
deleted file mode 100644
index e40cfc6..0000000
Binary files a/enemies/other/bee_dead.png and /dev/null differ
diff --git a/enemies/other/bee_fly.png b/enemies/other/bee_fly.png
deleted file mode 100644
index 08f7530..0000000
Binary files a/enemies/other/bee_fly.png and /dev/null differ
diff --git a/enemies/other/bee_hit.png b/enemies/other/bee_hit.png
deleted file mode 100644
index 4c53938..0000000
Binary files a/enemies/other/bee_hit.png and /dev/null differ
diff --git a/enemies/other/blockerBody.png b/enemies/other/blockerBody.png
deleted file mode 100644
index 1de10eb..0000000
Binary files a/enemies/other/blockerBody.png and /dev/null differ
diff --git a/enemies/other/blockerMad.png b/enemies/other/blockerMad.png
deleted file mode 100644
index e179b20..0000000
Binary files a/enemies/other/blockerMad.png and /dev/null differ
diff --git a/enemies/other/blockerSad.png b/enemies/other/blockerSad.png
deleted file mode 100644
index ce43f0e..0000000
Binary files a/enemies/other/blockerSad.png and /dev/null differ
diff --git a/enemies/other/enemies_spritesheet.png b/enemies/other/enemies_spritesheet.png
deleted file mode 100644
index b23aff5..0000000
Binary files a/enemies/other/enemies_spritesheet.png and /dev/null differ
diff --git a/enemies/other/fishDead.png b/enemies/other/fishDead.png
deleted file mode 100644
index 4d4a5e3..0000000
Binary files a/enemies/other/fishDead.png and /dev/null differ
diff --git a/enemies/other/fishDead_r.png b/enemies/other/fishDead_r.png
deleted file mode 100644
index 0f09456..0000000
Binary files a/enemies/other/fishDead_r.png and /dev/null differ
diff --git a/enemies/other/fishGreen.png b/enemies/other/fishGreen.png
deleted file mode 100644
index 4c173bf..0000000
Binary files a/enemies/other/fishGreen.png and /dev/null differ
diff --git a/enemies/other/fishGreen_dead.png b/enemies/other/fishGreen_dead.png
deleted file mode 100644
index 6ac7d27..0000000
Binary files a/enemies/other/fishGreen_dead.png and /dev/null differ
diff --git a/enemies/other/fishGreen_dead_r.png b/enemies/other/fishGreen_dead_r.png
deleted file mode 100644
index 7239cff..0000000
Binary files a/enemies/other/fishGreen_dead_r.png and /dev/null differ
diff --git a/enemies/other/fishGreen_hit.png b/enemies/other/fishGreen_hit.png
deleted file mode 100644
index 8f4fd6e..0000000
Binary files a/enemies/other/fishGreen_hit.png and /dev/null differ
diff --git a/enemies/other/fishGreen_swim.png b/enemies/other/fishGreen_swim.png
deleted file mode 100644
index 7f2bfbf..0000000
Binary files a/enemies/other/fishGreen_swim.png and /dev/null differ
diff --git a/enemies/other/fishGreen_swim_r.png b/enemies/other/fishGreen_swim_r.png
deleted file mode 100644
index 935b6c9..0000000
Binary files a/enemies/other/fishGreen_swim_r.png and /dev/null differ
diff --git a/enemies/other/fishPink.png b/enemies/other/fishPink.png
deleted file mode 100644
index 98b932f..0000000
Binary files a/enemies/other/fishPink.png and /dev/null differ
diff --git a/enemies/other/fishPink_dead.png b/enemies/other/fishPink_dead.png
deleted file mode 100644
index 8669dc3..0000000
Binary files a/enemies/other/fishPink_dead.png and /dev/null differ
diff --git a/enemies/other/fishPink_hit.png b/enemies/other/fishPink_hit.png
deleted file mode 100644
index 8f4fd6e..0000000
Binary files a/enemies/other/fishPink_hit.png and /dev/null differ
diff --git a/enemies/other/fishPink_swim.png b/enemies/other/fishPink_swim.png
deleted file mode 100644
index da4af35..0000000
Binary files a/enemies/other/fishPink_swim.png and /dev/null differ
diff --git a/enemies/other/fishSwim1.png b/enemies/other/fishSwim1.png
deleted file mode 100644
index ef60af6..0000000
Binary files a/enemies/other/fishSwim1.png and /dev/null differ
diff --git a/enemies/other/fishSwim1R.png b/enemies/other/fishSwim1R.png
deleted file mode 100644
index 3b9206a..0000000
Binary files a/enemies/other/fishSwim1R.png and /dev/null differ
diff --git a/enemies/other/fishSwim2.png b/enemies/other/fishSwim2.png
deleted file mode 100644
index f433086..0000000
Binary files a/enemies/other/fishSwim2.png and /dev/null differ
diff --git a/enemies/other/fishSwim2R.png b/enemies/other/fishSwim2R.png
deleted file mode 100644
index 021b2f3..0000000
Binary files a/enemies/other/fishSwim2R.png and /dev/null differ
diff --git a/enemies/other/fly.png b/enemies/other/fly.png
deleted file mode 100644
index e84579f..0000000
Binary files a/enemies/other/fly.png and /dev/null differ
diff --git a/enemies/other/flyDead.png b/enemies/other/flyDead.png
deleted file mode 100644
index b6e1f2d..0000000
Binary files a/enemies/other/flyDead.png and /dev/null differ
diff --git a/enemies/other/flyFly1.png b/enemies/other/flyFly1.png
deleted file mode 100644
index 8f85ad4..0000000
Binary files a/enemies/other/flyFly1.png and /dev/null differ
diff --git a/enemies/other/flyFly2.png b/enemies/other/flyFly2.png
deleted file mode 100644
index ccf4576..0000000
Binary files a/enemies/other/flyFly2.png and /dev/null differ
diff --git a/enemies/other/fly_dead.png b/enemies/other/fly_dead.png
deleted file mode 100644
index 840b8f9..0000000
Binary files a/enemies/other/fly_dead.png and /dev/null differ
diff --git a/enemies/other/fly_fly.png b/enemies/other/fly_fly.png
deleted file mode 100644
index 35219b3..0000000
Binary files a/enemies/other/fly_fly.png and /dev/null differ
diff --git a/enemies/other/fly_hit.png b/enemies/other/fly_hit.png
deleted file mode 100644
index 8b707e4..0000000
Binary files a/enemies/other/fly_hit.png and /dev/null differ
diff --git a/enemies/other/frog.png b/enemies/other/frog.png
deleted file mode 100644
index 7a4ca84..0000000
Binary files a/enemies/other/frog.png and /dev/null differ
diff --git a/enemies/other/frog_dead.png b/enemies/other/frog_dead.png
deleted file mode 100644
index 857f823..0000000
Binary files a/enemies/other/frog_dead.png and /dev/null differ
diff --git a/enemies/other/frog_hit.png b/enemies/other/frog_hit.png
deleted file mode 100644
index 073a8f9..0000000
Binary files a/enemies/other/frog_hit.png and /dev/null differ
diff --git a/enemies/other/frog_leap.png b/enemies/other/frog_leap.png
deleted file mode 100644
index af8623c..0000000
Binary files a/enemies/other/frog_leap.png and /dev/null differ
diff --git a/enemies/other/ghost.png b/enemies/other/ghost.png
deleted file mode 100644
index 1e1dc25..0000000
Binary files a/enemies/other/ghost.png and /dev/null differ
diff --git a/enemies/other/ghost_dead.png b/enemies/other/ghost_dead.png
deleted file mode 100644
index 4ae6cf8..0000000
Binary files a/enemies/other/ghost_dead.png and /dev/null differ
diff --git a/enemies/other/ghost_hit.png b/enemies/other/ghost_hit.png
deleted file mode 100644
index 6f60c6a..0000000
Binary files a/enemies/other/ghost_hit.png and /dev/null differ
diff --git a/enemies/other/ghost_normal.png b/enemies/other/ghost_normal.png
deleted file mode 100644
index fb5e374..0000000
Binary files a/enemies/other/ghost_normal.png and /dev/null differ
diff --git a/enemies/other/grassBlock.png b/enemies/other/grassBlock.png
deleted file mode 100644
index 639ed01..0000000
Binary files a/enemies/other/grassBlock.png and /dev/null differ
diff --git a/enemies/other/grassBlock_dead.png b/enemies/other/grassBlock_dead.png
deleted file mode 100644
index 5ac452d..0000000
Binary files a/enemies/other/grassBlock_dead.png and /dev/null differ
diff --git a/enemies/other/grassBlock_hit.png b/enemies/other/grassBlock_hit.png
deleted file mode 100644
index e270f2d..0000000
Binary files a/enemies/other/grassBlock_hit.png and /dev/null differ
diff --git a/enemies/other/grassBlock_jump.png b/enemies/other/grassBlock_jump.png
deleted file mode 100644
index ec419c1..0000000
Binary files a/enemies/other/grassBlock_jump.png and /dev/null differ
diff --git a/enemies/other/ladyBug.png b/enemies/other/ladyBug.png
deleted file mode 100644
index 0d59a52..0000000
Binary files a/enemies/other/ladyBug.png and /dev/null differ
diff --git a/enemies/other/ladyBug_fly.png b/enemies/other/ladyBug_fly.png
deleted file mode 100644
index 555e8a3..0000000
Binary files a/enemies/other/ladyBug_fly.png and /dev/null differ
diff --git a/enemies/other/ladyBug_hit.png b/enemies/other/ladyBug_hit.png
deleted file mode 100644
index b0acb00..0000000
Binary files a/enemies/other/ladyBug_hit.png and /dev/null differ
diff --git a/enemies/other/ladyBug_walk.png b/enemies/other/ladyBug_walk.png
deleted file mode 100644
index bed924e..0000000
Binary files a/enemies/other/ladyBug_walk.png and /dev/null differ
diff --git a/enemies/other/mouse.png b/enemies/other/mouse.png
deleted file mode 100644
index 3f7c2ff..0000000
Binary files a/enemies/other/mouse.png and /dev/null differ
diff --git a/enemies/other/mouse_dead.png b/enemies/other/mouse_dead.png
deleted file mode 100644
index bbba998..0000000
Binary files a/enemies/other/mouse_dead.png and /dev/null differ
diff --git a/enemies/other/mouse_hit.png b/enemies/other/mouse_hit.png
deleted file mode 100644
index 34b7b07..0000000
Binary files a/enemies/other/mouse_hit.png and /dev/null differ
diff --git a/enemies/other/mouse_walk.png b/enemies/other/mouse_walk.png
deleted file mode 100644
index 07bce84..0000000
Binary files a/enemies/other/mouse_walk.png and /dev/null differ
diff --git a/enemies/other/piranha.png b/enemies/other/piranha.png
deleted file mode 100644
index 39c1244..0000000
Binary files a/enemies/other/piranha.png and /dev/null differ
diff --git a/enemies/other/piranha_dead.png b/enemies/other/piranha_dead.png
deleted file mode 100644
index b6d7151..0000000
Binary files a/enemies/other/piranha_dead.png and /dev/null differ
diff --git a/enemies/other/piranha_down.png b/enemies/other/piranha_down.png
deleted file mode 100644
index 6e3c466..0000000
Binary files a/enemies/other/piranha_down.png and /dev/null differ
diff --git a/enemies/other/piranha_hit.png b/enemies/other/piranha_hit.png
deleted file mode 100644
index 1e12b9c..0000000
Binary files a/enemies/other/piranha_hit.png and /dev/null differ
diff --git a/enemies/other/pokerMad.png b/enemies/other/pokerMad.png
deleted file mode 100644
index b645b3e..0000000
Binary files a/enemies/other/pokerMad.png and /dev/null differ
diff --git a/enemies/other/pokerSad.png b/enemies/other/pokerSad.png
deleted file mode 100644
index d199afa..0000000
Binary files a/enemies/other/pokerSad.png and /dev/null differ
diff --git a/enemies/other/slime.png b/enemies/other/slime.png
deleted file mode 100644
index 8fb6ca1..0000000
Binary files a/enemies/other/slime.png and /dev/null differ
diff --git a/enemies/other/slimeBlock.png b/enemies/other/slimeBlock.png
deleted file mode 100644
index 6404f01..0000000
Binary files a/enemies/other/slimeBlock.png and /dev/null differ
diff --git a/enemies/other/slimeBlock_dead.png b/enemies/other/slimeBlock_dead.png
deleted file mode 100644
index 92e70dc..0000000
Binary files a/enemies/other/slimeBlock_dead.png and /dev/null differ
diff --git a/enemies/other/slimeBlock_hit.png b/enemies/other/slimeBlock_hit.png
deleted file mode 100644
index c8dd227..0000000
Binary files a/enemies/other/slimeBlock_hit.png and /dev/null differ
diff --git a/enemies/other/slimeDead.png b/enemies/other/slimeDead.png
deleted file mode 100644
index dce145f..0000000
Binary files a/enemies/other/slimeDead.png and /dev/null differ
diff --git a/enemies/other/slimeWalk1.png b/enemies/other/slimeWalk1.png
deleted file mode 100644
index b284a19..0000000
Binary files a/enemies/other/slimeWalk1.png and /dev/null differ
diff --git a/enemies/other/slimeWalk2.png b/enemies/other/slimeWalk2.png
deleted file mode 100644
index 96b0358..0000000
Binary files a/enemies/other/slimeWalk2.png and /dev/null differ
diff --git a/enemies/other/slime_dead.png b/enemies/other/slime_dead.png
deleted file mode 100644
index ee61ae7..0000000
Binary files a/enemies/other/slime_dead.png and /dev/null differ
diff --git a/enemies/other/slime_hit.png b/enemies/other/slime_hit.png
deleted file mode 100644
index 46ce4e2..0000000
Binary files a/enemies/other/slime_hit.png and /dev/null differ
diff --git a/enemies/other/slime_squashed.png b/enemies/other/slime_squashed.png
deleted file mode 100644
index 6a7859b..0000000
Binary files a/enemies/other/slime_squashed.png and /dev/null differ
diff --git a/enemies/other/slime_walk.png b/enemies/other/slime_walk.png
deleted file mode 100644
index ce421b6..0000000
Binary files a/enemies/other/slime_walk.png and /dev/null differ
diff --git a/enemies/other/snail.png b/enemies/other/snail.png
deleted file mode 100644
index 0ce4823..0000000
Binary files a/enemies/other/snail.png and /dev/null differ
diff --git a/enemies/other/snailShell.png b/enemies/other/snailShell.png
deleted file mode 100644
index 142daf0..0000000
Binary files a/enemies/other/snailShell.png and /dev/null differ
diff --git a/enemies/other/snailShellR.png b/enemies/other/snailShellR.png
deleted file mode 100644
index 5a9f520..0000000
Binary files a/enemies/other/snailShellR.png and /dev/null differ
diff --git a/enemies/other/snailShell_upsidedown.png b/enemies/other/snailShell_upsidedown.png
deleted file mode 100644
index 7515878..0000000
Binary files a/enemies/other/snailShell_upsidedown.png and /dev/null differ
diff --git a/enemies/other/snailWalk1.png b/enemies/other/snailWalk1.png
deleted file mode 100644
index 2a503fc..0000000
Binary files a/enemies/other/snailWalk1.png and /dev/null differ
diff --git a/enemies/other/snailWalk1R.png b/enemies/other/snailWalk1R.png
deleted file mode 100644
index 0e4ac9b..0000000
Binary files a/enemies/other/snailWalk1R.png and /dev/null differ
diff --git a/enemies/other/snailWalk2.png b/enemies/other/snailWalk2.png
deleted file mode 100644
index 905df93..0000000
Binary files a/enemies/other/snailWalk2.png and /dev/null differ
diff --git a/enemies/other/snailWalk2R.png b/enemies/other/snailWalk2R.png
deleted file mode 100644
index 7faff8b..0000000
Binary files a/enemies/other/snailWalk2R.png and /dev/null differ
diff --git a/enemies/other/snail_hit.png b/enemies/other/snail_hit.png
deleted file mode 100644
index a9dfba0..0000000
Binary files a/enemies/other/snail_hit.png and /dev/null differ
diff --git a/enemies/other/snail_shell.png b/enemies/other/snail_shell.png
deleted file mode 100644
index d481b5d..0000000
Binary files a/enemies/other/snail_shell.png and /dev/null differ
diff --git a/enemies/other/snail_walk.png b/enemies/other/snail_walk.png
deleted file mode 100644
index ed3def1..0000000
Binary files a/enemies/other/snail_walk.png and /dev/null differ
diff --git a/enemies/other/snake.png b/enemies/other/snake.png
deleted file mode 100644
index 6eb71e4..0000000
Binary files a/enemies/other/snake.png and /dev/null differ
diff --git a/enemies/other/snakeLava.png b/enemies/other/snakeLava.png
deleted file mode 100644
index 89dd34a..0000000
Binary files a/enemies/other/snakeLava.png and /dev/null differ
diff --git a/enemies/other/snakeLava_ani.png b/enemies/other/snakeLava_ani.png
deleted file mode 100644
index 48f2b67..0000000
Binary files a/enemies/other/snakeLava_ani.png and /dev/null differ
diff --git a/enemies/other/snakeLava_dead.png b/enemies/other/snakeLava_dead.png
deleted file mode 100644
index b781113..0000000
Binary files a/enemies/other/snakeLava_dead.png and /dev/null differ
diff --git a/enemies/other/snakeLava_hit.png b/enemies/other/snakeLava_hit.png
deleted file mode 100644
index 18ba7db..0000000
Binary files a/enemies/other/snakeLava_hit.png and /dev/null differ
diff --git a/enemies/other/snakeSlime.png b/enemies/other/snakeSlime.png
deleted file mode 100644
index 354bd54..0000000
Binary files a/enemies/other/snakeSlime.png and /dev/null differ
diff --git a/enemies/other/snakeSlime_ani.png b/enemies/other/snakeSlime_ani.png
deleted file mode 100644
index 6124361..0000000
Binary files a/enemies/other/snakeSlime_ani.png and /dev/null differ
diff --git a/enemies/other/snakeSlime_dead.png b/enemies/other/snakeSlime_dead.png
deleted file mode 100644
index de1e97c..0000000
Binary files a/enemies/other/snakeSlime_dead.png and /dev/null differ
diff --git a/enemies/other/snakeSlime_hit.png b/enemies/other/snakeSlime_hit.png
deleted file mode 100644
index 18ba7db..0000000
Binary files a/enemies/other/snakeSlime_hit.png and /dev/null differ
diff --git a/enemies/other/snake_dead.png b/enemies/other/snake_dead.png
deleted file mode 100644
index 92434a4..0000000
Binary files a/enemies/other/snake_dead.png and /dev/null differ
diff --git a/enemies/other/snake_hit.png b/enemies/other/snake_hit.png
deleted file mode 100644
index e3cfbf2..0000000
Binary files a/enemies/other/snake_hit.png and /dev/null differ
diff --git a/enemies/other/snake_walk.png b/enemies/other/snake_walk.png
deleted file mode 100644
index 463a121..0000000
Binary files a/enemies/other/snake_walk.png and /dev/null differ
diff --git a/enemies/other/spider.png b/enemies/other/spider.png
deleted file mode 100644
index 8f642f7..0000000
Binary files a/enemies/other/spider.png and /dev/null differ
diff --git a/enemies/other/spider_dead.png b/enemies/other/spider_dead.png
deleted file mode 100644
index 9da75f4..0000000
Binary files a/enemies/other/spider_dead.png and /dev/null differ
diff --git a/enemies/other/spider_hit.png b/enemies/other/spider_hit.png
deleted file mode 100644
index 25f5c6c..0000000
Binary files a/enemies/other/spider_hit.png and /dev/null differ
diff --git a/enemies/other/spider_walk1.png b/enemies/other/spider_walk1.png
deleted file mode 100644
index 040bc12..0000000
Binary files a/enemies/other/spider_walk1.png and /dev/null differ
diff --git a/enemies/other/spider_walk2.png b/enemies/other/spider_walk2.png
deleted file mode 100644
index 510f636..0000000
Binary files a/enemies/other/spider_walk2.png and /dev/null differ
diff --git a/enemies/other/spinner.png b/enemies/other/spinner.png
deleted file mode 100644
index af9e129..0000000
Binary files a/enemies/other/spinner.png and /dev/null differ
diff --git a/enemies/other/spinnerHalf.png b/enemies/other/spinnerHalf.png
deleted file mode 100644
index 1488fbd..0000000
Binary files a/enemies/other/spinnerHalf.png and /dev/null differ
diff --git a/enemies/other/spinnerHalf_dead.png b/enemies/other/spinnerHalf_dead.png
deleted file mode 100644
index 6266cdc..0000000
Binary files a/enemies/other/spinnerHalf_dead.png and /dev/null differ
diff --git a/enemies/other/spinnerHalf_hit.png b/enemies/other/spinnerHalf_hit.png
deleted file mode 100644
index 9c1940c..0000000
Binary files a/enemies/other/spinnerHalf_hit.png and /dev/null differ
diff --git a/enemies/other/spinnerHalf_spin.png b/enemies/other/spinnerHalf_spin.png
deleted file mode 100644
index 9267a45..0000000
Binary files a/enemies/other/spinnerHalf_spin.png and /dev/null differ
diff --git a/enemies/other/spinner_dead.png b/enemies/other/spinner_dead.png
deleted file mode 100644
index 429fd2c..0000000
Binary files a/enemies/other/spinner_dead.png and /dev/null differ
diff --git a/enemies/other/spinner_hit.png b/enemies/other/spinner_hit.png
deleted file mode 100644
index 95ecebf..0000000
Binary files a/enemies/other/spinner_hit.png and /dev/null differ
diff --git a/enemies/other/spinner_spin.png b/enemies/other/spinner_spin.png
deleted file mode 100644
index 7ec56ac..0000000
Binary files a/enemies/other/spinner_spin.png and /dev/null differ
diff --git a/enemies/other/worm.png b/enemies/other/worm.png
deleted file mode 100644
index 410f838..0000000
Binary files a/enemies/other/worm.png and /dev/null differ
diff --git a/enemies/other/worm_dead.png b/enemies/other/worm_dead.png
deleted file mode 100644
index 4ca9a7d..0000000
Binary files a/enemies/other/worm_dead.png and /dev/null differ
diff --git a/enemies/other/worm_hit.png b/enemies/other/worm_hit.png
deleted file mode 100644
index e3cfbf2..0000000
Binary files a/enemies/other/worm_hit.png and /dev/null differ
diff --git a/enemies/other/worm_walk.png b/enemies/other/worm_walk.png
deleted file mode 100644
index 53f91b3..0000000
Binary files a/enemies/other/worm_walk.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue.png b/enemies/slime/slimeBlue.png
deleted file mode 100644
index 9cbb8af..0000000
Binary files a/enemies/slime/slimeBlue.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue_blue.png b/enemies/slime/slimeBlue_blue.png
deleted file mode 100644
index adcf34c..0000000
Binary files a/enemies/slime/slimeBlue_blue.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue_dead.png b/enemies/slime/slimeBlue_dead.png
deleted file mode 100644
index 1b25022..0000000
Binary files a/enemies/slime/slimeBlue_dead.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue_hit.png b/enemies/slime/slimeBlue_hit.png
deleted file mode 100644
index 46ce4e2..0000000
Binary files a/enemies/slime/slimeBlue_hit.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue_squashed.png b/enemies/slime/slimeBlue_squashed.png
deleted file mode 100644
index f8f2384..0000000
Binary files a/enemies/slime/slimeBlue_squashed.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue_squashedR.png b/enemies/slime/slimeBlue_squashedR.png
deleted file mode 100644
index e9546b8..0000000
Binary files a/enemies/slime/slimeBlue_squashedR.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue_walk.png b/enemies/slime/slimeBlue_walk.png
deleted file mode 100644
index adcf34c..0000000
Binary files a/enemies/slime/slimeBlue_walk.png and /dev/null differ
diff --git a/enemies/slime/slimeBlue_walkR.png b/enemies/slime/slimeBlue_walkR.png
deleted file mode 100644
index f56f997..0000000
Binary files a/enemies/slime/slimeBlue_walkR.png and /dev/null differ
diff --git a/enemies/slime/slimeDead.png b/enemies/slime/slimeDead.png
deleted file mode 100644
index dce145f..0000000
Binary files a/enemies/slime/slimeDead.png and /dev/null differ
diff --git a/enemies/slime/slimeDeadR.png b/enemies/slime/slimeDeadR.png
deleted file mode 100644
index b8d0246..0000000
Binary files a/enemies/slime/slimeDeadR.png and /dev/null differ
diff --git a/enemies/slime/slimeGreen.png b/enemies/slime/slimeGreen.png
deleted file mode 100644
index 73a48b6..0000000
Binary files a/enemies/slime/slimeGreen.png and /dev/null differ
diff --git a/enemies/slime/slimeGreen_dead.png b/enemies/slime/slimeGreen_dead.png
deleted file mode 100644
index fe1f37f..0000000
Binary files a/enemies/slime/slimeGreen_dead.png and /dev/null differ
diff --git a/enemies/slime/slimeGreen_hit.png b/enemies/slime/slimeGreen_hit.png
deleted file mode 100644
index 46ce4e2..0000000
Binary files a/enemies/slime/slimeGreen_hit.png and /dev/null differ
diff --git a/enemies/slime/slimeGreen_squashed.png b/enemies/slime/slimeGreen_squashed.png
deleted file mode 100644
index 03a735e..0000000
Binary files a/enemies/slime/slimeGreen_squashed.png and /dev/null differ
diff --git a/enemies/slime/slimeGreen_squashedR.png b/enemies/slime/slimeGreen_squashedR.png
deleted file mode 100644
index 9df4f3e..0000000
Binary files a/enemies/slime/slimeGreen_squashedR.png and /dev/null differ
diff --git a/enemies/slime/slimeGreen_walk.png b/enemies/slime/slimeGreen_walk.png
deleted file mode 100644
index 5ff1f49..0000000
Binary files a/enemies/slime/slimeGreen_walk.png and /dev/null differ
diff --git a/enemies/slime/slimeGreen_walkR.png b/enemies/slime/slimeGreen_walkR.png
deleted file mode 100644
index f796814..0000000
Binary files a/enemies/slime/slimeGreen_walkR.png and /dev/null differ
diff --git a/enemies/slime/slimeWalk1.png b/enemies/slime/slimeWalk1.png
deleted file mode 100644
index b284a19..0000000
Binary files a/enemies/slime/slimeWalk1.png and /dev/null differ
diff --git a/enemies/slime/slimeWalk1R.png b/enemies/slime/slimeWalk1R.png
deleted file mode 100644
index d63eec4..0000000
Binary files a/enemies/slime/slimeWalk1R.png and /dev/null differ
diff --git a/enemies/slime/slimeWalk2.png b/enemies/slime/slimeWalk2.png
deleted file mode 100644
index 96b0358..0000000
Binary files a/enemies/slime/slimeWalk2.png and /dev/null differ
diff --git a/enemies/slime/slimeWalk2R.png b/enemies/slime/slimeWalk2R.png
deleted file mode 100644
index 65c8de1..0000000
Binary files a/enemies/slime/slimeWalk2R.png and /dev/null differ
diff --git a/enemies/slime/slime_dead.bmp b/enemies/slime/slime_dead.bmp
deleted file mode 100644
index 00aa5a6..0000000
Binary files a/enemies/slime/slime_dead.bmp and /dev/null differ
diff --git a/enemies/slime/slime_dead_r.bmp b/enemies/slime/slime_dead_r.bmp
deleted file mode 100644
index 19202a0..0000000
Binary files a/enemies/slime/slime_dead_r.bmp and /dev/null differ
diff --git a/enemies/slime/slime_normal.bmp b/enemies/slime/slime_normal.bmp
deleted file mode 100644
index 66f808f..0000000
Binary files a/enemies/slime/slime_normal.bmp and /dev/null differ
diff --git a/enemies/slime/slime_walk.bmp b/enemies/slime/slime_walk.bmp
deleted file mode 100644
index 2eafa79..0000000
Binary files a/enemies/slime/slime_walk.bmp and /dev/null differ
diff --git a/enemies/slime/slime_walk_r.bmp b/enemies/slime/slime_walk_r.bmp
deleted file mode 100644
index 57d7055..0000000
Binary files a/enemies/slime/slime_walk_r.bmp and /dev/null differ
diff --git a/environment/crossover/barnwhole0_0.bmp b/environment/crossover/barnwhole0_0.bmp
deleted file mode 100644
index df56296..0000000
Binary files a/environment/crossover/barnwhole0_0.bmp and /dev/null differ
diff --git a/environment/crossover/bonus.bmp b/environment/crossover/bonus.bmp
deleted file mode 100644
index e464ef7..0000000
Binary files a/environment/crossover/bonus.bmp and /dev/null differ
diff --git a/environment/crossover/bonus_used.bmp b/environment/crossover/bonus_used.bmp
deleted file mode 100644
index 900cfca..0000000
Binary files a/environment/crossover/bonus_used.bmp and /dev/null differ
diff --git a/environment/crossover/coin.bmp b/environment/crossover/coin.bmp
deleted file mode 100644
index 272e4b8..0000000
Binary files a/environment/crossover/coin.bmp and /dev/null differ
diff --git a/environment/crossover/farm.bmp b/environment/crossover/farm.bmp
deleted file mode 100644
index b40e581..0000000
Binary files a/environment/crossover/farm.bmp and /dev/null differ
diff --git a/environment/crossover/fence.bmp b/environment/crossover/fence.bmp
deleted file mode 100644
index 13e69b3..0000000
Binary files a/environment/crossover/fence.bmp and /dev/null differ
diff --git a/environment/crossover/fence_broken.bmp b/environment/crossover/fence_broken.bmp
deleted file mode 100644
index 8157a1c..0000000
Binary files a/environment/crossover/fence_broken.bmp and /dev/null differ
diff --git a/environment/crossover/ground.bmp b/environment/crossover/ground.bmp
deleted file mode 100644
index 8e5a6aa..0000000
Binary files a/environment/crossover/ground.bmp and /dev/null differ
diff --git a/environment/crossover/ground_ice.bmp b/environment/crossover/ground_ice.bmp
deleted file mode 100644
index 230e4cf..0000000
Binary files a/environment/crossover/ground_ice.bmp and /dev/null differ
diff --git a/environment/crossover/ground_snow.bmp b/environment/crossover/ground_snow.bmp
deleted file mode 100644
index 85838ad..0000000
Binary files a/environment/crossover/ground_snow.bmp and /dev/null differ
diff --git a/environment/crossover/lives.bmp b/environment/crossover/lives.bmp
deleted file mode 100644
index 500e8f4..0000000
Binary files a/environment/crossover/lives.bmp and /dev/null differ
diff --git a/environment/main/box.png b/environment/main/box.png
deleted file mode 100644
index 7471ed7..0000000
Binary files a/environment/main/box.png and /dev/null differ
diff --git a/environment/main/boxAlt.png b/environment/main/boxAlt.png
deleted file mode 100644
index 1da31f0..0000000
Binary files a/environment/main/boxAlt.png and /dev/null differ
diff --git a/environment/main/boxCoin.png b/environment/main/boxCoin.png
deleted file mode 100644
index fbba4d3..0000000
Binary files a/environment/main/boxCoin.png and /dev/null differ
diff --git a/environment/main/boxCoinAlt.png b/environment/main/boxCoinAlt.png
deleted file mode 100644
index 8ba823e..0000000
Binary files a/environment/main/boxCoinAlt.png and /dev/null differ
diff --git a/environment/main/boxCoinAlt_disabled.png b/environment/main/boxCoinAlt_disabled.png
deleted file mode 100644
index 9c2f177..0000000
Binary files a/environment/main/boxCoinAlt_disabled.png and /dev/null differ
diff --git a/environment/main/boxCoin_disabled.png b/environment/main/boxCoin_disabled.png
deleted file mode 100644
index 9d114d0..0000000
Binary files a/environment/main/boxCoin_disabled.png and /dev/null differ
diff --git a/environment/main/boxEmpty.png b/environment/main/boxEmpty.png
deleted file mode 100644
index baf0d06..0000000
Binary files a/environment/main/boxEmpty.png and /dev/null differ
diff --git a/environment/main/boxExplosive.png b/environment/main/boxExplosive.png
deleted file mode 100644
index d721258..0000000
Binary files a/environment/main/boxExplosive.png and /dev/null differ
diff --git a/environment/main/boxExplosiveAlt.png b/environment/main/boxExplosiveAlt.png
deleted file mode 100644
index 6a45a15..0000000
Binary files a/environment/main/boxExplosiveAlt.png and /dev/null differ
diff --git a/environment/main/boxExplosive_disabled.png b/environment/main/boxExplosive_disabled.png
deleted file mode 100644
index 4d91170..0000000
Binary files a/environment/main/boxExplosive_disabled.png and /dev/null differ
diff --git a/environment/main/boxItem.png b/environment/main/boxItem.png
deleted file mode 100644
index 9698ae6..0000000
Binary files a/environment/main/boxItem.png and /dev/null differ
diff --git a/environment/main/boxItemAlt.png b/environment/main/boxItemAlt.png
deleted file mode 100644
index 389bf5b..0000000
Binary files a/environment/main/boxItemAlt.png and /dev/null differ
diff --git a/environment/main/boxItemAlt_disabled.png b/environment/main/boxItemAlt_disabled.png
deleted file mode 100644
index dc59a02..0000000
Binary files a/environment/main/boxItemAlt_disabled.png and /dev/null differ
diff --git a/environment/main/boxItem_disabled.png b/environment/main/boxItem_disabled.png
deleted file mode 100644
index e504b99..0000000
Binary files a/environment/main/boxItem_disabled.png and /dev/null differ
diff --git a/environment/main/boxWarning.png b/environment/main/boxWarning.png
deleted file mode 100644
index 7b5a8a2..0000000
Binary files a/environment/main/boxWarning.png and /dev/null differ
diff --git a/environment/main/brickWall.png b/environment/main/brickWall.png
deleted file mode 100644
index 5741fce..0000000
Binary files a/environment/main/brickWall.png and /dev/null differ
diff --git a/environment/main/bridge.png b/environment/main/bridge.png
deleted file mode 100644
index 18c98da..0000000
Binary files a/environment/main/bridge.png and /dev/null differ
diff --git a/environment/main/bridgeLogs.png b/environment/main/bridgeLogs.png
deleted file mode 100644
index a1bb2cf..0000000
Binary files a/environment/main/bridgeLogs.png and /dev/null differ
diff --git a/environment/main/castle.png b/environment/main/castle.png
deleted file mode 100644
index beee256..0000000
Binary files a/environment/main/castle.png and /dev/null differ
diff --git a/environment/main/castleCenter.png b/environment/main/castleCenter.png
deleted file mode 100644
index 0760182..0000000
Binary files a/environment/main/castleCenter.png and /dev/null differ
diff --git a/environment/main/castleCenter_rounded.png b/environment/main/castleCenter_rounded.png
deleted file mode 100644
index dd79858..0000000
Binary files a/environment/main/castleCenter_rounded.png and /dev/null differ
diff --git a/environment/main/castleCliffLeft.png b/environment/main/castleCliffLeft.png
deleted file mode 100644
index b2e3a4e..0000000
Binary files a/environment/main/castleCliffLeft.png and /dev/null differ
diff --git a/environment/main/castleCliffLeftAlt.png b/environment/main/castleCliffLeftAlt.png
deleted file mode 100644
index db501bb..0000000
Binary files a/environment/main/castleCliffLeftAlt.png and /dev/null differ
diff --git a/environment/main/castleCliffRight.png b/environment/main/castleCliffRight.png
deleted file mode 100644
index 1ceccca..0000000
Binary files a/environment/main/castleCliffRight.png and /dev/null differ
diff --git a/environment/main/castleCliffRightAlt.png b/environment/main/castleCliffRightAlt.png
deleted file mode 100644
index 4873409..0000000
Binary files a/environment/main/castleCliffRightAlt.png and /dev/null differ
diff --git a/environment/main/castleHalf.png b/environment/main/castleHalf.png
deleted file mode 100644
index c84bdea..0000000
Binary files a/environment/main/castleHalf.png and /dev/null differ
diff --git a/environment/main/castleHalfLeft.png b/environment/main/castleHalfLeft.png
deleted file mode 100644
index 2c6f4fc..0000000
Binary files a/environment/main/castleHalfLeft.png and /dev/null differ
diff --git a/environment/main/castleHalfMid.png b/environment/main/castleHalfMid.png
deleted file mode 100644
index 58104cd..0000000
Binary files a/environment/main/castleHalfMid.png and /dev/null differ
diff --git a/environment/main/castleHalfRight.png b/environment/main/castleHalfRight.png
deleted file mode 100644
index 7cd9275..0000000
Binary files a/environment/main/castleHalfRight.png and /dev/null differ
diff --git a/environment/main/castleHillLeft.png b/environment/main/castleHillLeft.png
deleted file mode 100644
index 4fdafe7..0000000
Binary files a/environment/main/castleHillLeft.png and /dev/null differ
diff --git a/environment/main/castleHillLeft2.png b/environment/main/castleHillLeft2.png
deleted file mode 100644
index 1424379..0000000
Binary files a/environment/main/castleHillLeft2.png and /dev/null differ
diff --git a/environment/main/castleHillRight.png b/environment/main/castleHillRight.png
deleted file mode 100644
index c9c568d..0000000
Binary files a/environment/main/castleHillRight.png and /dev/null differ
diff --git a/environment/main/castleHillRight2.png b/environment/main/castleHillRight2.png
deleted file mode 100644
index f3a5426..0000000
Binary files a/environment/main/castleHillRight2.png and /dev/null differ
diff --git a/environment/main/castleLedgeRight.png b/environment/main/castleLedgeRight.png
deleted file mode 100644
index df83088..0000000
Binary files a/environment/main/castleLedgeRight.png and /dev/null differ
diff --git a/environment/main/castleLeft.png b/environment/main/castleLeft.png
deleted file mode 100644
index b3e7f64..0000000
Binary files a/environment/main/castleLeft.png and /dev/null differ
diff --git a/environment/main/castleMid.png b/environment/main/castleMid.png
deleted file mode 100644
index 5b7f872..0000000
Binary files a/environment/main/castleMid.png and /dev/null differ
diff --git a/environment/main/castleRight.png b/environment/main/castleRight.png
deleted file mode 100644
index dfeba11..0000000
Binary files a/environment/main/castleRight.png and /dev/null differ
diff --git a/environment/main/coin.bmp b/environment/main/coin.bmp
deleted file mode 100644
index 272e4b8..0000000
Binary files a/environment/main/coin.bmp and /dev/null differ
diff --git a/environment/main/coinGold.png b/environment/main/coinGold.png
deleted file mode 100644
index 721b6ff..0000000
Binary files a/environment/main/coinGold.png and /dev/null differ
diff --git a/environment/main/dirt.png b/environment/main/dirt.png
deleted file mode 100644
index 11b04d6..0000000
Binary files a/environment/main/dirt.png and /dev/null differ
diff --git a/environment/main/dirtCenter.png b/environment/main/dirtCenter.png
deleted file mode 100644
index d8e173f..0000000
Binary files a/environment/main/dirtCenter.png and /dev/null differ
diff --git a/environment/main/dirtCenter_rounded.png b/environment/main/dirtCenter_rounded.png
deleted file mode 100644
index 5cef229..0000000
Binary files a/environment/main/dirtCenter_rounded.png and /dev/null differ
diff --git a/environment/main/dirtCliffLeft.png b/environment/main/dirtCliffLeft.png
deleted file mode 100644
index ec01891..0000000
Binary files a/environment/main/dirtCliffLeft.png and /dev/null differ
diff --git a/environment/main/dirtCliffLeftAlt.png b/environment/main/dirtCliffLeftAlt.png
deleted file mode 100644
index 813a4fa..0000000
Binary files a/environment/main/dirtCliffLeftAlt.png and /dev/null differ
diff --git a/environment/main/dirtCliffRight.png b/environment/main/dirtCliffRight.png
deleted file mode 100644
index c794475..0000000
Binary files a/environment/main/dirtCliffRight.png and /dev/null differ
diff --git a/environment/main/dirtCliffRightAlt.png b/environment/main/dirtCliffRightAlt.png
deleted file mode 100644
index 321bce3..0000000
Binary files a/environment/main/dirtCliffRightAlt.png and /dev/null differ
diff --git a/environment/main/dirtHalf.png b/environment/main/dirtHalf.png
deleted file mode 100644
index e93d379..0000000
Binary files a/environment/main/dirtHalf.png and /dev/null differ
diff --git a/environment/main/dirtHalfLeft.png b/environment/main/dirtHalfLeft.png
deleted file mode 100644
index 13a9d24..0000000
Binary files a/environment/main/dirtHalfLeft.png and /dev/null differ
diff --git a/environment/main/dirtHalfMid.png b/environment/main/dirtHalfMid.png
deleted file mode 100644
index 6b13112..0000000
Binary files a/environment/main/dirtHalfMid.png and /dev/null differ
diff --git a/environment/main/dirtHalfRight.png b/environment/main/dirtHalfRight.png
deleted file mode 100644
index ff08f2c..0000000
Binary files a/environment/main/dirtHalfRight.png and /dev/null differ
diff --git a/environment/main/dirtHillLeft.png b/environment/main/dirtHillLeft.png
deleted file mode 100644
index 4429ec5..0000000
Binary files a/environment/main/dirtHillLeft.png and /dev/null differ
diff --git a/environment/main/dirtHillLeft2.png b/environment/main/dirtHillLeft2.png
deleted file mode 100644
index d8b7664..0000000
Binary files a/environment/main/dirtHillLeft2.png and /dev/null differ
diff --git a/environment/main/dirtHillRight.png b/environment/main/dirtHillRight.png
deleted file mode 100644
index 8f2c39c..0000000
Binary files a/environment/main/dirtHillRight.png and /dev/null differ
diff --git a/environment/main/dirtHillRight2.png b/environment/main/dirtHillRight2.png
deleted file mode 100644
index 1c241f8..0000000
Binary files a/environment/main/dirtHillRight2.png and /dev/null differ
diff --git a/environment/main/dirtLeft.png b/environment/main/dirtLeft.png
deleted file mode 100644
index e0fdf15..0000000
Binary files a/environment/main/dirtLeft.png and /dev/null differ
diff --git a/environment/main/dirtMid.png b/environment/main/dirtMid.png
deleted file mode 100644
index 23e0bda..0000000
Binary files a/environment/main/dirtMid.png and /dev/null differ
diff --git a/environment/main/dirtRight.png b/environment/main/dirtRight.png
deleted file mode 100644
index 0025aa2..0000000
Binary files a/environment/main/dirtRight.png and /dev/null differ
diff --git a/environment/main/door_closedMid.png b/environment/main/door_closedMid.png
deleted file mode 100644
index 9fa891b..0000000
Binary files a/environment/main/door_closedMid.png and /dev/null differ
diff --git a/environment/main/door_closedTop.png b/environment/main/door_closedTop.png
deleted file mode 100644
index e50c479..0000000
Binary files a/environment/main/door_closedTop.png and /dev/null differ
diff --git a/environment/main/door_openMid.png b/environment/main/door_openMid.png
deleted file mode 100644
index ae20a02..0000000
Binary files a/environment/main/door_openMid.png and /dev/null differ
diff --git a/environment/main/door_openTop.png b/environment/main/door_openTop.png
deleted file mode 100644
index 6af5862..0000000
Binary files a/environment/main/door_openTop.png and /dev/null differ
diff --git a/environment/main/explosion0.png b/environment/main/explosion0.png
deleted file mode 100644
index 86ed3ca..0000000
Binary files a/environment/main/explosion0.png and /dev/null differ
diff --git a/environment/main/explosion1.png b/environment/main/explosion1.png
deleted file mode 100644
index 94a331f..0000000
Binary files a/environment/main/explosion1.png and /dev/null differ
diff --git a/environment/main/explosion2.png b/environment/main/explosion2.png
deleted file mode 100644
index 72c4735..0000000
Binary files a/environment/main/explosion2.png and /dev/null differ
diff --git a/environment/main/fence.png b/environment/main/fence.png
deleted file mode 100644
index bf1e9be..0000000
Binary files a/environment/main/fence.png and /dev/null differ
diff --git a/environment/main/fenceBroken.png b/environment/main/fenceBroken.png
deleted file mode 100644
index 8c055c5..0000000
Binary files a/environment/main/fenceBroken.png and /dev/null differ
diff --git a/environment/main/grass.png b/environment/main/grass.png
deleted file mode 100644
index 2d2b7fd..0000000
Binary files a/environment/main/grass.png and /dev/null differ
diff --git a/environment/main/grassCenter.png b/environment/main/grassCenter.png
deleted file mode 100644
index 15650b4..0000000
Binary files a/environment/main/grassCenter.png and /dev/null differ
diff --git a/environment/main/grassCenter_rounded.png b/environment/main/grassCenter_rounded.png
deleted file mode 100644
index a2c28b6..0000000
Binary files a/environment/main/grassCenter_rounded.png and /dev/null differ
diff --git a/environment/main/grassCliffLeft.png b/environment/main/grassCliffLeft.png
deleted file mode 100644
index 68353e8..0000000
Binary files a/environment/main/grassCliffLeft.png and /dev/null differ
diff --git a/environment/main/grassCliffLeftAlt.png b/environment/main/grassCliffLeftAlt.png
deleted file mode 100644
index a7bf532..0000000
Binary files a/environment/main/grassCliffLeftAlt.png and /dev/null differ
diff --git a/environment/main/grassCliffRight.png b/environment/main/grassCliffRight.png
deleted file mode 100644
index a629213..0000000
Binary files a/environment/main/grassCliffRight.png and /dev/null differ
diff --git a/environment/main/grassCliffRightAlt.png b/environment/main/grassCliffRightAlt.png
deleted file mode 100644
index 05de3fa..0000000
Binary files a/environment/main/grassCliffRightAlt.png and /dev/null differ
diff --git a/environment/main/grassHalf.png b/environment/main/grassHalf.png
deleted file mode 100644
index f6c6ae0..0000000
Binary files a/environment/main/grassHalf.png and /dev/null differ
diff --git a/environment/main/grassHalfLeft.png b/environment/main/grassHalfLeft.png
deleted file mode 100644
index d815562..0000000
Binary files a/environment/main/grassHalfLeft.png and /dev/null differ
diff --git a/environment/main/grassHalfMid.png b/environment/main/grassHalfMid.png
deleted file mode 100644
index 43ee4fd..0000000
Binary files a/environment/main/grassHalfMid.png and /dev/null differ
diff --git a/environment/main/grassHalfRight.png b/environment/main/grassHalfRight.png
deleted file mode 100644
index 4e4e04f..0000000
Binary files a/environment/main/grassHalfRight.png and /dev/null differ
diff --git a/environment/main/grassHillLeft.png b/environment/main/grassHillLeft.png
deleted file mode 100644
index 46ab865..0000000
Binary files a/environment/main/grassHillLeft.png and /dev/null differ
diff --git a/environment/main/grassHillLeft2.png b/environment/main/grassHillLeft2.png
deleted file mode 100644
index 3682219..0000000
Binary files a/environment/main/grassHillLeft2.png and /dev/null differ
diff --git a/environment/main/grassHillRight.png b/environment/main/grassHillRight.png
deleted file mode 100644
index 71e35f6..0000000
Binary files a/environment/main/grassHillRight.png and /dev/null differ
diff --git a/environment/main/grassHillRight2.png b/environment/main/grassHillRight2.png
deleted file mode 100644
index f5f766d..0000000
Binary files a/environment/main/grassHillRight2.png and /dev/null differ
diff --git a/environment/main/grassLedgeLeft.png b/environment/main/grassLedgeLeft.png
deleted file mode 100644
index 169e31a..0000000
Binary files a/environment/main/grassLedgeLeft.png and /dev/null differ
diff --git a/environment/main/grassLedgeRight.png b/environment/main/grassLedgeRight.png
deleted file mode 100644
index 64412ff..0000000
Binary files a/environment/main/grassLedgeRight.png and /dev/null differ
diff --git a/environment/main/grassLeft.png b/environment/main/grassLeft.png
deleted file mode 100644
index 2f24f39..0000000
Binary files a/environment/main/grassLeft.png and /dev/null differ
diff --git a/environment/main/grassMid.png b/environment/main/grassMid.png
deleted file mode 100644
index 035adda..0000000
Binary files a/environment/main/grassMid.png and /dev/null differ
diff --git a/environment/main/grassRight.png b/environment/main/grassRight.png
deleted file mode 100644
index 53f4d96..0000000
Binary files a/environment/main/grassRight.png and /dev/null differ
diff --git a/environment/main/hill_large.png b/environment/main/hill_large.png
deleted file mode 100644
index 95562ae..0000000
Binary files a/environment/main/hill_large.png and /dev/null differ
diff --git a/environment/main/hill_largeAlt.png b/environment/main/hill_largeAlt.png
deleted file mode 100644
index cd6585c..0000000
Binary files a/environment/main/hill_largeAlt.png and /dev/null differ
diff --git a/environment/main/hill_small.png b/environment/main/hill_small.png
deleted file mode 100644
index 5446884..0000000
Binary files a/environment/main/hill_small.png and /dev/null differ
diff --git a/environment/main/hill_smallAlt.png b/environment/main/hill_smallAlt.png
deleted file mode 100644
index d4abd13..0000000
Binary files a/environment/main/hill_smallAlt.png and /dev/null differ
diff --git a/environment/main/keyblue.png b/environment/main/keyblue.png
deleted file mode 100644
index af17f80..0000000
Binary files a/environment/main/keyblue.png and /dev/null differ
diff --git a/environment/main/keygreen.png b/environment/main/keygreen.png
deleted file mode 100644
index 839294e..0000000
Binary files a/environment/main/keygreen.png and /dev/null differ
diff --git a/environment/main/keyred.png b/environment/main/keyred.png
deleted file mode 100644
index e2ebd91..0000000
Binary files a/environment/main/keyred.png and /dev/null differ
diff --git a/environment/main/keyyellow.png b/environment/main/keyyellow.png
deleted file mode 100644
index bc58e18..0000000
Binary files a/environment/main/keyyellow.png and /dev/null differ
diff --git a/environment/main/ladder_mid.png b/environment/main/ladder_mid.png
deleted file mode 100644
index 9b5eee9..0000000
Binary files a/environment/main/ladder_mid.png and /dev/null differ
diff --git a/environment/main/ladder_top.png b/environment/main/ladder_top.png
deleted file mode 100644
index 7e51171..0000000
Binary files a/environment/main/ladder_top.png and /dev/null differ
diff --git a/environment/main/liquidLava.png b/environment/main/liquidLava.png
deleted file mode 100644
index a364798..0000000
Binary files a/environment/main/liquidLava.png and /dev/null differ
diff --git a/environment/main/liquidLavaTop.png b/environment/main/liquidLavaTop.png
deleted file mode 100644
index 23a798b..0000000
Binary files a/environment/main/liquidLavaTop.png and /dev/null differ
diff --git a/environment/main/liquidLavaTop_mid.png b/environment/main/liquidLavaTop_mid.png
deleted file mode 100644
index ad70b55..0000000
Binary files a/environment/main/liquidLavaTop_mid.png and /dev/null differ
diff --git a/environment/main/liquidWater.png b/environment/main/liquidWater.png
deleted file mode 100644
index 6fbc63d..0000000
Binary files a/environment/main/liquidWater.png and /dev/null differ
diff --git a/environment/main/liquidWaterTop.png b/environment/main/liquidWaterTop.png
deleted file mode 100644
index c3a5756..0000000
Binary files a/environment/main/liquidWaterTop.png and /dev/null differ
diff --git a/environment/main/liquidWaterTop_mid.png b/environment/main/liquidWaterTop_mid.png
deleted file mode 100644
index 004ebdc..0000000
Binary files a/environment/main/liquidWaterTop_mid.png and /dev/null differ
diff --git a/environment/main/lock_blue.png b/environment/main/lock_blue.png
deleted file mode 100644
index a2d073b..0000000
Binary files a/environment/main/lock_blue.png and /dev/null differ
diff --git a/environment/main/lock_green.png b/environment/main/lock_green.png
deleted file mode 100644
index 983e9ff..0000000
Binary files a/environment/main/lock_green.png and /dev/null differ
diff --git a/environment/main/lock_red.png b/environment/main/lock_red.png
deleted file mode 100644
index 3394335..0000000
Binary files a/environment/main/lock_red.png and /dev/null differ
diff --git a/environment/main/lock_yellow.png b/environment/main/lock_yellow.png
deleted file mode 100644
index d7c36bd..0000000
Binary files a/environment/main/lock_yellow.png and /dev/null differ
diff --git a/environment/main/rockHillLeft.png b/environment/main/rockHillLeft.png
deleted file mode 100644
index ee0ef86..0000000
Binary files a/environment/main/rockHillLeft.png and /dev/null differ
diff --git a/environment/main/rockHillRight.png b/environment/main/rockHillRight.png
deleted file mode 100644
index 2716df5..0000000
Binary files a/environment/main/rockHillRight.png and /dev/null differ
diff --git a/environment/main/ropeAttached.png b/environment/main/ropeAttached.png
deleted file mode 100644
index c0afebf..0000000
Binary files a/environment/main/ropeAttached.png and /dev/null differ
diff --git a/environment/main/ropeHorizontal.png b/environment/main/ropeHorizontal.png
deleted file mode 100644
index 6e8379d..0000000
Binary files a/environment/main/ropeHorizontal.png and /dev/null differ
diff --git a/environment/main/ropeVertical.png b/environment/main/ropeVertical.png
deleted file mode 100644
index c52e38b..0000000
Binary files a/environment/main/ropeVertical.png and /dev/null differ
diff --git a/environment/main/sand.png b/environment/main/sand.png
deleted file mode 100644
index 97e939c..0000000
Binary files a/environment/main/sand.png and /dev/null differ
diff --git a/environment/main/sandCenter.png b/environment/main/sandCenter.png
deleted file mode 100644
index 15650b4..0000000
Binary files a/environment/main/sandCenter.png and /dev/null differ
diff --git a/environment/main/sandCenter_rounded.png b/environment/main/sandCenter_rounded.png
deleted file mode 100644
index a2c28b6..0000000
Binary files a/environment/main/sandCenter_rounded.png and /dev/null differ
diff --git a/environment/main/sandCliffLeft.png b/environment/main/sandCliffLeft.png
deleted file mode 100644
index ec19291..0000000
Binary files a/environment/main/sandCliffLeft.png and /dev/null differ
diff --git a/environment/main/sandCliffLeftAlt.png b/environment/main/sandCliffLeftAlt.png
deleted file mode 100644
index 2393855..0000000
Binary files a/environment/main/sandCliffLeftAlt.png and /dev/null differ
diff --git a/environment/main/sandCliffRight.png b/environment/main/sandCliffRight.png
deleted file mode 100644
index 73dd387..0000000
Binary files a/environment/main/sandCliffRight.png and /dev/null differ
diff --git a/environment/main/sandCliffRightAlt.png b/environment/main/sandCliffRightAlt.png
deleted file mode 100644
index 8ccf6c8..0000000
Binary files a/environment/main/sandCliffRightAlt.png and /dev/null differ
diff --git a/environment/main/sandHalf.png b/environment/main/sandHalf.png
deleted file mode 100644
index a89e8de..0000000
Binary files a/environment/main/sandHalf.png and /dev/null differ
diff --git a/environment/main/sandHalfLeft.png b/environment/main/sandHalfLeft.png
deleted file mode 100644
index e5618fe..0000000
Binary files a/environment/main/sandHalfLeft.png and /dev/null differ
diff --git a/environment/main/sandHalfMid.png b/environment/main/sandHalfMid.png
deleted file mode 100644
index 8228842..0000000
Binary files a/environment/main/sandHalfMid.png and /dev/null differ
diff --git a/environment/main/sandHalfRight.png b/environment/main/sandHalfRight.png
deleted file mode 100644
index 5ac3297..0000000
Binary files a/environment/main/sandHalfRight.png and /dev/null differ
diff --git a/environment/main/sandHillLeft.png b/environment/main/sandHillLeft.png
deleted file mode 100644
index 7d63b71..0000000
Binary files a/environment/main/sandHillLeft.png and /dev/null differ
diff --git a/environment/main/sandHillLeft2.png b/environment/main/sandHillLeft2.png
deleted file mode 100644
index a4b6f53..0000000
Binary files a/environment/main/sandHillLeft2.png and /dev/null differ
diff --git a/environment/main/sandHillRight.png b/environment/main/sandHillRight.png
deleted file mode 100644
index f6c4879..0000000
Binary files a/environment/main/sandHillRight.png and /dev/null differ
diff --git a/environment/main/sandHillRight2.png b/environment/main/sandHillRight2.png
deleted file mode 100644
index 9ede52d..0000000
Binary files a/environment/main/sandHillRight2.png and /dev/null differ
diff --git a/environment/main/sandLedgeLeft.png b/environment/main/sandLedgeLeft.png
deleted file mode 100644
index 8da54b0..0000000
Binary files a/environment/main/sandLedgeLeft.png and /dev/null differ
diff --git a/environment/main/sandLedgeRight.png b/environment/main/sandLedgeRight.png
deleted file mode 100644
index ae0d657..0000000
Binary files a/environment/main/sandLedgeRight.png and /dev/null differ
diff --git a/environment/main/sandLeft.png b/environment/main/sandLeft.png
deleted file mode 100644
index 4b68c87..0000000
Binary files a/environment/main/sandLeft.png and /dev/null differ
diff --git a/environment/main/sandMid.png b/environment/main/sandMid.png
deleted file mode 100644
index 0a60267..0000000
Binary files a/environment/main/sandMid.png and /dev/null differ
diff --git a/environment/main/sandRight.png b/environment/main/sandRight.png
deleted file mode 100644
index f29103d..0000000
Binary files a/environment/main/sandRight.png and /dev/null differ
diff --git a/environment/main/sign.png b/environment/main/sign.png
deleted file mode 100644
index 19b7d37..0000000
Binary files a/environment/main/sign.png and /dev/null differ
diff --git a/environment/main/signExit.png b/environment/main/signExit.png
deleted file mode 100644
index 37ee36e..0000000
Binary files a/environment/main/signExit.png and /dev/null differ
diff --git a/environment/main/signLeft.png b/environment/main/signLeft.png
deleted file mode 100644
index eb297d6..0000000
Binary files a/environment/main/signLeft.png and /dev/null differ
diff --git a/environment/main/signRight.png b/environment/main/signRight.png
deleted file mode 100644
index 32b0292..0000000
Binary files a/environment/main/signRight.png and /dev/null differ
diff --git a/environment/main/snow.png b/environment/main/snow.png
deleted file mode 100644
index a194bdc..0000000
Binary files a/environment/main/snow.png and /dev/null differ
diff --git a/environment/main/snowCenter.png b/environment/main/snowCenter.png
deleted file mode 100644
index c3f492f..0000000
Binary files a/environment/main/snowCenter.png and /dev/null differ
diff --git a/environment/main/snowCenter_rounded.png b/environment/main/snowCenter_rounded.png
deleted file mode 100644
index b6d8eb4..0000000
Binary files a/environment/main/snowCenter_rounded.png and /dev/null differ
diff --git a/environment/main/snowCliffLeft.png b/environment/main/snowCliffLeft.png
deleted file mode 100644
index b6a5eba..0000000
Binary files a/environment/main/snowCliffLeft.png and /dev/null differ
diff --git a/environment/main/snowCliffLeftAlt.png b/environment/main/snowCliffLeftAlt.png
deleted file mode 100644
index cb08d33..0000000
Binary files a/environment/main/snowCliffLeftAlt.png and /dev/null differ
diff --git a/environment/main/snowCliffRight.png b/environment/main/snowCliffRight.png
deleted file mode 100644
index fdb5e4b..0000000
Binary files a/environment/main/snowCliffRight.png and /dev/null differ
diff --git a/environment/main/snowCliffRightAlt.png b/environment/main/snowCliffRightAlt.png
deleted file mode 100644
index ef0faeb..0000000
Binary files a/environment/main/snowCliffRightAlt.png and /dev/null differ
diff --git a/environment/main/snowHalf.png b/environment/main/snowHalf.png
deleted file mode 100644
index 7e9a947..0000000
Binary files a/environment/main/snowHalf.png and /dev/null differ
diff --git a/environment/main/snowHalfLeft.png b/environment/main/snowHalfLeft.png
deleted file mode 100644
index a9d98a9..0000000
Binary files a/environment/main/snowHalfLeft.png and /dev/null differ
diff --git a/environment/main/snowHalfMid.png b/environment/main/snowHalfMid.png
deleted file mode 100644
index cf31bdc..0000000
Binary files a/environment/main/snowHalfMid.png and /dev/null differ
diff --git a/environment/main/snowHalfRight.png b/environment/main/snowHalfRight.png
deleted file mode 100644
index 3f5927b..0000000
Binary files a/environment/main/snowHalfRight.png and /dev/null differ
diff --git a/environment/main/snowHillLeft.png b/environment/main/snowHillLeft.png
deleted file mode 100644
index 867beb7..0000000
Binary files a/environment/main/snowHillLeft.png and /dev/null differ
diff --git a/environment/main/snowHillLeft2.png b/environment/main/snowHillLeft2.png
deleted file mode 100644
index 8f67c0e..0000000
Binary files a/environment/main/snowHillLeft2.png and /dev/null differ
diff --git a/environment/main/snowHillRight.png b/environment/main/snowHillRight.png
deleted file mode 100644
index 16e64fc..0000000
Binary files a/environment/main/snowHillRight.png and /dev/null differ
diff --git a/environment/main/snowHillRight2.png b/environment/main/snowHillRight2.png
deleted file mode 100644
index 71cfb11..0000000
Binary files a/environment/main/snowHillRight2.png and /dev/null differ
diff --git a/environment/main/snowLedgeLeft.png b/environment/main/snowLedgeLeft.png
deleted file mode 100644
index 3dd213d..0000000
Binary files a/environment/main/snowLedgeLeft.png and /dev/null differ
diff --git a/environment/main/snowLedgeRight.png b/environment/main/snowLedgeRight.png
deleted file mode 100644
index 61607a4..0000000
Binary files a/environment/main/snowLedgeRight.png and /dev/null differ
diff --git a/environment/main/snowLeft.png b/environment/main/snowLeft.png
deleted file mode 100644
index 5d0874a..0000000
Binary files a/environment/main/snowLeft.png and /dev/null differ
diff --git a/environment/main/snowMid.png b/environment/main/snowMid.png
deleted file mode 100644
index 07ad2a4..0000000
Binary files a/environment/main/snowMid.png and /dev/null differ
diff --git a/environment/main/snowRight.png b/environment/main/snowRight.png
deleted file mode 100644
index 23cf323..0000000
Binary files a/environment/main/snowRight.png and /dev/null differ
diff --git a/environment/main/spikeTop.png b/environment/main/spikeTop.png
deleted file mode 100644
index 06c57c7..0000000
Binary files a/environment/main/spikeTop.png and /dev/null differ
diff --git a/environment/main/spikesBottom.png b/environment/main/spikesBottom.png
deleted file mode 100644
index 8ca0bbf..0000000
Binary files a/environment/main/spikesBottom.png and /dev/null differ
diff --git a/environment/main/spikesBottomAlt.png b/environment/main/spikesBottomAlt.png
deleted file mode 100644
index f93ccf8..0000000
Binary files a/environment/main/spikesBottomAlt.png and /dev/null differ
diff --git a/environment/main/spikesBottomAlt2.png b/environment/main/spikesBottomAlt2.png
deleted file mode 100644
index 305b4c8..0000000
Binary files a/environment/main/spikesBottomAlt2.png and /dev/null differ
diff --git a/environment/main/spikesTop.png b/environment/main/spikesTop.png
deleted file mode 100644
index 3926a47..0000000
Binary files a/environment/main/spikesTop.png and /dev/null differ
diff --git a/environment/main/spikesTopAlt.png b/environment/main/spikesTopAlt.png
deleted file mode 100644
index 77a2ec6..0000000
Binary files a/environment/main/spikesTopAlt.png and /dev/null differ
diff --git a/environment/main/spikesTopAlt2.png b/environment/main/spikesTopAlt2.png
deleted file mode 100644
index 3d1addc..0000000
Binary files a/environment/main/spikesTopAlt2.png and /dev/null differ
diff --git a/environment/main/stone.png b/environment/main/stone.png
deleted file mode 100644
index 3f60ba5..0000000
Binary files a/environment/main/stone.png and /dev/null differ
diff --git a/environment/main/stoneCenter.png b/environment/main/stoneCenter.png
deleted file mode 100644
index e0149db..0000000
Binary files a/environment/main/stoneCenter.png and /dev/null differ
diff --git a/environment/main/stoneCenter_rounded.png b/environment/main/stoneCenter_rounded.png
deleted file mode 100644
index c98d051..0000000
Binary files a/environment/main/stoneCenter_rounded.png and /dev/null differ
diff --git a/environment/main/stoneCliffLeft.png b/environment/main/stoneCliffLeft.png
deleted file mode 100644
index 5cb7897..0000000
Binary files a/environment/main/stoneCliffLeft.png and /dev/null differ
diff --git a/environment/main/stoneCliffLeftAlt.png b/environment/main/stoneCliffLeftAlt.png
deleted file mode 100644
index 2ce63c5..0000000
Binary files a/environment/main/stoneCliffLeftAlt.png and /dev/null differ
diff --git a/environment/main/stoneCliffRight.png b/environment/main/stoneCliffRight.png
deleted file mode 100644
index 79999e6..0000000
Binary files a/environment/main/stoneCliffRight.png and /dev/null differ
diff --git a/environment/main/stoneCliffRightAlt.png b/environment/main/stoneCliffRightAlt.png
deleted file mode 100644
index b011b1f..0000000
Binary files a/environment/main/stoneCliffRightAlt.png and /dev/null differ
diff --git a/environment/main/stoneHalf.png b/environment/main/stoneHalf.png
deleted file mode 100644
index af930eb..0000000
Binary files a/environment/main/stoneHalf.png and /dev/null differ
diff --git a/environment/main/stoneHalfLeft.png b/environment/main/stoneHalfLeft.png
deleted file mode 100644
index e8351e0..0000000
Binary files a/environment/main/stoneHalfLeft.png and /dev/null differ
diff --git a/environment/main/stoneHalfMid.png b/environment/main/stoneHalfMid.png
deleted file mode 100644
index bf93035..0000000
Binary files a/environment/main/stoneHalfMid.png and /dev/null differ
diff --git a/environment/main/stoneHalfRight.png b/environment/main/stoneHalfRight.png
deleted file mode 100644
index 36c7167..0000000
Binary files a/environment/main/stoneHalfRight.png and /dev/null differ
diff --git a/environment/main/stoneHillLeft2.png b/environment/main/stoneHillLeft2.png
deleted file mode 100644
index b6fee0e..0000000
Binary files a/environment/main/stoneHillLeft2.png and /dev/null differ
diff --git a/environment/main/stoneHillRight2.png b/environment/main/stoneHillRight2.png
deleted file mode 100644
index 0e20570..0000000
Binary files a/environment/main/stoneHillRight2.png and /dev/null differ
diff --git a/environment/main/stoneLedgeLeft.png b/environment/main/stoneLedgeLeft.png
deleted file mode 100644
index 18b7901..0000000
Binary files a/environment/main/stoneLedgeLeft.png and /dev/null differ
diff --git a/environment/main/stoneLedgeRight.png b/environment/main/stoneLedgeRight.png
deleted file mode 100644
index 4b54abd..0000000
Binary files a/environment/main/stoneLedgeRight.png and /dev/null differ
diff --git a/environment/main/stoneLeft.png b/environment/main/stoneLeft.png
deleted file mode 100644
index 90edc01..0000000
Binary files a/environment/main/stoneLeft.png and /dev/null differ
diff --git a/environment/main/stoneMid.png b/environment/main/stoneMid.png
deleted file mode 100644
index e6dc76f..0000000
Binary files a/environment/main/stoneMid.png and /dev/null differ
diff --git a/environment/main/stoneRight.png b/environment/main/stoneRight.png
deleted file mode 100644
index 5c7acdc..0000000
Binary files a/environment/main/stoneRight.png and /dev/null differ
diff --git a/environment/main/stoneWall.png b/environment/main/stoneWall.png
deleted file mode 100644
index ff49f73..0000000
Binary files a/environment/main/stoneWall.png and /dev/null differ
diff --git a/environment/main/tiles_spritesheet.png b/environment/main/tiles_spritesheet.png
deleted file mode 100644
index 57ee83b..0000000
Binary files a/environment/main/tiles_spritesheet.png and /dev/null differ
diff --git a/environment/main/tochLit.png b/environment/main/tochLit.png
deleted file mode 100644
index 9e66647..0000000
Binary files a/environment/main/tochLit.png and /dev/null differ
diff --git a/environment/main/tochLit2.png b/environment/main/tochLit2.png
deleted file mode 100644
index 6d5555f..0000000
Binary files a/environment/main/tochLit2.png and /dev/null differ
diff --git a/environment/main/torch.png b/environment/main/torch.png
deleted file mode 100644
index 20bfeb4..0000000
Binary files a/environment/main/torch.png and /dev/null differ
diff --git a/environment/main/torchLit.png b/environment/main/torchLit.png
deleted file mode 100644
index 9e66647..0000000
Binary files a/environment/main/torchLit.png and /dev/null differ
diff --git a/environment/main/torchLit2.png b/environment/main/torchLit2.png
deleted file mode 100644
index 6d5555f..0000000
Binary files a/environment/main/torchLit2.png and /dev/null differ
diff --git a/environment/main/window.png b/environment/main/window.png
deleted file mode 100644
index bfde7a0..0000000
Binary files a/environment/main/window.png and /dev/null differ
diff --git a/environment/unused/backgrounds.png b/environment/unused/backgrounds.png
deleted file mode 100644
index 20e76c0..0000000
Binary files a/environment/unused/backgrounds.png and /dev/null differ
diff --git a/environment/unused/barnwhole0_0.bmp b/environment/unused/barnwhole0_0.bmp
deleted file mode 100644
index df56296..0000000
Binary files a/environment/unused/barnwhole0_0.bmp and /dev/null differ
diff --git a/environment/unused/bonus.bmp b/environment/unused/bonus.bmp
deleted file mode 100644
index e464ef7..0000000
Binary files a/environment/unused/bonus.bmp and /dev/null differ
diff --git a/environment/unused/bonus_used.bmp b/environment/unused/bonus_used.bmp
deleted file mode 100644
index 900cfca..0000000
Binary files a/environment/unused/bonus_used.bmp and /dev/null differ
diff --git a/environment/unused/coin.bmp b/environment/unused/coin.bmp
deleted file mode 100644
index 272e4b8..0000000
Binary files a/environment/unused/coin.bmp and /dev/null differ
diff --git a/environment/unused/farm.bmp b/environment/unused/farm.bmp
deleted file mode 100644
index b40e581..0000000
Binary files a/environment/unused/farm.bmp and /dev/null differ
diff --git a/environment/unused/fence.bmp b/environment/unused/fence.bmp
deleted file mode 100644
index 13e69b3..0000000
Binary files a/environment/unused/fence.bmp and /dev/null differ
diff --git a/environment/unused/fence_broken.bmp b/environment/unused/fence_broken.bmp
deleted file mode 100644
index 8157a1c..0000000
Binary files a/environment/unused/fence_broken.bmp and /dev/null differ
diff --git a/environment/unused/ground.bmp b/environment/unused/ground.bmp
deleted file mode 100644
index 8e5a6aa..0000000
Binary files a/environment/unused/ground.bmp and /dev/null differ
diff --git a/environment/unused/ground_ice.bmp b/environment/unused/ground_ice.bmp
deleted file mode 100644
index 230e4cf..0000000
Binary files a/environment/unused/ground_ice.bmp and /dev/null differ
diff --git a/environment/unused/ground_snow.bmp b/environment/unused/ground_snow.bmp
deleted file mode 100644
index 85838ad..0000000
Binary files a/environment/unused/ground_snow.bmp and /dev/null differ
diff --git a/environment/unused/license.txt b/environment/unused/license.txt
deleted file mode 100644
index bd96c69..0000000
--- a/environment/unused/license.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-###############################################################################
-
- Platformer Art Deluxe (Pixel Redux) by Kenney Vleugels (www.kenney.nl)
-
- ------------------------------
-
- License (CC0)
- http://creativecommons.org/publicdomain/zero/1.0/
-
- You may use these graphics in personal and commercial projects.
- Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
-
-###############################################################################
\ No newline at end of file
diff --git a/environment/unused/lives.bmp b/environment/unused/lives.bmp
deleted file mode 100644
index 500e8f4..0000000
Binary files a/environment/unused/lives.bmp and /dev/null differ
diff --git a/environment/unused/sample.png b/environment/unused/sample.png
deleted file mode 100644
index 00c4f17..0000000
Binary files a/environment/unused/sample.png and /dev/null differ
diff --git a/environment/unused/spritesheet.png b/environment/unused/spritesheet.png
deleted file mode 100644
index 02dc214..0000000
Binary files a/environment/unused/spritesheet.png and /dev/null differ
diff --git a/game.py b/game.py
deleted file mode 100644
index 49a9dd1..0000000
--- a/game.py
+++ /dev/null
@@ -1,641 +0,0 @@
-# coding=utf-8
-from random import randint, shuffle
-import pygame, sys, math
-from pygame.locals import *
-from aicharacter import AICharacter
-from backgroundfoliage import BackgroundFoliage
-from block import Block
-from door import Door
-from key import Key
-from platform import Platform
-from playablecharacter import PlayableCharacter
-from pool import Pool
-from spike import FallingSpike
-
-# Colours
-white = (255, 255, 255)
-grey = (185, 185, 185)
-black = (0, 0, 0)
-red = (155, 0, 0)
-brightred = (175, 20, 20)
-green = (0, 155, 0)
-brightgreen = ( 20, 175, 20)
-blue = (0, 0, 155)
-brightblue = (20, 20, 175)
-yellow = (255, 255, 0)
-
-c = None
-
-class Game(object):
-
- def __init__(self):
- pygame.mixer.pre_init(48000, -16, 2, 4096)
- pygame.mixer.init()
- pygame.mixer.set_num_channels(20)
- pygame.init()
-
- # Initialize control variables for the game
- self.developerMode = True
- self.antialiasing = True
- self.stableFPS = True
- self.decorations = True
- self.fpsClock = pygame.time.Clock()
- self.desiredFPS = 60
- self.fps, self.measuredFPS = self.desiredFPS, self.desiredFPS
- self.screenW = pygame.display.list_modes()[0][0]
- self.screenH = pygame.display.list_modes()[0][1]
- self.caption = 'Exit Dash - Hyperion'
- self.displaysurf = pygame.display.set_mode((self.screenW, self.screenH), pygame.FULLSCREEN | pygame.HWACCEL |
- pygame.ASYNCBLIT | pygame.HWSURFACE | pygame.DOUBLEBUF)
- if pygame.display.mode_ok((self.screenW, self.screenH), pygame.FULLSCREEN | pygame.HWACCEL |
- pygame.ASYNCBLIT | pygame.HWSURFACE | pygame.DOUBLEBUF) == 0:
- self.displaysurf = pygame.display.set_mode((self.screenW, self.screenH), pygame.FULLSCREEN)
- pygame.display.set_caption(self.caption)
- self.displayingOptions = False
- self.allMovableObjects, self.mobs = [], []
- self.defaultValue = -999
- self.levelDelay = 50
- self.devInfoX = self.screenW - 350
- self.devInfoY = 50
- self.devSpacing = 32
- self.mousex, self.mousey, self.mousex_hover, self.mousey_hover = 0, 0, 0, 0
- self.currLevel = 0
-
- # Fonts
- self.genericFont = pygame.font.Font('fonts\\gamecuben.ttf', 32)
- self.medFont = pygame.font.Font('fonts\\jetset.ttf', 24)
- self.smlFont = pygame.font.Font('fonts\\atari.ttf', 16)
-
- # Backgrounds
- self.origin = (0, 0)
- self.bgrdTitle = pygame.image.load('backgrounds\\main\\aquatiled_jordan_irwin.png').convert()
- self.bgrdGloomy = pygame.image.load('backgrounds\\main\\red_sky.jpg').convert()
- self.bgrdGloomyInv = pygame.image.load('backgrounds\\main\\red_sky_inverted.jpg').convert()
- self.bgrdYellowSky = pygame.image.load('backgrounds\\main\\yellow-sky.jpg').convert()
- self.bgrdYellowSkyInv = pygame.image.load('backgrounds\\main\\yellow-sky-inverted.jpg').convert()
- self.bgrdCastle = pygame.image.load('backgrounds\\main\\bg_castle.png').convert()
- self.bgrdCastleInv = pygame.image.load('backgrounds\\main\\bg_castle_inv.png').convert()
- self.bgrdCastle = pygame.transform.smoothscale(self.bgrdCastle, (3 * pygame.Surface.get_width(self.bgrdCastle),
- 3 * pygame.Surface.get_height(self.bgrdCastle)))
- self.bgrdCastleInv = pygame.transform.smoothscale(self.bgrdCastleInv, (pygame.Surface.get_width
- (self.bgrdCastle),
- pygame.Surface.get_height(self.bgrdCastle)))
- self.bgrdDesert = pygame.image.load('backgrounds\\main\\bg_desert.png').convert()
- self.bgrdDesertInv = pygame.image.load('backgrounds\\main\\bg_desert_inv.png').convert()
- self.initialBgrdSetup = True
- self.bgrdX, self.bgrdY, self.bgrdInvX = 0, 0, 0
-
- # --------------------------------------------------------------------------------------------------------------
-
- def printText(self,text, font, colour, coords):
- textSurf = font.render(text, self.antialiasing, colour)
- textRect = textSurf.get_rect()
- textRect.topleft = coords
- self.displaysurf.blit(textSurf, textRect)
- return textRect
-
- # --------------------------------------------------------------------------------------------------------------
-
- def checkForQuit(self):
- keys = pygame.key.get_pressed()
- if keys[K_ESCAPE]:
- pygame.quit(), sys.exit()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def distance(self, p0, p1):
- return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawTempText(self, text, font, colour, coords, time):
- global textTimer
-
- # Set the timer
- timeElapsed = pygame.time.get_ticks()
- if textTimer == 0:
- textTimer = timeElapsed
-
- # Draw text if applicable
- if timeElapsed - textTimer < time:
- self.printText(text, font, colour, coords)
- return True
- else:
- return False
-
- # --------------------------------------------------------------------------------------------------------------
-
- def handleFPS(self):
- pygame.display.flip()
- if self.stableFPS:
- self.fpsClock.tick_busy_loop(self.fps)
- else:
- self.fpsClock.tick(self.fps)
- self.measuredFPS = self.fpsClock.get_fps()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def showGameOverScreen(self, won):
- self.displaysurf.blit(self.bgrdTitle, self.origin)
- outcome = 'win' if won else 'lose'
- self.printText('Game Over! You ' + outcome + '.', self.genericFont, white, (50, 50))
- self.printText(str(c.coins) + ' coins', self.medFont, white, (50, 100))
- self.printText(str(c.lives) + ' lives left', self.medFont, white, (50, 150))
- self.printText(str(int(pygame.time.get_ticks() / 1000)) + ' seconds', self.medFont, white, (50, 200))
- self.printText('TOTAL SCORE: ' + str(int(c.coins + 100 * c.lives - 0.1 * pygame.time.get_ticks() / 1000)), self.medFont,
- white, (50, 250))
- self.printText('Esc to Quit', self.medFont, white, (50, 300))
- keys = pygame.key.get_pressed()
- while not keys[K_ESCAPE]:
- keys = pygame.key.get_pressed()
- self.handleFPS()
- pygame.quit()
- sys.exit()
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawToggle(self, name, coords, mousepos, mousehoverpos, on=True):
- # Draw the text for the toggle and save the rects
- mainText = self.printText(name, self.medFont, white, coords)
- onText = self.printText('ON', self.smlFont, white, (mainText.right + 50, coords[1] + 10))
- slash = self.printText(' / ', self.smlFont, white, (onText.right + 5, coords[1] + 10))
- offText = self.printText('OFF', self.smlFont, white, (slash.right + 5, coords[1] + 10))
-
- # Make the ON/OFF text yellow if it is the selected option or if the mouse hovers over it
- if onText.collidepoint(mousehoverpos[0], mousehoverpos[1]) or on:
- onText = self.printText('ON', self.smlFont, yellow, (mainText.right + 50, coords[1] + 10))
- if offText.collidepoint(mousehoverpos[0], mousehoverpos[1]) or not on:
- offText = self.printText('OFF', self.smlFont, yellow, (slash.right + 5, coords[1] + 10))
-
- # Return a toggle output
- if onText.collidepoint(mousepos[0], mousepos[1]):
- return True
- elif offText.collidepoint(mousepos[0], mousepos[1]):
- return False
- return self.defaultValue
-
- # --------------------------------------------------------------------------------------------------------------
-
- def drawOptionsMenu(self):
- global c
-
- self.displayingOptions = True
-
- # Fill screen with background
- self.displaysurf.fill(black)
- self.displaysurf.blit(self.bgrdTitle, self.origin)
-
- # Get mouse status
- for event in pygame.event.get():
- if event.type == MOUSEBUTTONDOWN:
- self.mousex, self.mousey = event.pos
- elif event.type == MOUSEMOTION:
- self.mousex_hover, self.mousey_hover = event.pos
-
- # Draw title
- self.printText('Exit Dash: Hyperion | Options Menu', self.genericFont, white, (int(self.screenW / 2) - 420, 50))
-
- # Draw toggles
- devModeToggle = self.drawToggle('Debug Info', (math.ceil(0.25 * self.screenW), 150), (self.mousex, self.mousey),
- (self.mousex_hover, self.mousey_hover), self.developerMode)
- aaToggle = self.drawToggle('Anti-aliasing', (math.ceil(0.25 * self.screenW), 200), (self.mousex, self.mousey), (self.mousex_hover,
- self.mousey_hover), self.antialiasing)
- sFPSToggle = self.drawToggle('Stabilize Framerate', (math.ceil(0.5 * self.screenW), 150), (self.mousex, self.mousey), (self.mousex_hover,
- self.mousey_hover), self.stableFPS)
- decorationToggle = self.drawToggle('Visual Details', (math.ceil(0.5 * self.screenW), 200), (self.mousex, self.mousey),
- (self.mousex_hover, self.mousey_hover), self.decorations)
-
- # Update global variables with the values from the toggles
- if devModeToggle != self.defaultValue:
- self.developerMode = devModeToggle
- if aaToggle != self.defaultValue:
- self.antialiasing = aaToggle
- if sFPSToggle != self.defaultValue:
- self.stableFPS = sFPSToggle
- if decorationToggle != self.defaultValue:
- self.decorations = decorationToggle
-
- # Draw quit button
- quitRect = self.printText('Return to Menu', self.genericFont, white, (int(self.screenW / 2) - 185, self.screenH - 150))
- if quitRect.collidepoint(self.mousex_hover, self.mousey_hover):
- quitRect = self.printText('Return to Menu', self.genericFont, yellow, (int(self.screenW / 2) - 185, self.screenH - 150))
- if quitRect.collidepoint(self.mousex, self.mousey):
- self.displayingOptions = False
-
- # Update display
- self.handleFPS()
-
- def generateRandomLevel(self, theme, numberofplatforms, lvl):
- global p, c, b, mobs, AllMovableObjects, Enemies, spikes, door, keys, propDoor, textTimer, \
- foliage, poolPlatform, MeasuredFPS, FPS
-
- # Step 0: Clear all data from the previous level
- mobs, AllMovableObjects, Enemies, spikes = [], [], [], []
- if not type(c) is PlayableCharacter:
- c = PlayableCharacter(self.defaultValue, self.defaultValue)
- self.initialBgrdSetup = True
- textTimer = 0
- c.hasKey = False
- MeasuredFPS, FPS = self.desiredFPS, self.desiredFPS
-
- # Step 1: Generate the necessary number of platforms using an iterative strategy
- firstPlatform = Platform(randint(-300, 500), randint(self.screenH - 200, self.screenH - 50),
- 0, 0, randint(800, 1500), theme)
- overlap = True
- attempts = 2 * numberofplatforms # Reduce number of attempts for slower computers
- maxHeightDifference = c.maxJumpHeight - 10
- maxWidthDifference = c.maxJumpLength * 2
- while overlap and attempts >= 0:
- overlap = False
- attempts -= 1
- p = [firstPlatform]
- for i in range(1, numberofplatforms):
- randomDirection = [1, randint(0, 1)]
- platformWidth = randint(400, 2000)
- prevPlatform = p[i - 1]
- if randomDirection[0] == 0 and randomDirection[1] == 0:
- platformRight = prevPlatform[0] - randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformLeft = platformRight - platformWidth
- platformTop = prevPlatform[1] + randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- elif randomDirection[0] == 0 and randomDirection[1] == 1:
- platformRight = prevPlatform[0] - randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformLeft = platformRight - platformWidth
- platformTop = prevPlatform[1] - randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- elif randomDirection[0] == 1 and randomDirection[1] == 1:
- platformLeft = prevPlatform[2] + randint(int(0.5 * maxWidthDifference), maxWidthDifference)
- platformTop = prevPlatform[1] - randint(int(0.75 * maxHeightDifference), maxHeightDifference)
- else:
- platformLeft = prevPlatform[2] + randint(int(1.2 * c.width), maxWidthDifference)
- platformTop = prevPlatform[1] + randint(int(0.5 * maxHeightDifference), int(0.4 * self.screenH))
- p.append(Platform(platformLeft, platformTop, 0, 0, platformWidth, theme))
- for x1 in range(p[i][0] - 50, p[i][2] + 50, int(p[i].width / 20)):
- for x2 in range(p[i - 1][0] - 50, p[i - 1][2] + 50, int(p[i - 1].width / 20)):
- if abs(x2 - x1) < max(p[i].width / 20, p[i - 1].width / 20) and \
- abs(p[i][3] - p[i - 1][1]) < 100:
- overlap = True
- for platform in p:
- AllMovableObjects.append(platform)
-
- # Step 2: Gather platform info
- topmostPlatform, lowestPlatform, shortestPlatform, longestPlatform, farthestPlatform = p[1], p[1], p[1], p[1], \
- p[1]
- for platform in p:
- if platform[1] < topmostPlatform[1]:
- topmostPlatform = platform
- if platform[1] > lowestPlatform[1]:
- lowestPlatform = platform
- if platform[2] - platform[0] > longestPlatform[2] - longestPlatform[0] and platform[0] != p[0]:
- longestPlatform = platform
- if platform[2] - platform[0] < shortestPlatform[2] - shortestPlatform[0]:
- shortestPlatform = platform
- if platform[2] > farthestPlatform[2]:
- farthestPlatform = platform
- focusHeight = longestPlatform[1] - 0.3 * self.screenH
-
- # Step 3: Generate rare pool platform
- poolPlatform = None
- if randint(0, 2) == 0 or self.currLevel <= 1:
- poolX = farthestPlatform[2] + int(0.5 * c.maxJumpLength)
- poolY = farthestPlatform[1]
- poolWidth = randint(700, 900)
- poolHeight = 3 * c.maxJumpHeight
- poolPlatform = Pool(poolX, poolY, poolWidth, poolHeight, theme)
- AllMovableObjects.append(poolPlatform)
-
- # Step 4: Generate blocks
- quantityBlocks = numberofplatforms
- sampleBlock = Block(0, 0, 'bonus')
- blockHeight = 2 * c.height + sampleBlock.height
- b = [Block(randint(p[0][0] + 50, p[0][2] - 50), p[0][1] - blockHeight, 'coin')]
- blockplatform = [0]
- keys = []
- for i in range(1, quantityBlocks):
- y = p[i][1] - blockHeight
- if p[i].x != longestPlatform.x and randint(0, 3) != 0:
- x = 0.5 * p[i][0] + 0.5 * p[i][2] + randint(int(-0.4 * p[i].width), int(0.4 * p[i].width))
- b.append(Block(x, y, 'coin'))
- blockplatform.append(i)
- elif p[i].x != longestPlatform.x and not keys:
- x = 0.5 * p[i][0] + 0.5 * p[i][2] + randint(int(-0.4 * p[i].width), int(0.4 * p[i].width))
- b.append(Block(x, y, 'regular'))
- blockplatform.append(i)
- if poolPlatform:
- poolBlock = Block(poolPlatform.poolStartX + poolPlatform.tileWidth,
- poolPlatform.y + poolPlatform.height - blockHeight, 'regular')
- poolBlock.yieldsStar = True
- b.append(poolBlock)
- shuffle(b)
- for block in b:
- if block.form == 'regular' and not keys and not block.yieldsStar:
- key = Key(block[0][0], block[0][1] - 80, 'blue')
- keys.append(key)
- AllMovableObjects.append(key)
- elif block.form == 'regular' and randint(0, 2) == 0:
- block.willExplode = True
- elif block.form == 'regular':
- block.yieldsStar = True
- AllMovableObjects.append(block)
-
- # Step 5: Generate spikes if necessary by first creating a platform to use as a ledge
- spikes = []
- if lvl == 1 or randint(0, 1) == 0:
- ledge = Platform(longestPlatform[0], focusHeight, 0, 0, longestPlatform.width, 'snow')
- p.append(ledge), AllMovableObjects.append(ledge)
- for i in range(ledge[0] + ledge.tileWidth * 2, ledge[2] - ledge.tileWidth * 2, 40):
- spikes.append(FallingSpike(i, ledge[3]))
- for spike in spikes:
- AllMovableObjects.append(spike)
-
- # Step 6: Add foliage to enhance the atmosphere
- foliage = []
- for platform in p:
- for x in range(platform.x, platform.x + platform.width - 100, 100):
- if randint(0, 10) == 0 and self.decorations:
- decoration = BackgroundFoliage(x, platform.y)
- decoration.y -= decoration.height
- AllMovableObjects.append(decoration)
- foliage.append(decoration)
-
- # Step 7: Generate mobs
- quantityMobs = len(p) - 1
- mainMobType = 'slime'
- sampleMob = AICharacter(0, 0, 0, 0, (mainMobType, -1, -1))
- mobs = []
- for i in range(0, quantityMobs):
- whichPlatform = randint(1, len(p) - 1)
- while p[whichPlatform][0] == longestPlatform[0]:
- whichPlatform = randint(1, len(p) - 1)
- if randint(0, 1) == 0:
- mobs.append(AICharacter(randint(p[whichPlatform][0], p[whichPlatform][2]),
- p[whichPlatform][3] - sampleMob.height, int(0.7 * c.runSpeed),
- 0, (mainMobType, -1, -1)))
- else:
- mobs.append(AICharacter(randint(p[whichPlatform][0], p[whichPlatform][2]),
- p[whichPlatform][3] - sampleMob.height, int(0.7 * c.runSpeed),
- 0, ('snail', -1, -1)))
- mobs.append(AICharacter(70, p[0][1] - 750, 5, 0, ('fly', p[0][0], farthestPlatform[2])))
- if poolPlatform:
- mobs.append(AICharacter(poolPlatform.poolStartX + poolPlatform.tileWidth, poolPlatform.y +
- poolPlatform.tileWidth, 5, 0, ('fish', -1, -1)))
- for enemy in mobs:
- Enemies.append(enemy)
- AllMovableObjects.append(enemy)
-
- # Step 8: Place a door
- doorX = farthestPlatform[2] - 100
- doorY = farthestPlatform[1]
- door = Door(doorX, doorY)
- AllMovableObjects.append(door)
- propDoor = Door(p[0].x + 10, p[0].y)
- AllMovableObjects.append(propDoor)
-
- # Step 9: Ensure there is a way out of the level
- if not keys:
- key = Key(int(0.5 * (farthestPlatform[0] + farthestPlatform[2])), farthestPlatform[1] - 80, 'blue')
- keys.append(key)
- AllMovableObjects.append(key)
- for key in keys:
- key.visible = False
-
- # Step 10: Move the player to the leftmost platform
- c.x = int(0.5 * p[0][0] + 0.5 * p[0][2])
- c.y = p[0][1] - c.height
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def drawBgrd(self, environment):
-
- # Determine correct background
- if environment == 'gloomy':
- self.bgrd = self.bgrdGloomy
- self.bgrdInv = self.bgrdGloomyInv
- elif environment == 'yellow':
- self.bgrd = self.bgrdYellowSky
- self.bgrdInv = self.bgrdYellowSkyInv
- elif environment == 'castle':
- self.bgrd = self.bgrdCastle
- self.bgrdInv = self.bgrdCastleInv
- elif environment == 'desert':
- self.bgrd = self.bgrdDesert
- self.bgrdInv = self.bgrdDesertInv
- self.bgrdWidth = pygame.Surface.get_width(self.bgrd)
-
- # Swap background positions as needed
- if self.bgrdX < -self.bgrdWidth:
- self.bgrdX = self.bgrdWidth
- elif self.bgrdX > self.bgrdWidth:
- self.bgrdX = -self.bgrdWidth
- if self.bgrdInvX < -self.bgrdWidth:
- self.bgrdInvX = self.bgrdWidth
- elif self.bgrdInvX > self.bgrdWidth:
- self.bgrdInvX = -self.bgrdWidth
-
- # Verify corrent positioning of the backgrounds
- if self.bgrdX > self.bgrdInvX:
- self.bgrdX = self.bgrdInvX + self.bgrdWidth
- elif self.bgrdInvX > self.bgrdX:
- self.bgrdInvX = self.bgrdX + self.bgrdWidth
-
- # If necessary, perform initial setup
- if self.initialBgrdSetup:
- self.initialBgrdSetup = False
- self.bgrdX, self.bgrdY = 0, 0
- self.bgrdInvX = -self.bgrdWidth
- self.displaysurf.blit(self.bgrd, (self.bgrdX, self.bgrdY))
- self.displaysurf.blit(self.bgrdInv, (self.bgrdInvX, self.bgrdY))
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def updateAll(self):
- global MeasuredFPS
-
- # Draw prop door
- propDoor.update(c, self.displaysurf, False)
-
- # Update all objects
- if poolPlatform:
- poolPlatform.update(self.displaysurf)
- for f in foliage:
- f.draw(self.displaysurf)
- for i in range(0, len(p)):
- p[i].update((0, 0, self.screenW, self.screenH), self.displaysurf)
- for i in range(0, len(b)):
- b[i].update(keys, self.displaysurf)
- for enemy in Enemies:
- enemy.update(p, pygame.event.get(), AllMovableObjects, b, Enemies, c, poolPlatform, self.displaysurf)
- for spike in spikes:
- spike.update(p, [c] + mobs, b, self.displaysurf)
- if not c.update(p, pygame.event.get(), AllMovableObjects, b, Enemies, c, poolPlatform, self.displaysurf,
- self.bgrdX, self.bgrdInvX, self.screenW, self.screenH, int(MeasuredFPS)):
- self.showGameOverScreen(False)
- for key in keys:
- key.update(c, self.displaysurf)
-
- # Draw temporary text
- self.drawTempText('self.currLevel ' + str(self.currLevel), self.medFont, white, (self.screenW - 150, 50), 8000)
-
- # Check for quit events
- self.checkForQuit()
-
- # Display developer mode info
- if self.developerMode:
- videoInfo = pygame.display.Info()
- hardwareAccel = 'False'
- if videoInfo.hw:
- hardwareAccel = 'True'
- vram = 'Unknown'
- if videoInfo.video_mem != 0:
- vram = str(videoInfo.video_mem)
- self.printText('dx = ' + str(c.Vx), self.smlFont, white, (self.devInfoX, self.devInfoY))
- self.printText('dy = ' + str(c.Vy), self.smlFont, white, (self.devInfoX, self.devInfoY + self.devSpacing))
- self.printText('fps = ' + str(round(MeasuredFPS, 1)) + (' (stable)' if self.stableFPS else ' (unstable)'),
- self.smlFont, white, (self.devInfoX, self.devInfoY + 2 * self.devSpacing))
- self.printText('vol = ' + str(100 * round(pygame.mixer.music.get_volume(), 2)) + '%', self.smlFont, white,
- (self.devInfoX, self.devInfoY + 3 * self.devSpacing))
- self.printText('onground = True' if c.onGround else 'onground = False', self.smlFont, white,
- (self.devInfoX, self.devInfoY + 4 * self.devSpacing))
- self.printText('hw accel = ' + hardwareAccel, self.smlFont, white, (self.devInfoX, self.devInfoY +
- 5 * self.devSpacing))
- self.printText('vram (MB): ' + vram, self.smlFont, white, (self.devInfoX, self.devInfoY + 6 *
- self.devSpacing))
- self.printText('esc to quit', self.smlFont, white, (self.devInfoX, self.devInfoY + 7 * self.devSpacing))
-
- # Update screen and enforce maximum FPS
- self.handleFPS()
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def drawTitleScreen(self):
- global gameStart, c
- whichChar = 0
-
- # Check for quit events
- self.checkForQuit()
- for event in pygame.event.get():
- if event.type == MOUSEBUTTONDOWN:
- self.mousex, self.mousey = event.pos
- elif event.type == MOUSEMOTION:
- self.mousex_hover, self.mousey_hover = event.pos
-
- # Fill screen with background
- self.displaysurf.fill(black)
- self.displaysurf.blit(self.bgrdTitle, self.origin)
-
- # Print static text
- self.printText('Welcome to Exit Dash: Hyperion!', self.genericFont, white, (50, 50))
- self.printText('Choose a character to begin:', self.genericFont, white, (math.floor(self.screenW / 2) - 350, 150))
-
- # Draw three characters to choose from
- firstCharX = math.floor(self.screenW / 4) - 30
- secondCharX = 2 * firstCharX + 80
- thirdCharX = 3 * firstCharX + 190
- charY = math.floor(self.screenH / 2) - 50
- firstChar = PlayableCharacter(firstCharX, charY, 0, 0, 1)
- secondChar = PlayableCharacter(secondCharX, charY, 0, 0, 2)
- thirdChar = PlayableCharacter(thirdCharX, charY, 0, 0, 3)
- firstCharRect = pygame.Rect(firstChar.x, firstChar.y, firstChar.width, firstChar.height)
- secondCharRect = pygame.Rect(secondChar.x, secondChar.y, secondChar.width, secondChar.height)
- thirdCharRect = pygame.Rect(thirdChar.x, thirdChar.y, thirdChar.width, thirdChar.height)
- self.displaysurf.blit(firstChar.standingImage, (firstCharX, charY))
- self.displaysurf.blit(secondChar.standingImage, (secondCharX, charY))
- self.displaysurf.blit(thirdChar.standingImage, (thirdCharX, charY))
- if firstCharRect.collidepoint(self.mousex_hover, self.mousey_hover):
- pygame.draw.rect(self.displaysurf, white, firstCharRect, 3)
- self.printText('Flight Commander Alex', self.medFont, yellow, (firstCharX - 95, charY +
- firstChar.height + 15))
- else:
- self.printText('Flight Commander Alex', self.medFont, white, (firstCharX - 95, charY +
- firstChar.height + 15))
- if secondCharRect.collidepoint(self.mousex_hover, self.mousey_hover):
- pygame.draw.rect(self.displaysurf, white, secondCharRect, 3)
- self.printText('Astronaut Allan', self.medFont, yellow, (secondCharX - 55, charY + secondChar.height + 15))
- else:
- self.printText('Astronaut Allan', self.medFont, white, (secondCharX - 55, charY + secondChar.height + 15))
- if thirdCharRect.collidepoint(self.mousex_hover, self.mousey_hover):
- pygame.draw.rect(self.displaysurf, white, thirdCharRect, 3)
- self.printText('Medical Specialist Lisa', self.medFont, yellow, (thirdCharX - 95, charY +
- thirdChar.height + 15))
- else:
- self.printText('Medical Specialist Lisa', self.medFont, white, (thirdCharX - 95, charY +
- thirdChar.height + 15))
- firstCharacterChosen = firstCharRect.collidepoint(self.mousex, self.mousey)
- secondCharacterChosen = secondCharRect.collidepoint(self.mousex, self.mousey)
- thirdCharacterChosen = thirdCharRect.collidepoint(self.mousex, self.mousey)
- if firstCharacterChosen:
- whichChar = 1
- elif secondCharacterChosen:
- whichChar = 2
- elif thirdCharacterChosen:
- whichChar = 3
-
- # Draw quit button
- quitRect = self.printText('Quit', self.genericFont, white,
- (int(self.screenW / 2) - 25, self.screenH - 200))
- if quitRect.collidepoint(self.mousex, self.mousey):
- pygame.quit()
- sys.exit()
- if quitRect.collidepoint(self.mousex_hover, self.mousey_hover):
- self.printText('Quit', self.genericFont, yellow, (int(self.screenW / 2) - 25, self.screenH - 200))
-
- # Draw settings button
- settingsRect = self.printText('Options', self.genericFont, white, (int(self.screenW / 2) - 60, self.screenH - 100))
- if settingsRect.collidepoint(self.mousex, self.mousey):
- self.displayingOptions = True
- if settingsRect.collidepoint(self.mousex_hover, self.mousey_hover):
- self.printText('Options', self.genericFont, yellow, (int(self.screenW / 2) - 60, self.screenH - 100))
- while self.displayingOptions:
- self.drawOptionsMenu()
-
- # Enter game if a character is chosen
- if firstCharacterChosen or secondCharacterChosen or thirdCharacterChosen:
- c = PlayableCharacter(0, 0, 0, 0, whichChar)
- self.currLevel = 1
- self.generateRandomLevel('stone', 10, 1)
- pygame.mixer.music.load('music\\artblock_jan125.ogg')
- pygame.mixer.music.set_volume(1.0)
- pygame.mixer.music.play(-1)
-
- self.handleFPS()
-
- # -----------------------------------------------------------------------------------------------------------------
-
- @staticmethod
- def loadLevel(self, level):
- fileName = 'levels/data_' + str(level[0]) + '_' + str(level[1]) + \
- '.txt'
- data = open(fileName)
-
- # --------------------------------------------------------------------------------------------------------------
-
- def executeGameLoop(self):
- global door, c, gameStart, textTimer
- textTimer = 0
- gameStart = False
- pygame.mixer.music.load('music\\disconnected_jukeri12.ogg')
- pygame.mixer.music.set_volume(1.0)
- pygame.mixer.music.play(-1)
-
- while self.currLevel == 0:
- self.drawTitleScreen()
-
- while self.currLevel == 1:
- self.displaysurf.fill(white)
- self.drawBgrd('castle')
- shouldAdvanceLevel = door.update(c, self.displaysurf)
- self.updateAll()
- if shouldAdvanceLevel:
- self.printText('Loading self.currLevel ' + str(self.currLevel + 1), self.medFont, white, (50, self.screenH - 50))
- self.currLevel += 1
- pygame.time.wait(self.levelDelay)
- self.generateRandomLevel('stone', 20, 2)
-
- while self.currLevel == 2:
- self.displaysurf.fill(white)
- self.drawBgrd('castle')
- shouldAdvanceLevel = door.update(c, self.displaysurf)
- self.updateAll()
- if shouldAdvanceLevel:
- self.printText('Loading self.currLevel ' + str(self.currLevel + 1), self.medFont, white, (50, self.screenH - 50))
- self.currLevel += 1
- pygame.time.wait(self.levelDelay)
- self.generateRandomLevel('stone', 25, 3)
diff --git a/hud/hud_0.png b/hud/hud_0.png
deleted file mode 100644
index 57e53cd..0000000
Binary files a/hud/hud_0.png and /dev/null differ
diff --git a/hud/hud_1.png b/hud/hud_1.png
deleted file mode 100644
index 3be585e..0000000
Binary files a/hud/hud_1.png and /dev/null differ
diff --git a/hud/hud_2.png b/hud/hud_2.png
deleted file mode 100644
index b982335..0000000
Binary files a/hud/hud_2.png and /dev/null differ
diff --git a/hud/hud_3.png b/hud/hud_3.png
deleted file mode 100644
index 641caea..0000000
Binary files a/hud/hud_3.png and /dev/null differ
diff --git a/hud/hud_4.png b/hud/hud_4.png
deleted file mode 100644
index 42a04fe..0000000
Binary files a/hud/hud_4.png and /dev/null differ
diff --git a/hud/hud_5.png b/hud/hud_5.png
deleted file mode 100644
index eb9ee83..0000000
Binary files a/hud/hud_5.png and /dev/null differ
diff --git a/hud/hud_6.png b/hud/hud_6.png
deleted file mode 100644
index 8ea3e1c..0000000
Binary files a/hud/hud_6.png and /dev/null differ
diff --git a/hud/hud_7.png b/hud/hud_7.png
deleted file mode 100644
index 0cee7c5..0000000
Binary files a/hud/hud_7.png and /dev/null differ
diff --git a/hud/hud_8.png b/hud/hud_8.png
deleted file mode 100644
index 6406607..0000000
Binary files a/hud/hud_8.png and /dev/null differ
diff --git a/hud/hud_9.png b/hud/hud_9.png
deleted file mode 100644
index 521f695..0000000
Binary files a/hud/hud_9.png and /dev/null differ
diff --git a/hud/hud_coins.png b/hud/hud_coins.png
deleted file mode 100644
index 4419b29..0000000
Binary files a/hud/hud_coins.png and /dev/null differ
diff --git a/hud/hud_gem_blue.png b/hud/hud_gem_blue.png
deleted file mode 100644
index 82b21fc..0000000
Binary files a/hud/hud_gem_blue.png and /dev/null differ
diff --git a/hud/hud_gem_green.png b/hud/hud_gem_green.png
deleted file mode 100644
index cff6068..0000000
Binary files a/hud/hud_gem_green.png and /dev/null differ
diff --git a/hud/hud_gem_red.png b/hud/hud_gem_red.png
deleted file mode 100644
index cfce021..0000000
Binary files a/hud/hud_gem_red.png and /dev/null differ
diff --git a/hud/hud_gem_yellow.png b/hud/hud_gem_yellow.png
deleted file mode 100644
index f5d07d6..0000000
Binary files a/hud/hud_gem_yellow.png and /dev/null differ
diff --git a/hud/hud_heartEmpty.png b/hud/hud_heartEmpty.png
deleted file mode 100644
index 2dfc0c9..0000000
Binary files a/hud/hud_heartEmpty.png and /dev/null differ
diff --git a/hud/hud_heartFull.png b/hud/hud_heartFull.png
deleted file mode 100644
index 4b9aba2..0000000
Binary files a/hud/hud_heartFull.png and /dev/null differ
diff --git a/hud/hud_heartHalf.png b/hud/hud_heartHalf.png
deleted file mode 100644
index 5d64f72..0000000
Binary files a/hud/hud_heartHalf.png and /dev/null differ
diff --git a/hud/hud_keyBlue.png b/hud/hud_keyBlue.png
deleted file mode 100644
index daf6025..0000000
Binary files a/hud/hud_keyBlue.png and /dev/null differ
diff --git a/hud/hud_keyBlue_disabled.png b/hud/hud_keyBlue_disabled.png
deleted file mode 100644
index 7b3ec24..0000000
Binary files a/hud/hud_keyBlue_disabled.png and /dev/null differ
diff --git a/hud/hud_keyGreem_disabled.png b/hud/hud_keyGreem_disabled.png
deleted file mode 100644
index 42cb177..0000000
Binary files a/hud/hud_keyGreem_disabled.png and /dev/null differ
diff --git a/hud/hud_keyGreen.png b/hud/hud_keyGreen.png
deleted file mode 100644
index cd5e763..0000000
Binary files a/hud/hud_keyGreen.png and /dev/null differ
diff --git a/hud/hud_keyRed.png b/hud/hud_keyRed.png
deleted file mode 100644
index 9669883..0000000
Binary files a/hud/hud_keyRed.png and /dev/null differ
diff --git a/hud/hud_keyRed_disabled.png b/hud/hud_keyRed_disabled.png
deleted file mode 100644
index 484d2db..0000000
Binary files a/hud/hud_keyRed_disabled.png and /dev/null differ
diff --git a/hud/hud_keyYellow.png b/hud/hud_keyYellow.png
deleted file mode 100644
index b011dbc..0000000
Binary files a/hud/hud_keyYellow.png and /dev/null differ
diff --git a/hud/hud_keyYellow_disabled.png b/hud/hud_keyYellow_disabled.png
deleted file mode 100644
index 16491ae..0000000
Binary files a/hud/hud_keyYellow_disabled.png and /dev/null differ
diff --git a/hud/hud_p1.png b/hud/hud_p1.png
deleted file mode 100644
index b9c1b27..0000000
Binary files a/hud/hud_p1.png and /dev/null differ
diff --git a/hud/hud_p1Alt.png b/hud/hud_p1Alt.png
deleted file mode 100644
index e8c45dd..0000000
Binary files a/hud/hud_p1Alt.png and /dev/null differ
diff --git a/hud/hud_p2.png b/hud/hud_p2.png
deleted file mode 100644
index 76db891..0000000
Binary files a/hud/hud_p2.png and /dev/null differ
diff --git a/hud/hud_p2Alt.png b/hud/hud_p2Alt.png
deleted file mode 100644
index a89150a..0000000
Binary files a/hud/hud_p2Alt.png and /dev/null differ
diff --git a/hud/hud_p3.png b/hud/hud_p3.png
deleted file mode 100644
index bbf28f8..0000000
Binary files a/hud/hud_p3.png and /dev/null differ
diff --git a/hud/hud_p3Alt.png b/hud/hud_p3Alt.png
deleted file mode 100644
index a79d2ae..0000000
Binary files a/hud/hud_p3Alt.png and /dev/null differ
diff --git a/hud/hud_spritesheet.png b/hud/hud_spritesheet.png
deleted file mode 100644
index 034b829..0000000
Binary files a/hud/hud_spritesheet.png and /dev/null differ
diff --git a/hud/hud_x.png b/hud/hud_x.png
deleted file mode 100644
index a628149..0000000
Binary files a/hud/hud_x.png and /dev/null differ
diff --git a/hud/pointer.png b/hud/pointer.png
deleted file mode 100644
index b18ed8c..0000000
Binary files a/hud/pointer.png and /dev/null differ
diff --git a/hud/pointerClicked.png b/hud/pointerClicked.png
deleted file mode 100644
index a76035c..0000000
Binary files a/hud/pointerClicked.png and /dev/null differ
diff --git a/items/bomb.png b/items/bomb.png
deleted file mode 100644
index 326c321..0000000
Binary files a/items/bomb.png and /dev/null differ
diff --git a/items/bombFlash.png b/items/bombFlash.png
deleted file mode 100644
index fd4c331..0000000
Binary files a/items/bombFlash.png and /dev/null differ
diff --git a/items/bush.png b/items/bush.png
deleted file mode 100644
index 5805bd1..0000000
Binary files a/items/bush.png and /dev/null differ
diff --git a/items/buttonBlue.png b/items/buttonBlue.png
deleted file mode 100644
index 7c0a738..0000000
Binary files a/items/buttonBlue.png and /dev/null differ
diff --git a/items/buttonBlue_pressed.png b/items/buttonBlue_pressed.png
deleted file mode 100644
index 4b793ff..0000000
Binary files a/items/buttonBlue_pressed.png and /dev/null differ
diff --git a/items/buttonGreen.png b/items/buttonGreen.png
deleted file mode 100644
index 74bf3f6..0000000
Binary files a/items/buttonGreen.png and /dev/null differ
diff --git a/items/buttonGreen_pressed.png b/items/buttonGreen_pressed.png
deleted file mode 100644
index c7a2095..0000000
Binary files a/items/buttonGreen_pressed.png and /dev/null differ
diff --git a/items/buttonRed.png b/items/buttonRed.png
deleted file mode 100644
index 5b6172b..0000000
Binary files a/items/buttonRed.png and /dev/null differ
diff --git a/items/buttonRed_pressed.png b/items/buttonRed_pressed.png
deleted file mode 100644
index 00cf179..0000000
Binary files a/items/buttonRed_pressed.png and /dev/null differ
diff --git a/items/buttonYellow.png b/items/buttonYellow.png
deleted file mode 100644
index 6b6caaa..0000000
Binary files a/items/buttonYellow.png and /dev/null differ
diff --git a/items/buttonYellow_pressed.png b/items/buttonYellow_pressed.png
deleted file mode 100644
index 5eb3656..0000000
Binary files a/items/buttonYellow_pressed.png and /dev/null differ
diff --git a/items/cactus.png b/items/cactus.png
deleted file mode 100644
index 00737ef..0000000
Binary files a/items/cactus.png and /dev/null differ
diff --git a/items/chain.png b/items/chain.png
deleted file mode 100644
index bbdc19b..0000000
Binary files a/items/chain.png and /dev/null differ
diff --git a/items/coinBronze.png b/items/coinBronze.png
deleted file mode 100644
index fe70f41..0000000
Binary files a/items/coinBronze.png and /dev/null differ
diff --git a/items/coinGold.png b/items/coinGold.png
deleted file mode 100644
index e63c689..0000000
Binary files a/items/coinGold.png and /dev/null differ
diff --git a/items/coinSilver.png b/items/coinSilver.png
deleted file mode 100644
index 4f7965b..0000000
Binary files a/items/coinSilver.png and /dev/null differ
diff --git a/items/fireball.png b/items/fireball.png
deleted file mode 100644
index 6436ef6..0000000
Binary files a/items/fireball.png and /dev/null differ
diff --git a/items/flagBlue.png b/items/flagBlue.png
deleted file mode 100644
index 1cc0f42..0000000
Binary files a/items/flagBlue.png and /dev/null differ
diff --git a/items/flagBlue2.png b/items/flagBlue2.png
deleted file mode 100644
index ce036d3..0000000
Binary files a/items/flagBlue2.png and /dev/null differ
diff --git a/items/flagBlueHanging.png b/items/flagBlueHanging.png
deleted file mode 100644
index 8821d1b..0000000
Binary files a/items/flagBlueHanging.png and /dev/null differ
diff --git a/items/flagGreen.png b/items/flagGreen.png
deleted file mode 100644
index a6d8e38..0000000
Binary files a/items/flagGreen.png and /dev/null differ
diff --git a/items/flagGreen2.png b/items/flagGreen2.png
deleted file mode 100644
index d7e3fbf..0000000
Binary files a/items/flagGreen2.png and /dev/null differ
diff --git a/items/flagGreenHanging.png b/items/flagGreenHanging.png
deleted file mode 100644
index e9f5dcd..0000000
Binary files a/items/flagGreenHanging.png and /dev/null differ
diff --git a/items/flagRed.png b/items/flagRed.png
deleted file mode 100644
index e33b298..0000000
Binary files a/items/flagRed.png and /dev/null differ
diff --git a/items/flagRed2.png b/items/flagRed2.png
deleted file mode 100644
index d5995d6..0000000
Binary files a/items/flagRed2.png and /dev/null differ
diff --git a/items/flagRedHanging.png b/items/flagRedHanging.png
deleted file mode 100644
index d6a97a2..0000000
Binary files a/items/flagRedHanging.png and /dev/null differ
diff --git a/items/flagYellow.png b/items/flagYellow.png
deleted file mode 100644
index 92b736a..0000000
Binary files a/items/flagYellow.png and /dev/null differ
diff --git a/items/flagYellow2.png b/items/flagYellow2.png
deleted file mode 100644
index 58b4566..0000000
Binary files a/items/flagYellow2.png and /dev/null differ
diff --git a/items/flagYellowHanging.png b/items/flagYellowHanging.png
deleted file mode 100644
index 15b0dd1..0000000
Binary files a/items/flagYellowHanging.png and /dev/null differ
diff --git a/items/gemBlue.png b/items/gemBlue.png
deleted file mode 100644
index 8beef0c..0000000
Binary files a/items/gemBlue.png and /dev/null differ
diff --git a/items/gemGreen.png b/items/gemGreen.png
deleted file mode 100644
index 9e9c3f6..0000000
Binary files a/items/gemGreen.png and /dev/null differ
diff --git a/items/gemRed.png b/items/gemRed.png
deleted file mode 100644
index deb5cb0..0000000
Binary files a/items/gemRed.png and /dev/null differ
diff --git a/items/gemYellow.png b/items/gemYellow.png
deleted file mode 100644
index 0e4b4db..0000000
Binary files a/items/gemYellow.png and /dev/null differ
diff --git a/items/items_spritesheet.png b/items/items_spritesheet.png
deleted file mode 100644
index 7169f4e..0000000
Binary files a/items/items_spritesheet.png and /dev/null differ
diff --git a/items/keyBlue.png b/items/keyBlue.png
deleted file mode 100644
index af17f80..0000000
Binary files a/items/keyBlue.png and /dev/null differ
diff --git a/items/keyGreen.png b/items/keyGreen.png
deleted file mode 100644
index 839294e..0000000
Binary files a/items/keyGreen.png and /dev/null differ
diff --git a/items/keyRed.png b/items/keyRed.png
deleted file mode 100644
index e2ebd91..0000000
Binary files a/items/keyRed.png and /dev/null differ
diff --git a/items/keyYellow.png b/items/keyYellow.png
deleted file mode 100644
index bc58e18..0000000
Binary files a/items/keyYellow.png and /dev/null differ
diff --git a/items/mushroomBrown.png b/items/mushroomBrown.png
deleted file mode 100644
index 0844c7e..0000000
Binary files a/items/mushroomBrown.png and /dev/null differ
diff --git a/items/mushroomRed.png b/items/mushroomRed.png
deleted file mode 100644
index a2a5986..0000000
Binary files a/items/mushroomRed.png and /dev/null differ
diff --git a/items/particleBrick1a.png b/items/particleBrick1a.png
deleted file mode 100644
index 2aa95b6..0000000
Binary files a/items/particleBrick1a.png and /dev/null differ
diff --git a/items/particleBrick1b.png b/items/particleBrick1b.png
deleted file mode 100644
index 4ebd0aa..0000000
Binary files a/items/particleBrick1b.png and /dev/null differ
diff --git a/items/particleBrick2a.png b/items/particleBrick2a.png
deleted file mode 100644
index de968dd..0000000
Binary files a/items/particleBrick2a.png and /dev/null differ
diff --git a/items/particleBrick2b.png b/items/particleBrick2b.png
deleted file mode 100644
index 1476011..0000000
Binary files a/items/particleBrick2b.png and /dev/null differ
diff --git a/items/plant.png b/items/plant.png
deleted file mode 100644
index 1794e56..0000000
Binary files a/items/plant.png and /dev/null differ
diff --git a/items/plantPurple.png b/items/plantPurple.png
deleted file mode 100644
index 2b23fce..0000000
Binary files a/items/plantPurple.png and /dev/null differ
diff --git a/items/rock.png b/items/rock.png
deleted file mode 100644
index ca4455d..0000000
Binary files a/items/rock.png and /dev/null differ
diff --git a/items/snowhill.png b/items/snowhill.png
deleted file mode 100644
index 84ffcf4..0000000
Binary files a/items/snowhill.png and /dev/null differ
diff --git a/items/spikes.png b/items/spikes.png
deleted file mode 100644
index 5b23a14..0000000
Binary files a/items/spikes.png and /dev/null differ
diff --git a/items/springboardDown.png b/items/springboardDown.png
deleted file mode 100644
index 1bfc9c8..0000000
Binary files a/items/springboardDown.png and /dev/null differ
diff --git a/items/springboardUp.png b/items/springboardUp.png
deleted file mode 100644
index 517cb36..0000000
Binary files a/items/springboardUp.png and /dev/null differ
diff --git a/items/star.png b/items/star.png
deleted file mode 100644
index f824ca0..0000000
Binary files a/items/star.png and /dev/null differ
diff --git a/items/switchLeft.png b/items/switchLeft.png
deleted file mode 100644
index 092a7d3..0000000
Binary files a/items/switchLeft.png and /dev/null differ
diff --git a/items/switchMid.png b/items/switchMid.png
deleted file mode 100644
index a146b6c..0000000
Binary files a/items/switchMid.png and /dev/null differ
diff --git a/items/switchRight.png b/items/switchRight.png
deleted file mode 100644
index 2457eec..0000000
Binary files a/items/switchRight.png and /dev/null differ
diff --git a/items/weight.png b/items/weight.png
deleted file mode 100644
index 1243052..0000000
Binary files a/items/weight.png and /dev/null differ
diff --git a/items/weightChained.png b/items/weightChained.png
deleted file mode 100644
index a912516..0000000
Binary files a/items/weightChained.png and /dev/null differ
diff --git a/key.py b/key.py
deleted file mode 100644
index b02e1bb..0000000
--- a/key.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# coding=utf-8
-import pygame
-from game import *
-
-
-class Key:
- def __init__(self, x, y, colour):
- self.x = x
- self.y = y
- self.visible = False
-
- # Load image
- self.image = pygame.image.load('environment\\main\\key' + colour + '.png').convert_alpha()
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, mainChar, surface):
- if self.visible:
- surface.blit(self.image, (self.x, self.y))
- keyRect = pygame.Rect(self.x, self.y, self.width, self.height)
- charRect = pygame.Rect(mainChar.x, mainChar.y, mainChar.width, mainChar.height)
- if keyRect.colliderect(charRect):
- mainChar.hasKey = True
- self.visible = False
\ No newline at end of file
diff --git a/levels/lvlhints.dat b/levels/lvlhints.dat
deleted file mode 100644
index 7792ddc..0000000
--- a/levels/lvlhints.dat
+++ /dev/null
@@ -1,2 +0,0 @@
-Welcome to the Hyperion Space Centre! Use {DUCK} to duck and the arrow keys to move around.
-Hey, who turned out the lights?
\ No newline at end of file
diff --git a/music/Alexander Ehlers - Doomed.mp3 b/music/Alexander Ehlers - Doomed.mp3
deleted file mode 100644
index 52565e3..0000000
Binary files a/music/Alexander Ehlers - Doomed.mp3 and /dev/null differ
diff --git a/music/Alexander Ehlers - Flags.mp3 b/music/Alexander Ehlers - Flags.mp3
deleted file mode 100644
index 1c878f0..0000000
Binary files a/music/Alexander Ehlers - Flags.mp3 and /dev/null differ
diff --git a/music/Alexander Ehlers - Great mission.mp3 b/music/Alexander Ehlers - Great mission.mp3
deleted file mode 100644
index 06ceb9e..0000000
Binary files a/music/Alexander Ehlers - Great mission.mp3 and /dev/null differ
diff --git a/music/Alexander Ehlers - Spacetime.mp3 b/music/Alexander Ehlers - Spacetime.mp3
deleted file mode 100644
index 7f55100..0000000
Binary files a/music/Alexander Ehlers - Spacetime.mp3 and /dev/null differ
diff --git a/music/Alexander Ehlers - Twists.mp3 b/music/Alexander Ehlers - Twists.mp3
deleted file mode 100644
index f2aaadc..0000000
Binary files a/music/Alexander Ehlers - Twists.mp3 and /dev/null differ
diff --git a/music/Alexander Ehlers - Waking the devil.mp3 b/music/Alexander Ehlers - Waking the devil.mp3
deleted file mode 100644
index a09d10d..0000000
Binary files a/music/Alexander Ehlers - Waking the devil.mp3 and /dev/null differ
diff --git a/music/Alexander Ehlers - Warped.mp3 b/music/Alexander Ehlers - Warped.mp3
deleted file mode 100644
index b9d7509..0000000
Binary files a/music/Alexander Ehlers - Warped.mp3 and /dev/null differ
diff --git a/music/Recall of the Shadows.mp3 b/music/Recall of the Shadows.mp3
deleted file mode 100644
index 21feea7..0000000
Binary files a/music/Recall of the Shadows.mp3 and /dev/null differ
diff --git a/music/artblock_jan125.ogg b/music/artblock_jan125.ogg
deleted file mode 100644
index 2fccc3d..0000000
Binary files a/music/artblock_jan125.ogg and /dev/null differ
diff --git a/music/awake_megawall.mp3 b/music/awake_megawall.mp3
deleted file mode 100644
index 7f2f988..0000000
Binary files a/music/awake_megawall.mp3 and /dev/null differ
diff --git a/music/bgrd_old.mp3 b/music/bgrd_old.mp3
deleted file mode 100644
index eb09478..0000000
Binary files a/music/bgrd_old.mp3 and /dev/null differ
diff --git a/music/char0_1.ogg b/music/char0_1.ogg
deleted file mode 100644
index bec6383..0000000
Binary files a/music/char0_1.ogg and /dev/null differ
diff --git a/music/char0_2.ogg b/music/char0_2.ogg
deleted file mode 100644
index 0d42b4a..0000000
Binary files a/music/char0_2.ogg and /dev/null differ
diff --git a/music/char0_3.ogg b/music/char0_3.ogg
deleted file mode 100644
index 77dee73..0000000
Binary files a/music/char0_3.ogg and /dev/null differ
diff --git a/music/char1_1.ogg b/music/char1_1.ogg
deleted file mode 100644
index bb5ab81..0000000
Binary files a/music/char1_1.ogg and /dev/null differ
diff --git a/music/char1_2.ogg b/music/char1_2.ogg
deleted file mode 100644
index 8aa93b7..0000000
Binary files a/music/char1_2.ogg and /dev/null differ
diff --git a/music/credits.ogg b/music/credits.ogg
deleted file mode 100644
index 0c8b486..0000000
Binary files a/music/credits.ogg and /dev/null differ
diff --git a/music/disconnected_jukeri12.ogg b/music/disconnected_jukeri12.ogg
deleted file mode 100644
index a0a4b4a..0000000
Binary files a/music/disconnected_jukeri12.ogg and /dev/null differ
diff --git a/music/final_castle.mp3 b/music/final_castle.mp3
deleted file mode 100644
index 8c73f41..0000000
Binary files a/music/final_castle.mp3 and /dev/null differ
diff --git a/music/flags.mp3 b/music/flags.mp3
deleted file mode 100644
index 1c878f0..0000000
Binary files a/music/flags.mp3 and /dev/null differ
diff --git a/music/gameover.mp3 b/music/gameover.mp3
deleted file mode 100644
index 0bddacb..0000000
Binary files a/music/gameover.mp3 and /dev/null differ
diff --git a/music/great_mission.mp3 b/music/great_mission.mp3
deleted file mode 100644
index 06ceb9e..0000000
Binary files a/music/great_mission.mp3 and /dev/null differ
diff --git a/music/menuloop.wav b/music/menuloop.wav
deleted file mode 100644
index d10cb8c..0000000
Binary files a/music/menuloop.wav and /dev/null differ
diff --git a/music/plan.mp3 b/music/plan.mp3
deleted file mode 100644
index 06fe495..0000000
Binary files a/music/plan.mp3 and /dev/null differ
diff --git a/music/puzzle.mp3 b/music/puzzle.mp3
deleted file mode 100644
index 06fe495..0000000
Binary files a/music/puzzle.mp3 and /dev/null differ
diff --git a/music/radiops_megalover.wav b/music/radiops_megalover.wav
deleted file mode 100644
index 2381b5f..0000000
Binary files a/music/radiops_megalover.wav and /dev/null differ
diff --git a/music/twists.mp3 b/music/twists.mp3
deleted file mode 100644
index f2aaadc..0000000
Binary files a/music/twists.mp3 and /dev/null differ
diff --git a/music/vision.mp3 b/music/vision.mp3
deleted file mode 100644
index 94a3442..0000000
Binary files a/music/vision.mp3 and /dev/null differ
diff --git a/music/waking_devil.mp3 b/music/waking_devil.mp3
deleted file mode 100644
index a09d10d..0000000
Binary files a/music/waking_devil.mp3 and /dev/null differ
diff --git a/platform.py b/platform.py
deleted file mode 100644
index cc73b1d..0000000
--- a/platform.py
+++ /dev/null
@@ -1,79 +0,0 @@
-import pygame
-
-
-class Platform(object):
-
- def __init__(self, x, y, Vx, Vy, width, style='grass'):
- self.x = x
- self.y = y
- self.Vx = Vx
- self.Vy = Vy
-
- # Load platform image
- self.image = pygame.image.load('environment\\main\\' + style + 'Mid.png').convert_alpha()
- self.width = width
- self.tileWidth = pygame.Surface.get_width(self.image)
- self.width -= self.width % self.tileWidth
- self.height = pygame.Surface.get_height(self.image)
-
- # Load platform edge images
- self.leftImage = pygame.image.load('environment\\main\\' + style + 'CliffLeft.png').convert_alpha()
- self.rightImage = pygame.image.load('environment\\main\\' + style + 'CliffRight.png').convert_alpha()
-
- # -----------------------------------------------------------------------------------------------------------------
- def __getitem__(self, i):
- # This method allows iteration of platform objects
- # From [0] to [3], it returns the left X, top Y,
- # rightX, and bottom Y, respectively
- if i == 0:
- return self.x
- elif i == 1:
- return self.y
- elif i == 2:
- return self.x + self.width
- elif i == 3:
- return self.y + self.height
- else:
- return i
-
- # -----------------------------------------------------------------------------------------------------------------
- def __setitem__(self, k, v):
- if k == 0:
- self.x = v
- elif k == 1:
- self.y = v
- elif k == 2:
- self.x = v - self.width
- elif k == 3:
- self.y = v - self.height
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, levelBorders, surface):
- self.updateMotion(levelBorders)
- self.draw(surface)
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, levelBorders):
- # Increment the position of the platform by the velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # Wrap the motion of the platform around the level edges
- if self.x >= levelBorders[2] and self.Vx > 0:
- self.x = levelBorders[0] - self.width
- elif (self.x - self.width) <= levelBorders[0] and self.Vx < 0:
- self.x = levelBorders[2]
- elif self.y >= levelBorders[3] and self.Vy > 0:
- self.y = levelBorders[1] - self.height
- elif (self.y + self.height) <= levelBorders[1] and self.Vy < 0:
- self.y = levelBorders[3]
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, surface):
- # Draw platform edges
- surface.blit(self.leftImage, (self.x, self.y))
- surface.blit(self.rightImage, (self.x + self.width - self.tileWidth, self.y))
-
- # Fill in the platform between the two edges
- for i in range(self.x + self.tileWidth, self.x + self.width - self.tileWidth, self.tileWidth):
- surface.blit(self.image, (i, self.y))
\ No newline at end of file
diff --git a/playablecharacter.py b/playablecharacter.py
deleted file mode 100644
index 537f046..0000000
--- a/playablecharacter.py
+++ /dev/null
@@ -1,210 +0,0 @@
-from random import randint
-import math
-import pygame
-from pygame.locals import *
-import sys
-from character import Character
-
-class PlayableCharacter(Character):
-
- def __init__(self, x, y, Vx=0, Vy=0, whichChar=1):
- Character.__init__(self, x, y, Vx, Vy, whichChar)
-
- # HUD images
- self.whichChar = whichChar
- self.heartEmpty = pygame.image.load('hud\\hud_heartEmpty.png').convert_alpha()
- self.heartHalf = pygame.image.load('hud\\hud_heartHalf.png').convert_alpha()
- self.heartFull = pygame.image.load('hud\\hud_heartFull.png').convert_alpha()
- self.heartWidth = pygame.Surface.get_width(self.heartFull)
- self.heartHeight = pygame.Surface.get_height(self.heartFull)
- self.coin = pygame.image.load('hud\\hud_coins.png').convert_alpha()
- self.coinWidth = pygame.Surface.get_width(self.coin)
- self.coinsMultiplier = pygame.image.load('hud\\hud_x.png').convert_alpha()
- self.hudNumber = []
- for i in range(0, 10):
- numberImage = pygame.image.load('hud\\hud_' + str(i) + '.png').convert_alpha()
- self.hudNumber.append(numberImage)
- self.hudTextWidth = pygame.Surface.get_width(self.hudNumber[0])
- self.playerCoins = []
- for i in range(0, 3):
- playerCoinImage = pygame.image.load('hud\\hud_p' + str(self.whichChar) + '.png').convert_alpha()
- self.playerCoins.append(playerCoinImage)
- self.key = pygame.image.load('hud\\hud_keyBlue.png').convert_alpha()
- self.noKey = pygame.image.load('hud\\hud_keyBlue_disabled.png').convert_alpha()
-
- # HUD variables
- self.spacing = 10
- self.coins = 0
- self.playerCoinCoords = (self.spacing, self.spacing)
- self.healthStart = (pygame.Surface.get_width(self.playerCoins[0]) + 2 * self.spacing, 10)
- self.healthInterval = self.spacing + self.heartWidth
-
- # Other variables
- if whichChar == 1:
- self.jumpSpeed = 22
- self.runSpeed = 8
- self.lives = 9
- else:
- self.jumpSpeed = 23
- self.runSpeed = 9
- self.lives = 4
- self.worldShiftCoefficient = 1.5
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def update(self, platforms, ev, movableObjects, blocks, aiCharacters, mainChar, pool, surface, bgrdX=0, bgrdInvX=0,
- scrW=0, scrH=0, FPS=75):
- self.collide(platforms, blocks, aiCharacters, pool)
- self.determineLowestPlatform(platforms)
- self.move(ev, platforms, movableObjects, aiCharacters, bgrdX, bgrdInvX, scrW, scrH)
- self.draw(surface, FPS)
- if self.move(ev, platforms, movableObjects, aiCharacters, bgrdX, bgrdInvX, scrW, scrH):
- return True
- return False
-
- # -----------------------------------------------------------------------------------------------------------------
-
- def move(self, events, platforms, movableObjects, aiCharacters, bgrdX, bgrdInvX, scrW, scrH):
-
- # Call base class implementation
- Character.updateMotion(self, events, platforms, movableObjects, aiCharacters)
- self.x -= self.Vx
-
- keys = pygame.key.get_pressed() # Get keyboard state
-
- # Enable horizontal motion
- if keys[K_LEFT]:
- self.Vx = -self.runSpeed
- self.movingLaterally = True
- self.direction = 0
- if keys[K_RIGHT]:
- self.Vx = self.runSpeed
- self.movingLaterally = True
- self.direction = 1
- if not keys[K_LEFT] and not keys[K_RIGHT]:
- self.Vx = 0
- self.movingLaterally = False
- self.direction = 2
-
- # Move world horizontally and vertically to follow player
- if self.y <= scrH:
- rightEdge = int(0.5 * scrW) + 2
- leftEdge = int(0.5 * scrW) - 2
- bottomEdge = int(0.5 * scrH) + 5
- topEdge = int(0.5 * scrH) - 5
- bgrdX -= self.Vx
- bgrdInvX -= self.Vx
- for obj in movableObjects:
- obj.x -= self.Vx
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] -= self.Vx
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] -= self.Vx
- for obj in movableObjects:
- obj.y -= self.Vy
- if self.x >= rightEdge:
- self.x -= int(self.worldShiftCoefficient * self.runSpeed)
- bgrdX -= int(self.worldShiftCoefficient * self.runSpeed)
- bgrdInvX -= int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.x -= int(self.worldShiftCoefficient * self.runSpeed)
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] -= int(self.worldShiftCoefficient * self.runSpeed)
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] -= int(self.worldShiftCoefficient * self.runSpeed)
- if self.x <= leftEdge:
- self.x += int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.x += int(self.worldShiftCoefficient * self.runSpeed)
- bgrdX += int(self.worldShiftCoefficient * self.runSpeed)
- bgrdInvX += int(self.worldShiftCoefficient * self.runSpeed)
- for aiCharacter in aiCharacters:
- if aiCharacter.limit[0] != -1:
- aiCharacter.limit[0] += int(self.worldShiftCoefficient * self.runSpeed)
- if aiCharacter.limit[1] != -1:
- aiCharacter.limit[1] += int(self.worldShiftCoefficient * self.runSpeed)
- if self.y <= topEdge:
- self.y += int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.y += int(self.worldShiftCoefficient * self.runSpeed)
- if self.y >= bottomEdge:
- self.y -= int(self.worldShiftCoefficient * self.runSpeed)
- for obj in movableObjects:
- obj.y -= int(self.worldShiftCoefficient * self.runSpeed)
- elif randint(0, 10) == 0:
- self.health -= 1
-
- # Allow jumping
- if self.jumping and self.onGround:
- self.jumping = False
- if (keys[K_SPACE] or keys[K_UP]) and self.canJump and self.onGround:
- Character.jump(self)
- self.jumping = True
- self.canJump = False
- self.onGround = False
- if not keys[K_SPACE] and not keys[K_UP] and self.onGround:
- self.canJump = True
-
- # Reset player if dead
- if self.health <= 0:
- self.x = int(0.5 * platforms[0][0] + 0.5 * platforms[0][2])
- self.y = platforms[0][1] - self.height - 10
- self.Vy = 0
- self.Vx = 0
- self.health = self.recoveryHealth
- self.flashing = True
- self.lives -= 1
- if self.x <= 0 or self.x >= scrW:
- self.worldShiftCoefficient = 20
- else:
- self.worldShiftCoefficient = 1.5
-
- # Show game over screen if no lives are remaining
- if self.lives <= 0 and self.x != 0:
- return False
-
- # Check for any other I/O events
- for event in events:
- if event.type == QUIT:
- pygame.quit()
- sys.exit()
- elif event.type == KEYDOWN:
- if event.key == K_ESCAPE:
- pygame.quit()
- sys.exit()
-
- return True
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, surface, FPS=75):
- Character.draw(self, surface)
-
- # DRAW HUD:
- # Player symbol
- surface.blit(self.playerCoins[self.whichChar - 1], self.playerCoinCoords)
- surface.blit(self.coinsMultiplier, (self.spacing + self.heartWidth, int(2.5 * self.spacing)))
- surface.blit(self.hudNumber[self.lives], (5 * self.spacing + self.heartWidth, int(1.5 * self.spacing)))
- # Health
- health = self.health / 2
- for filledHearts in range(1, int(math.floor(health) + 1)):
- if health >= 0:
- surface.blit(self.heartFull, (self.healthInterval * filledHearts - 55, 7 * self.spacing))
- if math.floor(health) != health and health >= 0:
- surface.blit(self.heartHalf, (self.healthInterval * math.ceil(health) - 55, 7 * self.spacing))
- # Coins
- surface.blit(self.coin, (self.spacing, 8 * self.spacing + self.heartHeight))
- surface.blit(self.coinsMultiplier, (self.spacing + self.heartWidth,
- 8 * self.spacing + self.heartHeight + 15))
- coinsAsList = []
- for i in str(self.coins):
- coinsAsList.append(int(i))
- for i in range(0, len(coinsAsList)):
- surface.blit(self.hudNumber[coinsAsList[i]], (3 * self.spacing + self.coinWidth + self.hudTextWidth *
- (i + 1), 7 * self.spacing + self.heartHeight + 15))
- # Key
- if self.hasKey:
- surface.blit(self.key, (self.spacing, 13 * self.spacing + self.heartHeight + 15))
- else:
- surface.blit(self.noKey, (self.spacing, 13 * self.spacing + self.heartHeight + 15))
\ No newline at end of file
diff --git a/pool.py b/pool.py
deleted file mode 100644
index 04ee84a..0000000
--- a/pool.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# coding=utf-8
-import pygame
-from game import *
-
-class Pool(object):
- def __init__(self, x, y, width, height, style='grass'):
- self.x, self.y = x, y
- self.Vx, self.Vy = 0, 0
- self.width, self.height = width, height
-
- # Platform images
- self.image = pygame.image.load('environment\\main\\' + style + 'Mid.png').convert_alpha()
- self.plainImage = pygame.image.load('environment\\main\\' + style + 'Center.png')
- self.leftImage = pygame.image.load('environment\\main\\' + style + 'CliffLeft.png').convert_alpha()
- self.rightImage = pygame.image.load('environment\\main\\' + style + 'CliffRight.png').convert_alpha()
- self.tileWidth = pygame.Surface.get_width(self.image)
-
- # Water images
- self.waterFilled = pygame.image.load('environment\\main\\liquidWater.png').convert_alpha()
- self.waterTop = pygame.image.load('environment\\main\\liquidWaterTop_mid.png').convert_alpha()
-
- # Update coordinates
- self.width -= self.width % self.tileWidth
- self.height -= self.height % self.tileWidth
- self.poolStartX = int(self.x + 2 * self.tileWidth)
- self.poolEndX = int(self.x + self.width - 2 * self.tileWidth)
-
- # Other control variables
- self.tilesOnEitherSide = 2
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, surface):
- self.updateMotion()
- self.draw(surface)
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self):
- # Increment position by velocity
- self.x += self.Vx
- self.y += self.Vy
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, surface):
- # Draw edge platforms
- surface.blit(self.leftImage, (self.x, self.y))
- surface.blit(self.rightImage, (self.x + self.width - self.tileWidth, self.y))
-
- # Draw platform tiles on either side of the pool
- self.poolStartX = int(self.x + self.tilesOnEitherSide * self.tileWidth)
- self.poolEndX = int(self.x + self.width - (1 + self.tilesOnEitherSide) * self.tileWidth)
- for x in range(int(self.x) + self.tileWidth, self.poolStartX + self.tileWidth, self.tileWidth):
- surface.blit(self.image, (x, self.y))
- for x in range(self.poolEndX, int(self.x) + self.width - self.tileWidth, self.tileWidth):
- surface.blit(self.image, (x, self.y))
-
- # Draw pool side columns
- for y in range(int(self.y + self.tileWidth), int(self.y + self.height), self.tileWidth):
- surface.blit(self.plainImage, (self.poolStartX, y))
- surface.blit(self.plainImage, (self.poolEndX, y))
-
- # Draw bottom of pool
- for x in range(self.poolStartX, self.poolEndX + self.tileWidth, self.tileWidth):
- surface.blit(self.plainImage, (x, self.y + self.height))
-
- # Fill with water
- for y in range(int(self.y + self.tileWidth), int(self.y + self.height), self.tileWidth):
- for x in range(self.poolStartX + self.tileWidth, self.poolEndX, self.tileWidth):
- surface.blit(self.waterFilled, (x, y))
- for x in range(self.poolStartX + self.tileWidth, self.poolEndX, self.tileWidth):
- surface.blit(self.waterTop, (x, self.y))
diff --git a/pyproject.toml b/pyproject.toml
new file mode 100644
index 0000000..58286ba
--- /dev/null
+++ b/pyproject.toml
@@ -0,0 +1,95 @@
+[project]
+name = "exit-dash-hyperion"
+version = "2.0.0"
+description = "Exit Dash: Hyperion — a 2D platformer, modernized for Python 3 and pygame-ce."
+readme = "README.md"
+license = { file = "LICENSE" }
+requires-python = ">=3.12"
+authors = [{ name = "Kenneth Sinder" }]
+keywords = ["game", "platformer", "pygame", "pygame-ce"]
+classifiers = [
+ "Development Status :: 5 - Production/Stable",
+ "Environment :: MacOS X",
+ "Environment :: Win32 (MS Windows)",
+ "Environment :: X11 Applications",
+ "Intended Audience :: End Users/Desktop",
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
+ "Topic :: Games/Entertainment :: Arcade",
+]
+dependencies = [
+ "pygame-ce>=2.5.7",
+ "platformdirs>=4.0",
+]
+
+[project.optional-dependencies]
+dev = [
+ "ruff>=0.6",
+ "pytest>=8",
+ "pytest-cov",
+ "mypy>=1.11",
+ "pre-commit",
+]
+
+[project.scripts]
+exit-dash-hyperion = "exit_dash.__main__:main"
+
+[project.urls]
+Homepage = "https://github.com/burincode/exit-dash-hyperion"
+Repository = "https://github.com/burincode/exit-dash-hyperion"
+
+[build-system]
+requires = ["hatchling"]
+build-backend = "hatchling.build"
+
+[tool.hatch.build.targets.wheel]
+packages = ["src/exit_dash"]
+
+[tool.hatch.build.targets.sdist]
+include = ["src/exit_dash", "README.md", "LICENSE", "CREDITS.md"]
+
+[tool.ruff]
+target-version = "py312"
+line-length = 100
+src = ["src", "tests"]
+
+[tool.ruff.lint]
+select = [
+ "E", # pycodestyle errors
+ "F", # pyflakes
+ "W", # pycodestyle warnings
+ "I", # isort
+ "UP", # pyupgrade
+ "B", # flake8-bugbear
+ "SIM", # flake8-simplify
+ "PTH", # flake8-use-pathlib
+ "RUF", # ruff-specific
+ "C4", # flake8-comprehensions
+ "PIE", # flake8-pie
+]
+ignore = [
+ "E501", # line length handled by the formatter
+]
+
+[tool.ruff.lint.per-file-ignores]
+"tests/*" = ["B011"]
+
+[tool.ruff.format]
+quote-style = "double"
+
+[tool.pytest.ini_options]
+testpaths = ["tests"]
+addopts = "-q"
+
+[tool.mypy]
+python_version = "3.12"
+mypy_path = "src"
+explicit_package_bases = true
+namespace_packages = true
+check_untyped_defs = true
+warn_redundant_casts = true
+warn_unused_ignores = true
+# pygame-ce ships partial type information; don't fail on its internals.
+ignore_missing_imports = true
diff --git a/scripts/asset_manifest.py b/scripts/asset_manifest.py
new file mode 100644
index 0000000..46742e3
--- /dev/null
+++ b/scripts/asset_manifest.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+"""Audit which bundled assets are referenced by the game vs orphaned.
+
+Run from the repo root: ``uv run python scripts/asset_manifest.py``.
+
+"Referenced" is computed as the union of:
+
+* every complete asset filename that appears as a string literal in the source, and
+* the *dynamic* filename families the code builds by concatenation (terrain themes,
+ key colours, slime colours, player walk frames, HUD digits, explosion frames, ...),
+ which a plain string scan cannot see.
+
+Matching is by basename, which deliberately *over-keeps* (a file is considered
+referenced if its name is used anywhere), so the orphan list is conservative — safe to
+delete. The script only reports; it never deletes anything.
+"""
+
+from __future__ import annotations
+
+import re
+from pathlib import Path
+
+REPO = Path(__file__).resolve().parent.parent
+ASSETS = REPO / "src" / "exit_dash" / "assets"
+SOURCE_DIRS = [REPO / "src" / "exit_dash"]
+
+ASSET_EXTS = ("png", "jpg", "jpeg", "bmp", "gif", "ogg", "mp3", "wav", "ttf", "otf")
+_FILENAME_RE = re.compile(rf"[\w .()-]+?\.(?:{'|'.join(ASSET_EXTS)})")
+
+THEMES = ["castle", "dirt", "grass", "sand", "snow", "stone"]
+KEY_COLORS = ["blue", "green", "red", "yellow"]
+SLIME_COLORS = ["Blue", "Green"]
+PLAYERS = [1, 2, 3]
+PLAYER_WALK_FRAMES = range(1, 12) # p{n}_walk1..11
+HUD_DIGITS = range(10)
+EXPLOSION_FRAMES = range(3)
+
+
+def dynamic_family_names() -> set[str]:
+ """Concretely expand the filename families the code builds by concatenation."""
+ names: set[str] = set()
+ for theme in THEMES:
+ names |= {f"{theme}Mid.png", f"{theme}CliffLeft.png", f"{theme}CliffRight.png"}
+ names |= {f"key{c}.png" for c in KEY_COLORS}
+ for c in SLIME_COLORS:
+ names |= {f"slime{c}_{s}.png" for s in ("walk", "walkR", "squashed", "squashedR")}
+ for n in PLAYERS:
+ names |= {f"p{n}_front.png", f"p{n}_jump.png", f"p{n}_jump_l.png"}
+ names |= {f"p{n}_duck.png", f"p{n}_duck_l.png"}
+ names |= {f"p{n}_walk{i}.png" for i in PLAYER_WALK_FRAMES}
+ names.add(f"hud_p{n}.png")
+ names |= {f"hud_{d}.png" for d in HUD_DIGITS}
+ names |= {f"explosion{i}.png" for i in EXPLOSION_FRAMES}
+ return names
+
+
+def referenced_names() -> set[str]:
+ names = dynamic_family_names()
+ for source_dir in SOURCE_DIRS:
+ for py in source_dir.rglob("*.py"):
+ for match in _FILENAME_RE.findall(py.read_text(encoding="utf-8")):
+ names.add(match.strip().rsplit("/", 1)[-1].rsplit("\\", 1)[-1])
+ return names
+
+
+def _human(num_bytes: int) -> str:
+ size = float(num_bytes)
+ for unit in ("B", "KB", "MB", "GB"):
+ if size < 1024 or unit == "GB":
+ return f"{size:.1f}{unit}"
+ size /= 1024
+ return f"{size:.1f}GB"
+
+
+def main() -> None:
+ referenced = referenced_names()
+ orphans: list[Path] = []
+ orphan_bytes = 0
+ kept = 0
+
+ for path in sorted(ASSETS.rglob("*")):
+ if not path.is_file() or path.name.endswith(".txt"):
+ continue
+ if path.name in referenced:
+ kept += 1
+ else:
+ orphans.append(path)
+ orphan_bytes += path.stat().st_size
+
+ by_dir: dict[str, tuple[int, int]] = {}
+ for path in orphans:
+ top = path.relative_to(ASSETS).parts[0]
+ count, size = by_dir.get(top, (0, 0))
+ by_dir[top] = (count + 1, size + path.stat().st_size)
+
+ print(f"Referenced names: {len(referenced)} | kept files: {kept} | orphans: {len(orphans)}")
+ print(f"Reclaimable from orphans: {_human(orphan_bytes)}\n")
+ print(f"{'directory':<16} {'orphans':>8} {'size':>10}")
+ print("-" * 36)
+ for top, (count, size) in sorted(by_dir.items(), key=lambda kv: -kv[1][1]):
+ print(f"{top:<16} {count:>8} {_human(size):>10}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/settings.cfg b/settings.cfg
deleted file mode 100644
index 82b4386..0000000
--- a/settings.cfg
+++ /dev/null
@@ -1,9 +0,0 @@
-Game Settings Configuration - DO NOT MODIFY THIS FILE! Change settings in-game!
-True
-True
-True
-True
-True
-True
-0.926315789474
-1080p
\ No newline at end of file
diff --git a/spike.py b/spike.py
deleted file mode 100644
index 5c61002..0000000
--- a/spike.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# coding=utf-8
-import pygame
-from game import *
-
-class FallingSpike(object):
- def __init__(self, x, y):
- # Initialize motion variables, "x" represents the x co-ordinate of the center of the spike
- self.x = x
- self.y = y
- self.Vx = 0
- self.Vy = 0
-
- # Initialize image
- self.image = pygame.image.load('environment\\main\\spikeTop.png')
- self.width = pygame.Surface.get_width(self.image)
- self.height = pygame.Surface.get_height(self.image)
- self.x -= int(0.5 * self.width)
-
- # Other control variables
- self.visible = True
- self.gravityAcceleration = 1.5
- self.dislodged = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def update(self, platforms, chars, blocks, surface):
- self.updateMotion(chars, platforms)
- self.collide(chars, platforms)
- self.draw(platforms, blocks, surface)
-
- # -----------------------------------------------------------------------------------------------------------------
- def collide(self, chars, platforms):
- for char in chars:
- spikeCentre = (int(self.x + self.width / 2), self.y + int(0.5 * self.height))
- charRect = pygame.Rect(char.x, char.y, char.width, char.height)
- if charRect.collidepoint(spikeCentre) and self.visible and not char.flashing:
- char.health -= 1
- char.flashing = True
- self.visible = False
-
- # -----------------------------------------------------------------------------------------------------------------
- def updateMotion(self, chars, platforms):
- # Increment position by velocity
- self.x += self.Vx
- self.y += int(self.Vy)
-
- # Check if spike should be dislodged
- for char in chars:
- if char.x + char.width >= self.x and char.x <= self.x + self.width and char.y >= self.y:
- self.dislodged = True
-
- # Set a terminal velocity
- if self.Vy >= platforms[0].height:
- self.Vy = platforms[0][3] - platforms[0][1] - 5
-
- # Apply gravity if dislodged
- if self.dislodged:
- self.Vy += self.gravityAcceleration
-
- # -----------------------------------------------------------------------------------------------------------------
- def draw(self, platforms, blocks, surface):
- # Only draw if icicle is either stationary or falling and not yet hit an object
- if self.visible:
- surface.blit(self.image, (self.x, self.y))
- for platform in platforms:
- if self.y + 0.5 * self.height >= platform[1] > self.y and platform[0] <= self.x <= platform[2]:
- self.visible = False
- for block in blocks:
- if self.y + 0.5 * self.height >= block[0][1] and self.x + \
- self.width >= block[0][0] and self.x <= block[0][2]:
- self.visible = False
\ No newline at end of file
diff --git a/src/exit_dash/__init__.py b/src/exit_dash/__init__.py
new file mode 100644
index 0000000..90e97f2
--- /dev/null
+++ b/src/exit_dash/__init__.py
@@ -0,0 +1,23 @@
+"""Exit Dash: Hyperion — a 2D platformer, modernized for Python 3 and pygame-ce.
+
+This package is the single source of truth for the game. It is laid out as:
+
+* :mod:`exit_dash.core` — the engine: app loop, scene stack, input, settings, resources.
+* :mod:`exit_dash.scenes` — the screens: title, options, level, editor, game-over.
+* :mod:`exit_dash.entities` — the sprites: player, enemies, platforms, blocks, etc.
+* :mod:`exit_dash.world` — levels, camera, the procedural generator, hints.
+* :mod:`exit_dash.ui` — reusable widgets (buttons, sliders, toggles).
+* :mod:`exit_dash.assets` — bundled images, audio, fonts and level data.
+"""
+
+from __future__ import annotations
+
+import os
+
+# Suppress pygame's "Hello from the pygame community" banner on import. Must be set
+# before pygame is first imported; this package is imported before any submodule that
+# imports pygame, so setting it here covers the whole game.
+os.environ.setdefault("PYGAME_HIDE_SUPPORT_PROMPT", "1")
+
+__version__ = "2.0.0"
+__all__ = ["__version__"]
diff --git a/src/exit_dash/__main__.py b/src/exit_dash/__main__.py
new file mode 100644
index 0000000..90bb522
--- /dev/null
+++ b/src/exit_dash/__main__.py
@@ -0,0 +1,71 @@
+"""Command-line entry point: ``exit-dash-hyperion`` (or ``python -m exit_dash``).
+
+Flags:
+ --windowed run in a window instead of fullscreen
+ --no-vsync disable vertical sync
+ --headless run with no real display/audio (for CI and smoke tests)
+ --frames N run exactly N frames then exit (implies a bounded run)
+ --level N start on level N (default 1)
+ --character N play as character 1, 2 or 3 (default 1)
+"""
+
+from __future__ import annotations
+
+import argparse
+import sys
+
+from exit_dash import __version__
+from exit_dash.core.constants import WINDOW_TITLE
+
+
+def _parse_args(argv: list[str] | None) -> argparse.Namespace:
+ parser = argparse.ArgumentParser(prog="exit-dash-hyperion", description=WINDOW_TITLE)
+ parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
+ parser.add_argument("--windowed", action="store_true", help="run in a window")
+ parser.add_argument("--no-vsync", action="store_true", help="disable vertical sync")
+ parser.add_argument(
+ "--headless", action="store_true", help="run with no display/audio (CI/tests)"
+ )
+ parser.add_argument(
+ "--frames", type=int, default=None, metavar="N", help="run exactly N frames then exit"
+ )
+ parser.add_argument("--level", type=int, default=1, metavar="N", help="start on level N")
+ parser.add_argument(
+ "--character", type=int, default=1, choices=(1, 2, 3), help="character to play as"
+ )
+ return parser.parse_args(argv)
+
+
+def main(argv: list[str] | None = None) -> int:
+ args = _parse_args(argv if argv is not None else sys.argv[1:])
+
+ # Import here so `--version`/`--help` stay fast and import-side-effect free.
+ from exit_dash.core.app import Application
+ from exit_dash.core.scene import Scene
+ from exit_dash.core.settings import load_settings
+
+ settings = load_settings()
+ app = Application(
+ headless=args.headless,
+ fullscreen=not args.windowed and settings.fullscreen,
+ vsync=not args.no_vsync and settings.vsync,
+ )
+ try:
+ scene: Scene
+ if args.headless:
+ # In CI/smoke runs, exercise the actual gameplay loop rather than the title.
+ from exit_dash.scenes.level import LevelScene
+
+ scene = LevelScene(args.level, args.character, settings, audio=app.audio_enabled)
+ else:
+ from exit_dash.scenes.title import TitleScene
+
+ scene = TitleScene(settings, audio=app.audio_enabled)
+ app.run(scene, max_frames=args.frames)
+ finally:
+ app.quit()
+ return 0
+
+
+if __name__ == "__main__":
+ raise SystemExit(main())
diff --git a/src/exit_dash/assets/backgrounds/main/bg_castle.png b/src/exit_dash/assets/backgrounds/main/bg_castle.png
new file mode 100644
index 0000000..8210c28
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_castle.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/bg_castle_inv.png b/src/exit_dash/assets/backgrounds/main/bg_castle_inv.png
new file mode 100644
index 0000000..273621c
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_castle_inv.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/bg_desert.png b/src/exit_dash/assets/backgrounds/main/bg_desert.png
new file mode 100644
index 0000000..ea6ae44
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_desert.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/bg_desert_inv.png b/src/exit_dash/assets/backgrounds/main/bg_desert_inv.png
new file mode 100644
index 0000000..64c806c
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_desert_inv.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/bg_grasslands.png b/src/exit_dash/assets/backgrounds/main/bg_grasslands.png
new file mode 100644
index 0000000..dcbddf4
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_grasslands.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/bg_grasslands_inv.png b/src/exit_dash/assets/backgrounds/main/bg_grasslands_inv.png
new file mode 100644
index 0000000..bf01f23
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_grasslands_inv.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/bg_shroom.png b/src/exit_dash/assets/backgrounds/main/bg_shroom.png
new file mode 100644
index 0000000..1c98c06
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_shroom.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/bg_shroom_inv.png b/src/exit_dash/assets/backgrounds/main/bg_shroom_inv.png
new file mode 100644
index 0000000..2bba1f0
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/bg_shroom_inv.png differ
diff --git a/src/exit_dash/assets/backgrounds/main/red_sky.jpg b/src/exit_dash/assets/backgrounds/main/red_sky.jpg
new file mode 100644
index 0000000..b5776e1
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/red_sky.jpg differ
diff --git a/src/exit_dash/assets/backgrounds/main/title.jpg b/src/exit_dash/assets/backgrounds/main/title.jpg
new file mode 100644
index 0000000..512b346
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/title.jpg differ
diff --git a/src/exit_dash/assets/backgrounds/main/yellow-sky.jpg b/src/exit_dash/assets/backgrounds/main/yellow-sky.jpg
new file mode 100644
index 0000000..6fa9deb
Binary files /dev/null and b/src/exit_dash/assets/backgrounds/main/yellow-sky.jpg differ
diff --git a/src/exit_dash/assets/character/main/license.txt b/src/exit_dash/assets/character/main/license.txt
new file mode 100644
index 0000000..7bd535a
--- /dev/null
+++ b/src/exit_dash/assets/character/main/license.txt
@@ -0,0 +1,15 @@
+
+###############################################################################
+
+ Platformer Art (Xeno Diversity) by Arsonide
+
+ ------------------------------
+
+ License (CC0)
+ http://creativecommons.org/publicdomain/zero/1.0/
+
+ You may use these graphics in personal and commercial projects.
+ Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
+ Credit Arsonide would also be nice but is not mandatory.
+
+###############################################################################
diff --git a/src/exit_dash/assets/character/main/p1_duck.png b/src/exit_dash/assets/character/main/p1_duck.png
new file mode 100644
index 0000000..9a4a93e
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_duck.png differ
diff --git a/src/exit_dash/assets/character/main/p1_duck_l.png b/src/exit_dash/assets/character/main/p1_duck_l.png
new file mode 100644
index 0000000..fd07800
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_duck_l.png differ
diff --git a/src/exit_dash/assets/character/main/p1_front.png b/src/exit_dash/assets/character/main/p1_front.png
new file mode 100644
index 0000000..0826c15
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_front.png differ
diff --git a/src/exit_dash/assets/character/main/p1_hurt.png b/src/exit_dash/assets/character/main/p1_hurt.png
new file mode 100644
index 0000000..4a02ddc
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_hurt.png differ
diff --git a/src/exit_dash/assets/character/main/p1_jump.png b/src/exit_dash/assets/character/main/p1_jump.png
new file mode 100644
index 0000000..93df975
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_jump.png differ
diff --git a/src/exit_dash/assets/character/main/p1_jump_l.png b/src/exit_dash/assets/character/main/p1_jump_l.png
new file mode 100644
index 0000000..1257549
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_jump_l.png differ
diff --git a/src/exit_dash/assets/character/main/p1_stand.png b/src/exit_dash/assets/character/main/p1_stand.png
new file mode 100644
index 0000000..9e43e69
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_stand.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk1.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk1.png
new file mode 100644
index 0000000..aeabaa7
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk1.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk10.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk10.png
new file mode 100644
index 0000000..7a827c1
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk10.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk11.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk11.png
new file mode 100644
index 0000000..8a39dbc
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk11.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk2.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk2.png
new file mode 100644
index 0000000..abae097
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk2.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk3.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk3.png
new file mode 100644
index 0000000..e325fb4
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk3.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk4.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk4.png
new file mode 100644
index 0000000..e9f12f6
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk4.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk5.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk5.png
new file mode 100644
index 0000000..b6c68e3
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk5.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk6.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk6.png
new file mode 100644
index 0000000..d77d94f
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk6.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk7.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk7.png
new file mode 100644
index 0000000..81e8aff
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk7.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk8.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk8.png
new file mode 100644
index 0000000..efb549a
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk8.png differ
diff --git a/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk9.png b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk9.png
new file mode 100644
index 0000000..6df8a32
Binary files /dev/null and b/src/exit_dash/assets/character/main/p1_walk/PNG/p1_walk9.png differ
diff --git a/src/exit_dash/assets/character/main/p2_duck.png b/src/exit_dash/assets/character/main/p2_duck.png
new file mode 100644
index 0000000..9cd5631
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_duck.png differ
diff --git a/src/exit_dash/assets/character/main/p2_duck_l.png b/src/exit_dash/assets/character/main/p2_duck_l.png
new file mode 100644
index 0000000..9e57066
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_duck_l.png differ
diff --git a/src/exit_dash/assets/character/main/p2_front.png b/src/exit_dash/assets/character/main/p2_front.png
new file mode 100644
index 0000000..244ec1e
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_front.png differ
diff --git a/src/exit_dash/assets/character/main/p2_hurt.png b/src/exit_dash/assets/character/main/p2_hurt.png
new file mode 100644
index 0000000..5f1cace
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_hurt.png differ
diff --git a/src/exit_dash/assets/character/main/p2_jump.png b/src/exit_dash/assets/character/main/p2_jump.png
new file mode 100644
index 0000000..5c9d512
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_jump.png differ
diff --git a/src/exit_dash/assets/character/main/p2_jump_l.png b/src/exit_dash/assets/character/main/p2_jump_l.png
new file mode 100644
index 0000000..f55f163
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_jump_l.png differ
diff --git a/src/exit_dash/assets/character/main/p2_stand.png b/src/exit_dash/assets/character/main/p2_stand.png
new file mode 100644
index 0000000..be67ff3
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_stand.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk1.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk1.png
new file mode 100644
index 0000000..0e49fcc
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk1.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk10.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk10.png
new file mode 100644
index 0000000..159690c
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk10.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk11.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk11.png
new file mode 100644
index 0000000..fb39cb5
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk11.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk2.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk2.png
new file mode 100644
index 0000000..18afbe6
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk2.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk3.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk3.png
new file mode 100644
index 0000000..e129c46
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk3.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk4.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk4.png
new file mode 100644
index 0000000..cc79f5e
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk4.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk5.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk5.png
new file mode 100644
index 0000000..3b7ea9a
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk5.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk6.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk6.png
new file mode 100644
index 0000000..bb2226f
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk6.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk7.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk7.png
new file mode 100644
index 0000000..338c34c
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk7.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk8.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk8.png
new file mode 100644
index 0000000..d25754d
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk8.png differ
diff --git a/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk9.png b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk9.png
new file mode 100644
index 0000000..1d5b252
Binary files /dev/null and b/src/exit_dash/assets/character/main/p2_walk/PNG/p2_walk9.png differ
diff --git a/src/exit_dash/assets/character/main/p3_duck.png b/src/exit_dash/assets/character/main/p3_duck.png
new file mode 100644
index 0000000..930005d
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_duck.png differ
diff --git a/src/exit_dash/assets/character/main/p3_duck_l.png b/src/exit_dash/assets/character/main/p3_duck_l.png
new file mode 100644
index 0000000..a438d6c
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_duck_l.png differ
diff --git a/src/exit_dash/assets/character/main/p3_front.png b/src/exit_dash/assets/character/main/p3_front.png
new file mode 100644
index 0000000..c1686c6
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_front.png differ
diff --git a/src/exit_dash/assets/character/main/p3_hurt.png b/src/exit_dash/assets/character/main/p3_hurt.png
new file mode 100644
index 0000000..199237f
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_hurt.png differ
diff --git a/src/exit_dash/assets/character/main/p3_jump.png b/src/exit_dash/assets/character/main/p3_jump.png
new file mode 100644
index 0000000..98bc507
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_jump.png differ
diff --git a/src/exit_dash/assets/character/main/p3_jump_l.png b/src/exit_dash/assets/character/main/p3_jump_l.png
new file mode 100644
index 0000000..f5a65cb
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_jump_l.png differ
diff --git a/src/exit_dash/assets/character/main/p3_stand.png b/src/exit_dash/assets/character/main/p3_stand.png
new file mode 100644
index 0000000..591e4da
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_stand.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk1.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk1.png
new file mode 100644
index 0000000..c3b3f15
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk1.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk10.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk10.png
new file mode 100644
index 0000000..1379d0d
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk10.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk11.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk11.png
new file mode 100644
index 0000000..326392b
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk11.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk2.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk2.png
new file mode 100644
index 0000000..f233de8
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk2.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk3.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk3.png
new file mode 100644
index 0000000..4d087ec
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk3.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk4.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk4.png
new file mode 100644
index 0000000..c29019b
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk4.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk5.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk5.png
new file mode 100644
index 0000000..1a555fc
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk5.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk6.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk6.png
new file mode 100644
index 0000000..8c632db
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk6.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk7.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk7.png
new file mode 100644
index 0000000..91a28e2
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk7.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk8.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk8.png
new file mode 100644
index 0000000..18b828d
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk8.png differ
diff --git a/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk9.png b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk9.png
new file mode 100644
index 0000000..4090a7e
Binary files /dev/null and b/src/exit_dash/assets/character/main/p3_walk/PNG/p3_walk9.png differ
diff --git a/src/exit_dash/assets/enemies/fly/fly_dead.png b/src/exit_dash/assets/enemies/fly/fly_dead.png
new file mode 100644
index 0000000..842f7a1
Binary files /dev/null and b/src/exit_dash/assets/enemies/fly/fly_dead.png differ
diff --git a/src/exit_dash/assets/enemies/fly/fly_dead_r.png b/src/exit_dash/assets/enemies/fly/fly_dead_r.png
new file mode 100644
index 0000000..8d909c2
Binary files /dev/null and b/src/exit_dash/assets/enemies/fly/fly_dead_r.png differ
diff --git a/src/exit_dash/assets/enemies/fly/fly_fly.png b/src/exit_dash/assets/enemies/fly/fly_fly.png
new file mode 100644
index 0000000..abf46c0
Binary files /dev/null and b/src/exit_dash/assets/enemies/fly/fly_fly.png differ
diff --git a/src/exit_dash/assets/enemies/fly/fly_fly_r.png b/src/exit_dash/assets/enemies/fly/fly_fly_r.png
new file mode 100644
index 0000000..857db39
Binary files /dev/null and b/src/exit_dash/assets/enemies/fly/fly_fly_r.png differ
diff --git a/src/exit_dash/assets/enemies/fly/fly_normal.png b/src/exit_dash/assets/enemies/fly/fly_normal.png
new file mode 100644
index 0000000..7d152e6
Binary files /dev/null and b/src/exit_dash/assets/enemies/fly/fly_normal.png differ
diff --git a/src/exit_dash/assets/enemies/other/barnacle.png b/src/exit_dash/assets/enemies/other/barnacle.png
new file mode 100644
index 0000000..a405ef7
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/barnacle.png differ
diff --git a/src/exit_dash/assets/enemies/other/barnacle_bite.png b/src/exit_dash/assets/enemies/other/barnacle_bite.png
new file mode 100644
index 0000000..9fa9c85
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/barnacle_bite.png differ
diff --git a/src/exit_dash/assets/enemies/other/barnacle_dead.png b/src/exit_dash/assets/enemies/other/barnacle_dead.png
new file mode 100644
index 0000000..df09018
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/barnacle_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/barnacle_hit.png b/src/exit_dash/assets/enemies/other/barnacle_hit.png
new file mode 100644
index 0000000..30e9988
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/barnacle_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/bat.png b/src/exit_dash/assets/enemies/other/bat.png
new file mode 100644
index 0000000..46149ab
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bat.png differ
diff --git a/src/exit_dash/assets/enemies/other/bat_dead.png b/src/exit_dash/assets/enemies/other/bat_dead.png
new file mode 100644
index 0000000..a993084
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bat_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/bat_fly.png b/src/exit_dash/assets/enemies/other/bat_fly.png
new file mode 100644
index 0000000..a7c79a4
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bat_fly.png differ
diff --git a/src/exit_dash/assets/enemies/other/bat_hang.png b/src/exit_dash/assets/enemies/other/bat_hang.png
new file mode 100644
index 0000000..665aed6
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bat_hang.png differ
diff --git a/src/exit_dash/assets/enemies/other/bat_hit.png b/src/exit_dash/assets/enemies/other/bat_hit.png
new file mode 100644
index 0000000..8486757
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bat_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/bee.png b/src/exit_dash/assets/enemies/other/bee.png
new file mode 100644
index 0000000..3d63d30
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bee.png differ
diff --git a/src/exit_dash/assets/enemies/other/bee_dead.png b/src/exit_dash/assets/enemies/other/bee_dead.png
new file mode 100644
index 0000000..0fce947
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bee_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/bee_fly.png b/src/exit_dash/assets/enemies/other/bee_fly.png
new file mode 100644
index 0000000..6850f82
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bee_fly.png differ
diff --git a/src/exit_dash/assets/enemies/other/bee_hit.png b/src/exit_dash/assets/enemies/other/bee_hit.png
new file mode 100644
index 0000000..663e305
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/bee_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/blockerBody.png b/src/exit_dash/assets/enemies/other/blockerBody.png
new file mode 100644
index 0000000..f5a9834
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/blockerBody.png differ
diff --git a/src/exit_dash/assets/enemies/other/blockerMad.png b/src/exit_dash/assets/enemies/other/blockerMad.png
new file mode 100644
index 0000000..c0333d1
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/blockerMad.png differ
diff --git a/src/exit_dash/assets/enemies/other/blockerSad.png b/src/exit_dash/assets/enemies/other/blockerSad.png
new file mode 100644
index 0000000..effe609
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/blockerSad.png differ
diff --git a/src/exit_dash/assets/enemies/other/enemies_spritesheet.png b/src/exit_dash/assets/enemies/other/enemies_spritesheet.png
new file mode 100644
index 0000000..da5fee1
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/enemies_spritesheet.png differ
diff --git a/enemies/other/enemies_spritesheet.txt b/src/exit_dash/assets/enemies/other/enemies_spritesheet.txt
similarity index 96%
rename from enemies/other/enemies_spritesheet.txt
rename to src/exit_dash/assets/enemies/other/enemies_spritesheet.txt
index 5a4d091..5aa2262 100644
--- a/enemies/other/enemies_spritesheet.txt
+++ b/src/exit_dash/assets/enemies/other/enemies_spritesheet.txt
@@ -1,18 +1,18 @@
-blockerBody = 203 0 51 51
-blockerMad = 136 66 51 51
-blockerSad = 188 66 51 51
-fishDead = 0 69 66 42
-fishSwim1 = 76 0 66 42
-fishSwim2 = 73 43 62 43
-flyDead = 143 0 59 33
-flyFly1 = 0 32 72 36
-flyFly2 = 0 0 75 31
-pokerMad = 255 0 48 146
-pokerSad = 304 0 48 146
-slimeDead = 0 112 59 12
-slimeWalk1 = 52 125 50 28
-slimeWalk2 = 0 125 51 26
-snailShell = 103 119 44 30
-snailShell_upsidedown = 148 118 44 30
-snailWalk1 = 143 34 54 31
-snailWalk2 = 67 87 57 31
+blockerBody = 203 0 51 51
+blockerMad = 136 66 51 51
+blockerSad = 188 66 51 51
+fishDead = 0 69 66 42
+fishSwim1 = 76 0 66 42
+fishSwim2 = 73 43 62 43
+flyDead = 143 0 59 33
+flyFly1 = 0 32 72 36
+flyFly2 = 0 0 75 31
+pokerMad = 255 0 48 146
+pokerSad = 304 0 48 146
+slimeDead = 0 112 59 12
+slimeWalk1 = 52 125 50 28
+slimeWalk2 = 0 125 51 26
+snailShell = 103 119 44 30
+snailShell_upsidedown = 148 118 44 30
+snailWalk1 = 143 34 54 31
+snailWalk2 = 67 87 57 31
diff --git a/src/exit_dash/assets/enemies/other/fishDead.png b/src/exit_dash/assets/enemies/other/fishDead.png
new file mode 100644
index 0000000..2daba3d
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishDead.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishDead_r.png b/src/exit_dash/assets/enemies/other/fishDead_r.png
new file mode 100644
index 0000000..76909f4
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishDead_r.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishGreen.png b/src/exit_dash/assets/enemies/other/fishGreen.png
new file mode 100644
index 0000000..d192375
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishGreen.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishGreen_dead.png b/src/exit_dash/assets/enemies/other/fishGreen_dead.png
new file mode 100644
index 0000000..765cc57
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishGreen_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishGreen_dead_r.png b/src/exit_dash/assets/enemies/other/fishGreen_dead_r.png
new file mode 100644
index 0000000..653a07c
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishGreen_dead_r.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishGreen_hit.png b/src/exit_dash/assets/enemies/other/fishGreen_hit.png
new file mode 100644
index 0000000..a5b4718
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishGreen_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishGreen_swim.png b/src/exit_dash/assets/enemies/other/fishGreen_swim.png
new file mode 100644
index 0000000..76b1973
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishGreen_swim.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishGreen_swim_r.png b/src/exit_dash/assets/enemies/other/fishGreen_swim_r.png
new file mode 100644
index 0000000..af2cb86
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishGreen_swim_r.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishPink.png b/src/exit_dash/assets/enemies/other/fishPink.png
new file mode 100644
index 0000000..a1ee31d
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishPink.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishPink_dead.png b/src/exit_dash/assets/enemies/other/fishPink_dead.png
new file mode 100644
index 0000000..4f99f6a
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishPink_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishPink_hit.png b/src/exit_dash/assets/enemies/other/fishPink_hit.png
new file mode 100644
index 0000000..a5b4718
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishPink_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishPink_swim.png b/src/exit_dash/assets/enemies/other/fishPink_swim.png
new file mode 100644
index 0000000..90ea1bb
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishPink_swim.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishSwim1.png b/src/exit_dash/assets/enemies/other/fishSwim1.png
new file mode 100644
index 0000000..431fea6
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishSwim1.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishSwim1R.png b/src/exit_dash/assets/enemies/other/fishSwim1R.png
new file mode 100644
index 0000000..5ed6ba5
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishSwim1R.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishSwim2.png b/src/exit_dash/assets/enemies/other/fishSwim2.png
new file mode 100644
index 0000000..2548a85
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishSwim2.png differ
diff --git a/src/exit_dash/assets/enemies/other/fishSwim2R.png b/src/exit_dash/assets/enemies/other/fishSwim2R.png
new file mode 100644
index 0000000..5a3e28b
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fishSwim2R.png differ
diff --git a/src/exit_dash/assets/enemies/other/fly.png b/src/exit_dash/assets/enemies/other/fly.png
new file mode 100644
index 0000000..857d8a5
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fly.png differ
diff --git a/src/exit_dash/assets/enemies/other/flyDead.png b/src/exit_dash/assets/enemies/other/flyDead.png
new file mode 100644
index 0000000..6785ec2
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/flyDead.png differ
diff --git a/src/exit_dash/assets/enemies/other/flyFly1.png b/src/exit_dash/assets/enemies/other/flyFly1.png
new file mode 100644
index 0000000..88fc764
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/flyFly1.png differ
diff --git a/src/exit_dash/assets/enemies/other/flyFly2.png b/src/exit_dash/assets/enemies/other/flyFly2.png
new file mode 100644
index 0000000..53f9982
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/flyFly2.png differ
diff --git a/src/exit_dash/assets/enemies/other/fly_dead.png b/src/exit_dash/assets/enemies/other/fly_dead.png
new file mode 100644
index 0000000..842f7a1
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fly_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/fly_fly.png b/src/exit_dash/assets/enemies/other/fly_fly.png
new file mode 100644
index 0000000..abf46c0
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fly_fly.png differ
diff --git a/src/exit_dash/assets/enemies/other/fly_hit.png b/src/exit_dash/assets/enemies/other/fly_hit.png
new file mode 100644
index 0000000..0c94cbc
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/fly_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/frog.png b/src/exit_dash/assets/enemies/other/frog.png
new file mode 100644
index 0000000..a21606f
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/frog.png differ
diff --git a/src/exit_dash/assets/enemies/other/frog_dead.png b/src/exit_dash/assets/enemies/other/frog_dead.png
new file mode 100644
index 0000000..1ca0939
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/frog_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/frog_hit.png b/src/exit_dash/assets/enemies/other/frog_hit.png
new file mode 100644
index 0000000..64a9844
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/frog_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/frog_leap.png b/src/exit_dash/assets/enemies/other/frog_leap.png
new file mode 100644
index 0000000..30d3909
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/frog_leap.png differ
diff --git a/src/exit_dash/assets/enemies/other/ghost.png b/src/exit_dash/assets/enemies/other/ghost.png
new file mode 100644
index 0000000..535aea2
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ghost.png differ
diff --git a/src/exit_dash/assets/enemies/other/ghost_dead.png b/src/exit_dash/assets/enemies/other/ghost_dead.png
new file mode 100644
index 0000000..17ad3bc
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ghost_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/ghost_hit.png b/src/exit_dash/assets/enemies/other/ghost_hit.png
new file mode 100644
index 0000000..10c6a45
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ghost_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/ghost_normal.png b/src/exit_dash/assets/enemies/other/ghost_normal.png
new file mode 100644
index 0000000..0880c46
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ghost_normal.png differ
diff --git a/src/exit_dash/assets/enemies/other/grassBlock.png b/src/exit_dash/assets/enemies/other/grassBlock.png
new file mode 100644
index 0000000..5b56ccb
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/grassBlock.png differ
diff --git a/src/exit_dash/assets/enemies/other/grassBlock_dead.png b/src/exit_dash/assets/enemies/other/grassBlock_dead.png
new file mode 100644
index 0000000..1ce6e49
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/grassBlock_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/grassBlock_hit.png b/src/exit_dash/assets/enemies/other/grassBlock_hit.png
new file mode 100644
index 0000000..477e695
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/grassBlock_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/grassBlock_jump.png b/src/exit_dash/assets/enemies/other/grassBlock_jump.png
new file mode 100644
index 0000000..bed2660
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/grassBlock_jump.png differ
diff --git a/src/exit_dash/assets/enemies/other/ladyBug.png b/src/exit_dash/assets/enemies/other/ladyBug.png
new file mode 100644
index 0000000..b90cbd6
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ladyBug.png differ
diff --git a/src/exit_dash/assets/enemies/other/ladyBug_fly.png b/src/exit_dash/assets/enemies/other/ladyBug_fly.png
new file mode 100644
index 0000000..43fd7ce
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ladyBug_fly.png differ
diff --git a/src/exit_dash/assets/enemies/other/ladyBug_hit.png b/src/exit_dash/assets/enemies/other/ladyBug_hit.png
new file mode 100644
index 0000000..3d37068
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ladyBug_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/ladyBug_walk.png b/src/exit_dash/assets/enemies/other/ladyBug_walk.png
new file mode 100644
index 0000000..979fefd
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/ladyBug_walk.png differ
diff --git a/src/exit_dash/assets/enemies/other/mouse.png b/src/exit_dash/assets/enemies/other/mouse.png
new file mode 100644
index 0000000..d62fa59
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/mouse.png differ
diff --git a/src/exit_dash/assets/enemies/other/mouse_dead.png b/src/exit_dash/assets/enemies/other/mouse_dead.png
new file mode 100644
index 0000000..dc5eacd
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/mouse_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/mouse_hit.png b/src/exit_dash/assets/enemies/other/mouse_hit.png
new file mode 100644
index 0000000..eed5502
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/mouse_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/mouse_walk.png b/src/exit_dash/assets/enemies/other/mouse_walk.png
new file mode 100644
index 0000000..4346d9d
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/mouse_walk.png differ
diff --git a/src/exit_dash/assets/enemies/other/piranha.png b/src/exit_dash/assets/enemies/other/piranha.png
new file mode 100644
index 0000000..4cbe927
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/piranha.png differ
diff --git a/src/exit_dash/assets/enemies/other/piranha_dead.png b/src/exit_dash/assets/enemies/other/piranha_dead.png
new file mode 100644
index 0000000..a75f400
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/piranha_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/piranha_down.png b/src/exit_dash/assets/enemies/other/piranha_down.png
new file mode 100644
index 0000000..74b3ea7
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/piranha_down.png differ
diff --git a/src/exit_dash/assets/enemies/other/piranha_hit.png b/src/exit_dash/assets/enemies/other/piranha_hit.png
new file mode 100644
index 0000000..3c9fd9d
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/piranha_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/pokerMad.png b/src/exit_dash/assets/enemies/other/pokerMad.png
new file mode 100644
index 0000000..b7ee2ae
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/pokerMad.png differ
diff --git a/src/exit_dash/assets/enemies/other/pokerSad.png b/src/exit_dash/assets/enemies/other/pokerSad.png
new file mode 100644
index 0000000..42de1f6
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/pokerSad.png differ
diff --git a/src/exit_dash/assets/enemies/other/slime.png b/src/exit_dash/assets/enemies/other/slime.png
new file mode 100644
index 0000000..e1209fb
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slime.png differ
diff --git a/src/exit_dash/assets/enemies/other/slimeBlock.png b/src/exit_dash/assets/enemies/other/slimeBlock.png
new file mode 100644
index 0000000..389615b
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slimeBlock.png differ
diff --git a/src/exit_dash/assets/enemies/other/slimeBlock_dead.png b/src/exit_dash/assets/enemies/other/slimeBlock_dead.png
new file mode 100644
index 0000000..2349f59
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slimeBlock_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/slimeBlock_hit.png b/src/exit_dash/assets/enemies/other/slimeBlock_hit.png
new file mode 100644
index 0000000..496e5a8
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slimeBlock_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/slimeDead.png b/src/exit_dash/assets/enemies/other/slimeDead.png
new file mode 100644
index 0000000..d34402c
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slimeDead.png differ
diff --git a/src/exit_dash/assets/enemies/other/slimeWalk1.png b/src/exit_dash/assets/enemies/other/slimeWalk1.png
new file mode 100644
index 0000000..26ee381
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slimeWalk1.png differ
diff --git a/src/exit_dash/assets/enemies/other/slimeWalk2.png b/src/exit_dash/assets/enemies/other/slimeWalk2.png
new file mode 100644
index 0000000..b6ca9f6
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slimeWalk2.png differ
diff --git a/src/exit_dash/assets/enemies/other/slime_dead.png b/src/exit_dash/assets/enemies/other/slime_dead.png
new file mode 100644
index 0000000..82d3996
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slime_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/slime_hit.png b/src/exit_dash/assets/enemies/other/slime_hit.png
new file mode 100644
index 0000000..f20f2b9
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slime_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/slime_squashed.png b/src/exit_dash/assets/enemies/other/slime_squashed.png
new file mode 100644
index 0000000..c40917d
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slime_squashed.png differ
diff --git a/src/exit_dash/assets/enemies/other/slime_walk.png b/src/exit_dash/assets/enemies/other/slime_walk.png
new file mode 100644
index 0000000..e854070
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/slime_walk.png differ
diff --git a/src/exit_dash/assets/enemies/other/snail.png b/src/exit_dash/assets/enemies/other/snail.png
new file mode 100644
index 0000000..b36dda7
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snail.png differ
diff --git a/src/exit_dash/assets/enemies/other/snailShell.png b/src/exit_dash/assets/enemies/other/snailShell.png
new file mode 100644
index 0000000..0e5f525
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snailShell.png differ
diff --git a/src/exit_dash/assets/enemies/other/snailShellR.png b/src/exit_dash/assets/enemies/other/snailShellR.png
new file mode 100644
index 0000000..52920b9
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snailShellR.png differ
diff --git a/src/exit_dash/assets/enemies/other/snailShell_upsidedown.png b/src/exit_dash/assets/enemies/other/snailShell_upsidedown.png
new file mode 100644
index 0000000..7a10a2d
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snailShell_upsidedown.png differ
diff --git a/src/exit_dash/assets/enemies/other/snailWalk1.png b/src/exit_dash/assets/enemies/other/snailWalk1.png
new file mode 100644
index 0000000..0b5a66b
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snailWalk1.png differ
diff --git a/src/exit_dash/assets/enemies/other/snailWalk1R.png b/src/exit_dash/assets/enemies/other/snailWalk1R.png
new file mode 100644
index 0000000..7ed1b75
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snailWalk1R.png differ
diff --git a/src/exit_dash/assets/enemies/other/snailWalk2.png b/src/exit_dash/assets/enemies/other/snailWalk2.png
new file mode 100644
index 0000000..beb37ad
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snailWalk2.png differ
diff --git a/src/exit_dash/assets/enemies/other/snailWalk2R.png b/src/exit_dash/assets/enemies/other/snailWalk2R.png
new file mode 100644
index 0000000..4f31547
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snailWalk2R.png differ
diff --git a/src/exit_dash/assets/enemies/other/snail_hit.png b/src/exit_dash/assets/enemies/other/snail_hit.png
new file mode 100644
index 0000000..b80f949
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snail_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/snail_shell.png b/src/exit_dash/assets/enemies/other/snail_shell.png
new file mode 100644
index 0000000..eab554a
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snail_shell.png differ
diff --git a/src/exit_dash/assets/enemies/other/snail_walk.png b/src/exit_dash/assets/enemies/other/snail_walk.png
new file mode 100644
index 0000000..092fb0d
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snail_walk.png differ
diff --git a/src/exit_dash/assets/enemies/other/snake.png b/src/exit_dash/assets/enemies/other/snake.png
new file mode 100644
index 0000000..b7a3ba1
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snake.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeLava.png b/src/exit_dash/assets/enemies/other/snakeLava.png
new file mode 100644
index 0000000..98b3af8
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeLava.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeLava_ani.png b/src/exit_dash/assets/enemies/other/snakeLava_ani.png
new file mode 100644
index 0000000..6ea8757
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeLava_ani.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeLava_dead.png b/src/exit_dash/assets/enemies/other/snakeLava_dead.png
new file mode 100644
index 0000000..46761e7
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeLava_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeLava_hit.png b/src/exit_dash/assets/enemies/other/snakeLava_hit.png
new file mode 100644
index 0000000..4f8fdb1
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeLava_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeSlime.png b/src/exit_dash/assets/enemies/other/snakeSlime.png
new file mode 100644
index 0000000..6a7d378
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeSlime.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeSlime_ani.png b/src/exit_dash/assets/enemies/other/snakeSlime_ani.png
new file mode 100644
index 0000000..8ec94da
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeSlime_ani.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeSlime_dead.png b/src/exit_dash/assets/enemies/other/snakeSlime_dead.png
new file mode 100644
index 0000000..80823dd
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeSlime_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/snakeSlime_hit.png b/src/exit_dash/assets/enemies/other/snakeSlime_hit.png
new file mode 100644
index 0000000..4f8fdb1
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snakeSlime_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/snake_dead.png b/src/exit_dash/assets/enemies/other/snake_dead.png
new file mode 100644
index 0000000..cec12e2
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snake_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/snake_hit.png b/src/exit_dash/assets/enemies/other/snake_hit.png
new file mode 100644
index 0000000..b00c461
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snake_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/snake_walk.png b/src/exit_dash/assets/enemies/other/snake_walk.png
new file mode 100644
index 0000000..217628b
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/snake_walk.png differ
diff --git a/src/exit_dash/assets/enemies/other/spider.png b/src/exit_dash/assets/enemies/other/spider.png
new file mode 100644
index 0000000..e35c511
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spider.png differ
diff --git a/src/exit_dash/assets/enemies/other/spider_dead.png b/src/exit_dash/assets/enemies/other/spider_dead.png
new file mode 100644
index 0000000..ad752a6
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spider_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/spider_hit.png b/src/exit_dash/assets/enemies/other/spider_hit.png
new file mode 100644
index 0000000..90d3efe
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spider_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/spider_walk1.png b/src/exit_dash/assets/enemies/other/spider_walk1.png
new file mode 100644
index 0000000..6f7bc10
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spider_walk1.png differ
diff --git a/src/exit_dash/assets/enemies/other/spider_walk2.png b/src/exit_dash/assets/enemies/other/spider_walk2.png
new file mode 100644
index 0000000..12ad820
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spider_walk2.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinner.png b/src/exit_dash/assets/enemies/other/spinner.png
new file mode 100644
index 0000000..ffd3ca8
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinner.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinnerHalf.png b/src/exit_dash/assets/enemies/other/spinnerHalf.png
new file mode 100644
index 0000000..cebd10b
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinnerHalf.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinnerHalf_dead.png b/src/exit_dash/assets/enemies/other/spinnerHalf_dead.png
new file mode 100644
index 0000000..fc84200
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinnerHalf_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinnerHalf_hit.png b/src/exit_dash/assets/enemies/other/spinnerHalf_hit.png
new file mode 100644
index 0000000..723400b
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinnerHalf_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinnerHalf_spin.png b/src/exit_dash/assets/enemies/other/spinnerHalf_spin.png
new file mode 100644
index 0000000..2c8c290
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinnerHalf_spin.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinner_dead.png b/src/exit_dash/assets/enemies/other/spinner_dead.png
new file mode 100644
index 0000000..f04b823
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinner_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinner_hit.png b/src/exit_dash/assets/enemies/other/spinner_hit.png
new file mode 100644
index 0000000..bd45589
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinner_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/spinner_spin.png b/src/exit_dash/assets/enemies/other/spinner_spin.png
new file mode 100644
index 0000000..9fdb7ae
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/spinner_spin.png differ
diff --git a/src/exit_dash/assets/enemies/other/worm.png b/src/exit_dash/assets/enemies/other/worm.png
new file mode 100644
index 0000000..03e7952
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/worm.png differ
diff --git a/src/exit_dash/assets/enemies/other/worm_dead.png b/src/exit_dash/assets/enemies/other/worm_dead.png
new file mode 100644
index 0000000..3fe42a5
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/worm_dead.png differ
diff --git a/src/exit_dash/assets/enemies/other/worm_hit.png b/src/exit_dash/assets/enemies/other/worm_hit.png
new file mode 100644
index 0000000..b00c461
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/worm_hit.png differ
diff --git a/src/exit_dash/assets/enemies/other/worm_walk.png b/src/exit_dash/assets/enemies/other/worm_walk.png
new file mode 100644
index 0000000..3d99391
Binary files /dev/null and b/src/exit_dash/assets/enemies/other/worm_walk.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue.png b/src/exit_dash/assets/enemies/slime/slimeBlue.png
new file mode 100644
index 0000000..12b5a44
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue_blue.png b/src/exit_dash/assets/enemies/slime/slimeBlue_blue.png
new file mode 100644
index 0000000..5613605
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue_blue.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue_dead.png b/src/exit_dash/assets/enemies/slime/slimeBlue_dead.png
new file mode 100644
index 0000000..e139956
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue_dead.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue_hit.png b/src/exit_dash/assets/enemies/slime/slimeBlue_hit.png
new file mode 100644
index 0000000..f20f2b9
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue_hit.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue_squashed.png b/src/exit_dash/assets/enemies/slime/slimeBlue_squashed.png
new file mode 100644
index 0000000..d4026a4
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue_squashed.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue_squashedR.png b/src/exit_dash/assets/enemies/slime/slimeBlue_squashedR.png
new file mode 100644
index 0000000..e0351ee
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue_squashedR.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue_walk.png b/src/exit_dash/assets/enemies/slime/slimeBlue_walk.png
new file mode 100644
index 0000000..5613605
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue_walk.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeBlue_walkR.png b/src/exit_dash/assets/enemies/slime/slimeBlue_walkR.png
new file mode 100644
index 0000000..219c32e
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeBlue_walkR.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeDead.png b/src/exit_dash/assets/enemies/slime/slimeDead.png
new file mode 100644
index 0000000..d34402c
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeDead.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeDeadR.png b/src/exit_dash/assets/enemies/slime/slimeDeadR.png
new file mode 100644
index 0000000..ec3c6de
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeDeadR.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeGreen.png b/src/exit_dash/assets/enemies/slime/slimeGreen.png
new file mode 100644
index 0000000..286b9da
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeGreen.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeGreen_dead.png b/src/exit_dash/assets/enemies/slime/slimeGreen_dead.png
new file mode 100644
index 0000000..8404404
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeGreen_dead.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeGreen_hit.png b/src/exit_dash/assets/enemies/slime/slimeGreen_hit.png
new file mode 100644
index 0000000..f20f2b9
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeGreen_hit.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeGreen_squashed.png b/src/exit_dash/assets/enemies/slime/slimeGreen_squashed.png
new file mode 100644
index 0000000..0cddd5d
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeGreen_squashed.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeGreen_squashedR.png b/src/exit_dash/assets/enemies/slime/slimeGreen_squashedR.png
new file mode 100644
index 0000000..07180d8
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeGreen_squashedR.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeGreen_walk.png b/src/exit_dash/assets/enemies/slime/slimeGreen_walk.png
new file mode 100644
index 0000000..5d79e28
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeGreen_walk.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeGreen_walkR.png b/src/exit_dash/assets/enemies/slime/slimeGreen_walkR.png
new file mode 100644
index 0000000..b6bb567
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeGreen_walkR.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeWalk1.png b/src/exit_dash/assets/enemies/slime/slimeWalk1.png
new file mode 100644
index 0000000..26ee381
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeWalk1.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeWalk1R.png b/src/exit_dash/assets/enemies/slime/slimeWalk1R.png
new file mode 100644
index 0000000..4b30f05
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeWalk1R.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeWalk2.png b/src/exit_dash/assets/enemies/slime/slimeWalk2.png
new file mode 100644
index 0000000..b6ca9f6
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeWalk2.png differ
diff --git a/src/exit_dash/assets/enemies/slime/slimeWalk2R.png b/src/exit_dash/assets/enemies/slime/slimeWalk2R.png
new file mode 100644
index 0000000..78f4e2b
Binary files /dev/null and b/src/exit_dash/assets/enemies/slime/slimeWalk2R.png differ
diff --git a/environment/ed_hyperion_assets.zip b/src/exit_dash/assets/environment/ed_hyperion_assets.zip
similarity index 100%
rename from environment/ed_hyperion_assets.zip
rename to src/exit_dash/assets/environment/ed_hyperion_assets.zip
diff --git a/src/exit_dash/assets/environment/main/box.png b/src/exit_dash/assets/environment/main/box.png
new file mode 100644
index 0000000..444618a
Binary files /dev/null and b/src/exit_dash/assets/environment/main/box.png differ
diff --git a/src/exit_dash/assets/environment/main/boxAlt.png b/src/exit_dash/assets/environment/main/boxAlt.png
new file mode 100644
index 0000000..48a9fc2
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/boxCoin.png b/src/exit_dash/assets/environment/main/boxCoin.png
new file mode 100644
index 0000000..ba3a329
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxCoin.png differ
diff --git a/src/exit_dash/assets/environment/main/boxCoinAlt.png b/src/exit_dash/assets/environment/main/boxCoinAlt.png
new file mode 100644
index 0000000..327d89d
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxCoinAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/boxCoinAlt_disabled.png b/src/exit_dash/assets/environment/main/boxCoinAlt_disabled.png
new file mode 100644
index 0000000..69dfff6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxCoinAlt_disabled.png differ
diff --git a/src/exit_dash/assets/environment/main/boxCoin_disabled.png b/src/exit_dash/assets/environment/main/boxCoin_disabled.png
new file mode 100644
index 0000000..9e163ec
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxCoin_disabled.png differ
diff --git a/src/exit_dash/assets/environment/main/boxEmpty.png b/src/exit_dash/assets/environment/main/boxEmpty.png
new file mode 100644
index 0000000..105aab6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxEmpty.png differ
diff --git a/src/exit_dash/assets/environment/main/boxExplosive.png b/src/exit_dash/assets/environment/main/boxExplosive.png
new file mode 100644
index 0000000..3e101c5
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxExplosive.png differ
diff --git a/src/exit_dash/assets/environment/main/boxExplosiveAlt.png b/src/exit_dash/assets/environment/main/boxExplosiveAlt.png
new file mode 100644
index 0000000..e7437d3
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxExplosiveAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/boxExplosive_disabled.png b/src/exit_dash/assets/environment/main/boxExplosive_disabled.png
new file mode 100644
index 0000000..e64b3ad
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxExplosive_disabled.png differ
diff --git a/src/exit_dash/assets/environment/main/boxItem.png b/src/exit_dash/assets/environment/main/boxItem.png
new file mode 100644
index 0000000..482114c
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxItem.png differ
diff --git a/src/exit_dash/assets/environment/main/boxItemAlt.png b/src/exit_dash/assets/environment/main/boxItemAlt.png
new file mode 100644
index 0000000..f88d731
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxItemAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/boxItemAlt_disabled.png b/src/exit_dash/assets/environment/main/boxItemAlt_disabled.png
new file mode 100644
index 0000000..de8f910
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxItemAlt_disabled.png differ
diff --git a/src/exit_dash/assets/environment/main/boxItem_disabled.png b/src/exit_dash/assets/environment/main/boxItem_disabled.png
new file mode 100644
index 0000000..7b2f4d8
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxItem_disabled.png differ
diff --git a/src/exit_dash/assets/environment/main/boxWarning.png b/src/exit_dash/assets/environment/main/boxWarning.png
new file mode 100644
index 0000000..6dfa718
Binary files /dev/null and b/src/exit_dash/assets/environment/main/boxWarning.png differ
diff --git a/src/exit_dash/assets/environment/main/brickWall.png b/src/exit_dash/assets/environment/main/brickWall.png
new file mode 100644
index 0000000..4e2870a
Binary files /dev/null and b/src/exit_dash/assets/environment/main/brickWall.png differ
diff --git a/src/exit_dash/assets/environment/main/bridge.png b/src/exit_dash/assets/environment/main/bridge.png
new file mode 100644
index 0000000..ce4e3a6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/bridge.png differ
diff --git a/src/exit_dash/assets/environment/main/bridgeLogs.png b/src/exit_dash/assets/environment/main/bridgeLogs.png
new file mode 100644
index 0000000..ea0b5ae
Binary files /dev/null and b/src/exit_dash/assets/environment/main/bridgeLogs.png differ
diff --git a/src/exit_dash/assets/environment/main/castle.png b/src/exit_dash/assets/environment/main/castle.png
new file mode 100644
index 0000000..402fb8e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castle.png differ
diff --git a/src/exit_dash/assets/environment/main/castleCenter.png b/src/exit_dash/assets/environment/main/castleCenter.png
new file mode 100644
index 0000000..3e94615
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleCenter.png differ
diff --git a/src/exit_dash/assets/environment/main/castleCenter_rounded.png b/src/exit_dash/assets/environment/main/castleCenter_rounded.png
new file mode 100644
index 0000000..194c90e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleCenter_rounded.png differ
diff --git a/src/exit_dash/assets/environment/main/castleCliffLeft.png b/src/exit_dash/assets/environment/main/castleCliffLeft.png
new file mode 100644
index 0000000..32b6a5c
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleCliffLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/castleCliffLeftAlt.png b/src/exit_dash/assets/environment/main/castleCliffLeftAlt.png
new file mode 100644
index 0000000..f953573
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleCliffLeftAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/castleCliffRight.png b/src/exit_dash/assets/environment/main/castleCliffRight.png
new file mode 100644
index 0000000..096f7d1
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleCliffRight.png differ
diff --git a/src/exit_dash/assets/environment/main/castleCliffRightAlt.png b/src/exit_dash/assets/environment/main/castleCliffRightAlt.png
new file mode 100644
index 0000000..5ea6618
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleCliffRightAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHalf.png b/src/exit_dash/assets/environment/main/castleHalf.png
new file mode 100644
index 0000000..3aea96f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHalf.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHalfLeft.png b/src/exit_dash/assets/environment/main/castleHalfLeft.png
new file mode 100644
index 0000000..d4264f7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHalfLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHalfMid.png b/src/exit_dash/assets/environment/main/castleHalfMid.png
new file mode 100644
index 0000000..7d407a5
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHalfMid.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHalfRight.png b/src/exit_dash/assets/environment/main/castleHalfRight.png
new file mode 100644
index 0000000..491596f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHalfRight.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHillLeft.png b/src/exit_dash/assets/environment/main/castleHillLeft.png
new file mode 100644
index 0000000..04118cf
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHillLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHillLeft2.png b/src/exit_dash/assets/environment/main/castleHillLeft2.png
new file mode 100644
index 0000000..5d35fcb
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHillLeft2.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHillRight.png b/src/exit_dash/assets/environment/main/castleHillRight.png
new file mode 100644
index 0000000..6dd390f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHillRight.png differ
diff --git a/src/exit_dash/assets/environment/main/castleHillRight2.png b/src/exit_dash/assets/environment/main/castleHillRight2.png
new file mode 100644
index 0000000..24d6d82
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleHillRight2.png differ
diff --git a/environment/main/castleLedgeLeft.png b/src/exit_dash/assets/environment/main/castleLedgeLeft.png
similarity index 100%
rename from environment/main/castleLedgeLeft.png
rename to src/exit_dash/assets/environment/main/castleLedgeLeft.png
diff --git a/src/exit_dash/assets/environment/main/castleLedgeRight.png b/src/exit_dash/assets/environment/main/castleLedgeRight.png
new file mode 100644
index 0000000..1429919
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleLedgeRight.png differ
diff --git a/src/exit_dash/assets/environment/main/castleLeft.png b/src/exit_dash/assets/environment/main/castleLeft.png
new file mode 100644
index 0000000..6b753d5
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/castleMid.png b/src/exit_dash/assets/environment/main/castleMid.png
new file mode 100644
index 0000000..a941dc9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleMid.png differ
diff --git a/src/exit_dash/assets/environment/main/castleRight.png b/src/exit_dash/assets/environment/main/castleRight.png
new file mode 100644
index 0000000..d9d64eb
Binary files /dev/null and b/src/exit_dash/assets/environment/main/castleRight.png differ
diff --git a/src/exit_dash/assets/environment/main/coinGold.png b/src/exit_dash/assets/environment/main/coinGold.png
new file mode 100644
index 0000000..2afec7c
Binary files /dev/null and b/src/exit_dash/assets/environment/main/coinGold.png differ
diff --git a/src/exit_dash/assets/environment/main/dirt.png b/src/exit_dash/assets/environment/main/dirt.png
new file mode 100644
index 0000000..ee895c9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirt.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtCenter.png b/src/exit_dash/assets/environment/main/dirtCenter.png
new file mode 100644
index 0000000..1ee4f5d
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtCenter.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtCenter_rounded.png b/src/exit_dash/assets/environment/main/dirtCenter_rounded.png
new file mode 100644
index 0000000..1de46fc
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtCenter_rounded.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtCliffLeft.png b/src/exit_dash/assets/environment/main/dirtCliffLeft.png
new file mode 100644
index 0000000..0c44da2
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtCliffLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtCliffLeftAlt.png b/src/exit_dash/assets/environment/main/dirtCliffLeftAlt.png
new file mode 100644
index 0000000..9e0cce4
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtCliffLeftAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtCliffRight.png b/src/exit_dash/assets/environment/main/dirtCliffRight.png
new file mode 100644
index 0000000..724a8a0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtCliffRight.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtCliffRightAlt.png b/src/exit_dash/assets/environment/main/dirtCliffRightAlt.png
new file mode 100644
index 0000000..adaacdc
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtCliffRightAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHalf.png b/src/exit_dash/assets/environment/main/dirtHalf.png
new file mode 100644
index 0000000..040a90e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHalf.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHalfLeft.png b/src/exit_dash/assets/environment/main/dirtHalfLeft.png
new file mode 100644
index 0000000..772cba9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHalfLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHalfMid.png b/src/exit_dash/assets/environment/main/dirtHalfMid.png
new file mode 100644
index 0000000..b6c80a5
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHalfMid.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHalfRight.png b/src/exit_dash/assets/environment/main/dirtHalfRight.png
new file mode 100644
index 0000000..12a24e0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHalfRight.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHillLeft.png b/src/exit_dash/assets/environment/main/dirtHillLeft.png
new file mode 100644
index 0000000..7da87c7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHillLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHillLeft2.png b/src/exit_dash/assets/environment/main/dirtHillLeft2.png
new file mode 100644
index 0000000..6ee0330
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHillLeft2.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHillRight.png b/src/exit_dash/assets/environment/main/dirtHillRight.png
new file mode 100644
index 0000000..fa711e0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHillRight.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtHillRight2.png b/src/exit_dash/assets/environment/main/dirtHillRight2.png
new file mode 100644
index 0000000..e3f7930
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtHillRight2.png differ
diff --git a/environment/main/dirtLedgeLeft.png b/src/exit_dash/assets/environment/main/dirtLedgeLeft.png
similarity index 100%
rename from environment/main/dirtLedgeLeft.png
rename to src/exit_dash/assets/environment/main/dirtLedgeLeft.png
diff --git a/environment/main/dirtLedgeRight.png b/src/exit_dash/assets/environment/main/dirtLedgeRight.png
similarity index 100%
rename from environment/main/dirtLedgeRight.png
rename to src/exit_dash/assets/environment/main/dirtLedgeRight.png
diff --git a/src/exit_dash/assets/environment/main/dirtLeft.png b/src/exit_dash/assets/environment/main/dirtLeft.png
new file mode 100644
index 0000000..6046541
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtMid.png b/src/exit_dash/assets/environment/main/dirtMid.png
new file mode 100644
index 0000000..c5ede01
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtMid.png differ
diff --git a/src/exit_dash/assets/environment/main/dirtRight.png b/src/exit_dash/assets/environment/main/dirtRight.png
new file mode 100644
index 0000000..9d8d671
Binary files /dev/null and b/src/exit_dash/assets/environment/main/dirtRight.png differ
diff --git a/src/exit_dash/assets/environment/main/door_closedMid.png b/src/exit_dash/assets/environment/main/door_closedMid.png
new file mode 100644
index 0000000..2c3dd0a
Binary files /dev/null and b/src/exit_dash/assets/environment/main/door_closedMid.png differ
diff --git a/src/exit_dash/assets/environment/main/door_closedTop.png b/src/exit_dash/assets/environment/main/door_closedTop.png
new file mode 100644
index 0000000..cf8df20
Binary files /dev/null and b/src/exit_dash/assets/environment/main/door_closedTop.png differ
diff --git a/src/exit_dash/assets/environment/main/door_openMid.png b/src/exit_dash/assets/environment/main/door_openMid.png
new file mode 100644
index 0000000..ccd84ce
Binary files /dev/null and b/src/exit_dash/assets/environment/main/door_openMid.png differ
diff --git a/src/exit_dash/assets/environment/main/door_openTop.png b/src/exit_dash/assets/environment/main/door_openTop.png
new file mode 100644
index 0000000..a807ec7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/door_openTop.png differ
diff --git a/src/exit_dash/assets/environment/main/explosion0.png b/src/exit_dash/assets/environment/main/explosion0.png
new file mode 100644
index 0000000..4a506b7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/explosion0.png differ
diff --git a/src/exit_dash/assets/environment/main/explosion1.png b/src/exit_dash/assets/environment/main/explosion1.png
new file mode 100644
index 0000000..a481ad7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/explosion1.png differ
diff --git a/src/exit_dash/assets/environment/main/explosion2.png b/src/exit_dash/assets/environment/main/explosion2.png
new file mode 100644
index 0000000..658fb5b
Binary files /dev/null and b/src/exit_dash/assets/environment/main/explosion2.png differ
diff --git a/src/exit_dash/assets/environment/main/fence.png b/src/exit_dash/assets/environment/main/fence.png
new file mode 100644
index 0000000..2adb3e1
Binary files /dev/null and b/src/exit_dash/assets/environment/main/fence.png differ
diff --git a/src/exit_dash/assets/environment/main/fenceBroken.png b/src/exit_dash/assets/environment/main/fenceBroken.png
new file mode 100644
index 0000000..cc82e0a
Binary files /dev/null and b/src/exit_dash/assets/environment/main/fenceBroken.png differ
diff --git a/src/exit_dash/assets/environment/main/grass.png b/src/exit_dash/assets/environment/main/grass.png
new file mode 100644
index 0000000..3063e26
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grass.png differ
diff --git a/src/exit_dash/assets/environment/main/grassCenter.png b/src/exit_dash/assets/environment/main/grassCenter.png
new file mode 100644
index 0000000..17ab258
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassCenter.png differ
diff --git a/src/exit_dash/assets/environment/main/grassCenter_rounded.png b/src/exit_dash/assets/environment/main/grassCenter_rounded.png
new file mode 100644
index 0000000..0015e73
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassCenter_rounded.png differ
diff --git a/src/exit_dash/assets/environment/main/grassCliffLeft.png b/src/exit_dash/assets/environment/main/grassCliffLeft.png
new file mode 100644
index 0000000..0d44d8a
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassCliffLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/grassCliffLeftAlt.png b/src/exit_dash/assets/environment/main/grassCliffLeftAlt.png
new file mode 100644
index 0000000..af8aaa9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassCliffLeftAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/grassCliffRight.png b/src/exit_dash/assets/environment/main/grassCliffRight.png
new file mode 100644
index 0000000..f027147
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassCliffRight.png differ
diff --git a/src/exit_dash/assets/environment/main/grassCliffRightAlt.png b/src/exit_dash/assets/environment/main/grassCliffRightAlt.png
new file mode 100644
index 0000000..b497c85
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassCliffRightAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHalf.png b/src/exit_dash/assets/environment/main/grassHalf.png
new file mode 100644
index 0000000..d9ef787
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHalf.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHalfLeft.png b/src/exit_dash/assets/environment/main/grassHalfLeft.png
new file mode 100644
index 0000000..23a83b6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHalfLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHalfMid.png b/src/exit_dash/assets/environment/main/grassHalfMid.png
new file mode 100644
index 0000000..82eb37f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHalfMid.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHalfRight.png b/src/exit_dash/assets/environment/main/grassHalfRight.png
new file mode 100644
index 0000000..df24a27
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHalfRight.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHillLeft.png b/src/exit_dash/assets/environment/main/grassHillLeft.png
new file mode 100644
index 0000000..0fde49b
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHillLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHillLeft2.png b/src/exit_dash/assets/environment/main/grassHillLeft2.png
new file mode 100644
index 0000000..93b91da
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHillLeft2.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHillRight.png b/src/exit_dash/assets/environment/main/grassHillRight.png
new file mode 100644
index 0000000..52685ee
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHillRight.png differ
diff --git a/src/exit_dash/assets/environment/main/grassHillRight2.png b/src/exit_dash/assets/environment/main/grassHillRight2.png
new file mode 100644
index 0000000..9e3a1f0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassHillRight2.png differ
diff --git a/src/exit_dash/assets/environment/main/grassLedgeLeft.png b/src/exit_dash/assets/environment/main/grassLedgeLeft.png
new file mode 100644
index 0000000..170d8f7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassLedgeLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/grassLedgeRight.png b/src/exit_dash/assets/environment/main/grassLedgeRight.png
new file mode 100644
index 0000000..baef482
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassLedgeRight.png differ
diff --git a/src/exit_dash/assets/environment/main/grassLeft.png b/src/exit_dash/assets/environment/main/grassLeft.png
new file mode 100644
index 0000000..8faa0f3
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/grassMid.png b/src/exit_dash/assets/environment/main/grassMid.png
new file mode 100644
index 0000000..ace09eb
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassMid.png differ
diff --git a/src/exit_dash/assets/environment/main/grassRight.png b/src/exit_dash/assets/environment/main/grassRight.png
new file mode 100644
index 0000000..db42e6b
Binary files /dev/null and b/src/exit_dash/assets/environment/main/grassRight.png differ
diff --git a/src/exit_dash/assets/environment/main/hill_large.png b/src/exit_dash/assets/environment/main/hill_large.png
new file mode 100644
index 0000000..ebaca4e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/hill_large.png differ
diff --git a/src/exit_dash/assets/environment/main/hill_largeAlt.png b/src/exit_dash/assets/environment/main/hill_largeAlt.png
new file mode 100644
index 0000000..aa1e80e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/hill_largeAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/hill_small.png b/src/exit_dash/assets/environment/main/hill_small.png
new file mode 100644
index 0000000..0c341e8
Binary files /dev/null and b/src/exit_dash/assets/environment/main/hill_small.png differ
diff --git a/src/exit_dash/assets/environment/main/hill_smallAlt.png b/src/exit_dash/assets/environment/main/hill_smallAlt.png
new file mode 100644
index 0000000..08a0091
Binary files /dev/null and b/src/exit_dash/assets/environment/main/hill_smallAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/keyblue.png b/src/exit_dash/assets/environment/main/keyblue.png
new file mode 100644
index 0000000..b446fbc
Binary files /dev/null and b/src/exit_dash/assets/environment/main/keyblue.png differ
diff --git a/src/exit_dash/assets/environment/main/keygreen.png b/src/exit_dash/assets/environment/main/keygreen.png
new file mode 100644
index 0000000..717c134
Binary files /dev/null and b/src/exit_dash/assets/environment/main/keygreen.png differ
diff --git a/src/exit_dash/assets/environment/main/keyred.png b/src/exit_dash/assets/environment/main/keyred.png
new file mode 100644
index 0000000..92aa3c0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/keyred.png differ
diff --git a/src/exit_dash/assets/environment/main/keyyellow.png b/src/exit_dash/assets/environment/main/keyyellow.png
new file mode 100644
index 0000000..90733f0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/keyyellow.png differ
diff --git a/src/exit_dash/assets/environment/main/ladder_mid.png b/src/exit_dash/assets/environment/main/ladder_mid.png
new file mode 100644
index 0000000..3edce49
Binary files /dev/null and b/src/exit_dash/assets/environment/main/ladder_mid.png differ
diff --git a/src/exit_dash/assets/environment/main/ladder_top.png b/src/exit_dash/assets/environment/main/ladder_top.png
new file mode 100644
index 0000000..a9798ea
Binary files /dev/null and b/src/exit_dash/assets/environment/main/ladder_top.png differ
diff --git a/src/exit_dash/assets/environment/main/liquidLava.png b/src/exit_dash/assets/environment/main/liquidLava.png
new file mode 100644
index 0000000..89c53fc
Binary files /dev/null and b/src/exit_dash/assets/environment/main/liquidLava.png differ
diff --git a/src/exit_dash/assets/environment/main/liquidLavaTop.png b/src/exit_dash/assets/environment/main/liquidLavaTop.png
new file mode 100644
index 0000000..ed9e31e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/liquidLavaTop.png differ
diff --git a/src/exit_dash/assets/environment/main/liquidLavaTop_mid.png b/src/exit_dash/assets/environment/main/liquidLavaTop_mid.png
new file mode 100644
index 0000000..4719748
Binary files /dev/null and b/src/exit_dash/assets/environment/main/liquidLavaTop_mid.png differ
diff --git a/src/exit_dash/assets/environment/main/liquidWater.png b/src/exit_dash/assets/environment/main/liquidWater.png
new file mode 100644
index 0000000..a2cac18
Binary files /dev/null and b/src/exit_dash/assets/environment/main/liquidWater.png differ
diff --git a/src/exit_dash/assets/environment/main/liquidWaterTop.png b/src/exit_dash/assets/environment/main/liquidWaterTop.png
new file mode 100644
index 0000000..e3fcf69
Binary files /dev/null and b/src/exit_dash/assets/environment/main/liquidWaterTop.png differ
diff --git a/src/exit_dash/assets/environment/main/liquidWaterTop_mid.png b/src/exit_dash/assets/environment/main/liquidWaterTop_mid.png
new file mode 100644
index 0000000..209899a
Binary files /dev/null and b/src/exit_dash/assets/environment/main/liquidWaterTop_mid.png differ
diff --git a/src/exit_dash/assets/environment/main/lock_blue.png b/src/exit_dash/assets/environment/main/lock_blue.png
new file mode 100644
index 0000000..ea3026e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/lock_blue.png differ
diff --git a/src/exit_dash/assets/environment/main/lock_green.png b/src/exit_dash/assets/environment/main/lock_green.png
new file mode 100644
index 0000000..9f5a43f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/lock_green.png differ
diff --git a/src/exit_dash/assets/environment/main/lock_red.png b/src/exit_dash/assets/environment/main/lock_red.png
new file mode 100644
index 0000000..b8220f0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/lock_red.png differ
diff --git a/src/exit_dash/assets/environment/main/lock_yellow.png b/src/exit_dash/assets/environment/main/lock_yellow.png
new file mode 100644
index 0000000..87e368c
Binary files /dev/null and b/src/exit_dash/assets/environment/main/lock_yellow.png differ
diff --git a/src/exit_dash/assets/environment/main/rockHillLeft.png b/src/exit_dash/assets/environment/main/rockHillLeft.png
new file mode 100644
index 0000000..654f7ee
Binary files /dev/null and b/src/exit_dash/assets/environment/main/rockHillLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/rockHillRight.png b/src/exit_dash/assets/environment/main/rockHillRight.png
new file mode 100644
index 0000000..f4ae523
Binary files /dev/null and b/src/exit_dash/assets/environment/main/rockHillRight.png differ
diff --git a/src/exit_dash/assets/environment/main/ropeAttached.png b/src/exit_dash/assets/environment/main/ropeAttached.png
new file mode 100644
index 0000000..83282c7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/ropeAttached.png differ
diff --git a/src/exit_dash/assets/environment/main/ropeHorizontal.png b/src/exit_dash/assets/environment/main/ropeHorizontal.png
new file mode 100644
index 0000000..6e9d4fe
Binary files /dev/null and b/src/exit_dash/assets/environment/main/ropeHorizontal.png differ
diff --git a/src/exit_dash/assets/environment/main/ropeVertical.png b/src/exit_dash/assets/environment/main/ropeVertical.png
new file mode 100644
index 0000000..9cae69b
Binary files /dev/null and b/src/exit_dash/assets/environment/main/ropeVertical.png differ
diff --git a/src/exit_dash/assets/environment/main/sand.png b/src/exit_dash/assets/environment/main/sand.png
new file mode 100644
index 0000000..ace7718
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sand.png differ
diff --git a/src/exit_dash/assets/environment/main/sandCenter.png b/src/exit_dash/assets/environment/main/sandCenter.png
new file mode 100644
index 0000000..17ab258
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandCenter.png differ
diff --git a/src/exit_dash/assets/environment/main/sandCenter_rounded.png b/src/exit_dash/assets/environment/main/sandCenter_rounded.png
new file mode 100644
index 0000000..0015e73
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandCenter_rounded.png differ
diff --git a/src/exit_dash/assets/environment/main/sandCliffLeft.png b/src/exit_dash/assets/environment/main/sandCliffLeft.png
new file mode 100644
index 0000000..f8f775f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandCliffLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/sandCliffLeftAlt.png b/src/exit_dash/assets/environment/main/sandCliffLeftAlt.png
new file mode 100644
index 0000000..0c85121
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandCliffLeftAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/sandCliffRight.png b/src/exit_dash/assets/environment/main/sandCliffRight.png
new file mode 100644
index 0000000..a2a21fc
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandCliffRight.png differ
diff --git a/src/exit_dash/assets/environment/main/sandCliffRightAlt.png b/src/exit_dash/assets/environment/main/sandCliffRightAlt.png
new file mode 100644
index 0000000..f041909
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandCliffRightAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHalf.png b/src/exit_dash/assets/environment/main/sandHalf.png
new file mode 100644
index 0000000..56aba63
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHalf.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHalfLeft.png b/src/exit_dash/assets/environment/main/sandHalfLeft.png
new file mode 100644
index 0000000..364dba6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHalfLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHalfMid.png b/src/exit_dash/assets/environment/main/sandHalfMid.png
new file mode 100644
index 0000000..ecb2bfe
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHalfMid.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHalfRight.png b/src/exit_dash/assets/environment/main/sandHalfRight.png
new file mode 100644
index 0000000..e611920
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHalfRight.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHillLeft.png b/src/exit_dash/assets/environment/main/sandHillLeft.png
new file mode 100644
index 0000000..26d8df8
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHillLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHillLeft2.png b/src/exit_dash/assets/environment/main/sandHillLeft2.png
new file mode 100644
index 0000000..71374d6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHillLeft2.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHillRight.png b/src/exit_dash/assets/environment/main/sandHillRight.png
new file mode 100644
index 0000000..f24b1ff
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHillRight.png differ
diff --git a/src/exit_dash/assets/environment/main/sandHillRight2.png b/src/exit_dash/assets/environment/main/sandHillRight2.png
new file mode 100644
index 0000000..0129f55
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandHillRight2.png differ
diff --git a/src/exit_dash/assets/environment/main/sandLedgeLeft.png b/src/exit_dash/assets/environment/main/sandLedgeLeft.png
new file mode 100644
index 0000000..01f77b3
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandLedgeLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/sandLedgeRight.png b/src/exit_dash/assets/environment/main/sandLedgeRight.png
new file mode 100644
index 0000000..99f7286
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandLedgeRight.png differ
diff --git a/src/exit_dash/assets/environment/main/sandLeft.png b/src/exit_dash/assets/environment/main/sandLeft.png
new file mode 100644
index 0000000..e4438b6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/sandMid.png b/src/exit_dash/assets/environment/main/sandMid.png
new file mode 100644
index 0000000..ce4ffc9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandMid.png differ
diff --git a/src/exit_dash/assets/environment/main/sandRight.png b/src/exit_dash/assets/environment/main/sandRight.png
new file mode 100644
index 0000000..00ce9fb
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sandRight.png differ
diff --git a/src/exit_dash/assets/environment/main/sign.png b/src/exit_dash/assets/environment/main/sign.png
new file mode 100644
index 0000000..68d6582
Binary files /dev/null and b/src/exit_dash/assets/environment/main/sign.png differ
diff --git a/src/exit_dash/assets/environment/main/signExit.png b/src/exit_dash/assets/environment/main/signExit.png
new file mode 100644
index 0000000..8a78514
Binary files /dev/null and b/src/exit_dash/assets/environment/main/signExit.png differ
diff --git a/src/exit_dash/assets/environment/main/signLeft.png b/src/exit_dash/assets/environment/main/signLeft.png
new file mode 100644
index 0000000..76a39b1
Binary files /dev/null and b/src/exit_dash/assets/environment/main/signLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/signRight.png b/src/exit_dash/assets/environment/main/signRight.png
new file mode 100644
index 0000000..d7c3e23
Binary files /dev/null and b/src/exit_dash/assets/environment/main/signRight.png differ
diff --git a/src/exit_dash/assets/environment/main/snow.png b/src/exit_dash/assets/environment/main/snow.png
new file mode 100644
index 0000000..cfe6156
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snow.png differ
diff --git a/src/exit_dash/assets/environment/main/snowCenter.png b/src/exit_dash/assets/environment/main/snowCenter.png
new file mode 100644
index 0000000..c687db0
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowCenter.png differ
diff --git a/src/exit_dash/assets/environment/main/snowCenter_rounded.png b/src/exit_dash/assets/environment/main/snowCenter_rounded.png
new file mode 100644
index 0000000..60626e2
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowCenter_rounded.png differ
diff --git a/src/exit_dash/assets/environment/main/snowCliffLeft.png b/src/exit_dash/assets/environment/main/snowCliffLeft.png
new file mode 100644
index 0000000..daaf824
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowCliffLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/snowCliffLeftAlt.png b/src/exit_dash/assets/environment/main/snowCliffLeftAlt.png
new file mode 100644
index 0000000..8454f1c
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowCliffLeftAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/snowCliffRight.png b/src/exit_dash/assets/environment/main/snowCliffRight.png
new file mode 100644
index 0000000..66f7c4e
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowCliffRight.png differ
diff --git a/src/exit_dash/assets/environment/main/snowCliffRightAlt.png b/src/exit_dash/assets/environment/main/snowCliffRightAlt.png
new file mode 100644
index 0000000..63acb63
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowCliffRightAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHalf.png b/src/exit_dash/assets/environment/main/snowHalf.png
new file mode 100644
index 0000000..dbc87d9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHalf.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHalfLeft.png b/src/exit_dash/assets/environment/main/snowHalfLeft.png
new file mode 100644
index 0000000..a824b56
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHalfLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHalfMid.png b/src/exit_dash/assets/environment/main/snowHalfMid.png
new file mode 100644
index 0000000..165f1d9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHalfMid.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHalfRight.png b/src/exit_dash/assets/environment/main/snowHalfRight.png
new file mode 100644
index 0000000..4547893
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHalfRight.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHillLeft.png b/src/exit_dash/assets/environment/main/snowHillLeft.png
new file mode 100644
index 0000000..9f33536
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHillLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHillLeft2.png b/src/exit_dash/assets/environment/main/snowHillLeft2.png
new file mode 100644
index 0000000..f239cda
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHillLeft2.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHillRight.png b/src/exit_dash/assets/environment/main/snowHillRight.png
new file mode 100644
index 0000000..b71e889
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHillRight.png differ
diff --git a/src/exit_dash/assets/environment/main/snowHillRight2.png b/src/exit_dash/assets/environment/main/snowHillRight2.png
new file mode 100644
index 0000000..e80581d
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowHillRight2.png differ
diff --git a/src/exit_dash/assets/environment/main/snowLedgeLeft.png b/src/exit_dash/assets/environment/main/snowLedgeLeft.png
new file mode 100644
index 0000000..35aa0f4
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowLedgeLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/snowLedgeRight.png b/src/exit_dash/assets/environment/main/snowLedgeRight.png
new file mode 100644
index 0000000..64a37e9
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowLedgeRight.png differ
diff --git a/src/exit_dash/assets/environment/main/snowLeft.png b/src/exit_dash/assets/environment/main/snowLeft.png
new file mode 100644
index 0000000..c194992
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/snowMid.png b/src/exit_dash/assets/environment/main/snowMid.png
new file mode 100644
index 0000000..05b9597
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowMid.png differ
diff --git a/src/exit_dash/assets/environment/main/snowRight.png b/src/exit_dash/assets/environment/main/snowRight.png
new file mode 100644
index 0000000..ff02c91
Binary files /dev/null and b/src/exit_dash/assets/environment/main/snowRight.png differ
diff --git a/src/exit_dash/assets/environment/main/spikeTop.png b/src/exit_dash/assets/environment/main/spikeTop.png
new file mode 100644
index 0000000..cb747bd
Binary files /dev/null and b/src/exit_dash/assets/environment/main/spikeTop.png differ
diff --git a/src/exit_dash/assets/environment/main/spikesBottom.png b/src/exit_dash/assets/environment/main/spikesBottom.png
new file mode 100644
index 0000000..4c72acc
Binary files /dev/null and b/src/exit_dash/assets/environment/main/spikesBottom.png differ
diff --git a/src/exit_dash/assets/environment/main/spikesBottomAlt.png b/src/exit_dash/assets/environment/main/spikesBottomAlt.png
new file mode 100644
index 0000000..f5090dc
Binary files /dev/null and b/src/exit_dash/assets/environment/main/spikesBottomAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/spikesBottomAlt2.png b/src/exit_dash/assets/environment/main/spikesBottomAlt2.png
new file mode 100644
index 0000000..31e3b45
Binary files /dev/null and b/src/exit_dash/assets/environment/main/spikesBottomAlt2.png differ
diff --git a/src/exit_dash/assets/environment/main/spikesTop.png b/src/exit_dash/assets/environment/main/spikesTop.png
new file mode 100644
index 0000000..f0afcf1
Binary files /dev/null and b/src/exit_dash/assets/environment/main/spikesTop.png differ
diff --git a/src/exit_dash/assets/environment/main/spikesTopAlt.png b/src/exit_dash/assets/environment/main/spikesTopAlt.png
new file mode 100644
index 0000000..35e48f6
Binary files /dev/null and b/src/exit_dash/assets/environment/main/spikesTopAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/spikesTopAlt2.png b/src/exit_dash/assets/environment/main/spikesTopAlt2.png
new file mode 100644
index 0000000..d4d16a3
Binary files /dev/null and b/src/exit_dash/assets/environment/main/spikesTopAlt2.png differ
diff --git a/src/exit_dash/assets/environment/main/stone.png b/src/exit_dash/assets/environment/main/stone.png
new file mode 100644
index 0000000..1c6722c
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stone.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneCenter.png b/src/exit_dash/assets/environment/main/stoneCenter.png
new file mode 100644
index 0000000..b4496e2
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneCenter.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneCenter_rounded.png b/src/exit_dash/assets/environment/main/stoneCenter_rounded.png
new file mode 100644
index 0000000..0a4a2ec
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneCenter_rounded.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneCliffLeft.png b/src/exit_dash/assets/environment/main/stoneCliffLeft.png
new file mode 100644
index 0000000..ed8a459
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneCliffLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneCliffLeftAlt.png b/src/exit_dash/assets/environment/main/stoneCliffLeftAlt.png
new file mode 100644
index 0000000..23ae174
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneCliffLeftAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneCliffRight.png b/src/exit_dash/assets/environment/main/stoneCliffRight.png
new file mode 100644
index 0000000..13dfe6f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneCliffRight.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneCliffRightAlt.png b/src/exit_dash/assets/environment/main/stoneCliffRightAlt.png
new file mode 100644
index 0000000..7ca811a
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneCliffRightAlt.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneHalf.png b/src/exit_dash/assets/environment/main/stoneHalf.png
new file mode 100644
index 0000000..95e5525
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneHalf.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneHalfLeft.png b/src/exit_dash/assets/environment/main/stoneHalfLeft.png
new file mode 100644
index 0000000..66d6442
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneHalfLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneHalfMid.png b/src/exit_dash/assets/environment/main/stoneHalfMid.png
new file mode 100644
index 0000000..47dbbf1
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneHalfMid.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneHalfRight.png b/src/exit_dash/assets/environment/main/stoneHalfRight.png
new file mode 100644
index 0000000..f4a819d
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneHalfRight.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneHillLeft2.png b/src/exit_dash/assets/environment/main/stoneHillLeft2.png
new file mode 100644
index 0000000..a5e2b61
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneHillLeft2.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneHillRight2.png b/src/exit_dash/assets/environment/main/stoneHillRight2.png
new file mode 100644
index 0000000..ee38310
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneHillRight2.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneLedgeLeft.png b/src/exit_dash/assets/environment/main/stoneLedgeLeft.png
new file mode 100644
index 0000000..279121d
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneLedgeLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneLedgeRight.png b/src/exit_dash/assets/environment/main/stoneLedgeRight.png
new file mode 100644
index 0000000..f09f442
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneLedgeRight.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneLeft.png b/src/exit_dash/assets/environment/main/stoneLeft.png
new file mode 100644
index 0000000..582952f
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneLeft.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneMid.png b/src/exit_dash/assets/environment/main/stoneMid.png
new file mode 100644
index 0000000..0b87306
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneMid.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneRight.png b/src/exit_dash/assets/environment/main/stoneRight.png
new file mode 100644
index 0000000..aa7ca90
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneRight.png differ
diff --git a/src/exit_dash/assets/environment/main/stoneWall.png b/src/exit_dash/assets/environment/main/stoneWall.png
new file mode 100644
index 0000000..373fd51
Binary files /dev/null and b/src/exit_dash/assets/environment/main/stoneWall.png differ
diff --git a/src/exit_dash/assets/environment/main/tiles_spritesheet.png b/src/exit_dash/assets/environment/main/tiles_spritesheet.png
new file mode 100644
index 0000000..dfd35d1
Binary files /dev/null and b/src/exit_dash/assets/environment/main/tiles_spritesheet.png differ
diff --git a/environment/main/tiles_spritesheet.xml b/src/exit_dash/assets/environment/main/tiles_spritesheet.xml
similarity index 99%
rename from environment/main/tiles_spritesheet.xml
rename to src/exit_dash/assets/environment/main/tiles_spritesheet.xml
index 8c9584f..6613ffb 100644
--- a/environment/main/tiles_spritesheet.xml
+++ b/src/exit_dash/assets/environment/main/tiles_spritesheet.xml
@@ -171,4 +171,4 @@
-
\ No newline at end of file
+
diff --git a/src/exit_dash/assets/environment/main/tochLit.png b/src/exit_dash/assets/environment/main/tochLit.png
new file mode 100644
index 0000000..67fa8d7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/tochLit.png differ
diff --git a/src/exit_dash/assets/environment/main/tochLit2.png b/src/exit_dash/assets/environment/main/tochLit2.png
new file mode 100644
index 0000000..600c69b
Binary files /dev/null and b/src/exit_dash/assets/environment/main/tochLit2.png differ
diff --git a/src/exit_dash/assets/environment/main/torch.png b/src/exit_dash/assets/environment/main/torch.png
new file mode 100644
index 0000000..6a3c7d7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/torch.png differ
diff --git a/src/exit_dash/assets/environment/main/torchLit.png b/src/exit_dash/assets/environment/main/torchLit.png
new file mode 100644
index 0000000..67fa8d7
Binary files /dev/null and b/src/exit_dash/assets/environment/main/torchLit.png differ
diff --git a/src/exit_dash/assets/environment/main/torchLit2.png b/src/exit_dash/assets/environment/main/torchLit2.png
new file mode 100644
index 0000000..600c69b
Binary files /dev/null and b/src/exit_dash/assets/environment/main/torchLit2.png differ
diff --git a/src/exit_dash/assets/environment/main/window.png b/src/exit_dash/assets/environment/main/window.png
new file mode 100644
index 0000000..8f00b79
Binary files /dev/null and b/src/exit_dash/assets/environment/main/window.png differ
diff --git a/fonts/2lines.ttf b/src/exit_dash/assets/fonts/2lines.ttf
similarity index 100%
rename from fonts/2lines.ttf
rename to src/exit_dash/assets/fonts/2lines.ttf
diff --git a/fonts/atari.ttf b/src/exit_dash/assets/fonts/atari.ttf
similarity index 100%
rename from fonts/atari.ttf
rename to src/exit_dash/assets/fonts/atari.ttf
diff --git a/fonts/gamecuben.ttf b/src/exit_dash/assets/fonts/gamecuben.ttf
similarity index 100%
rename from fonts/gamecuben.ttf
rename to src/exit_dash/assets/fonts/gamecuben.ttf
diff --git a/fonts/jetset.ttf b/src/exit_dash/assets/fonts/jetset.ttf
similarity index 100%
rename from fonts/jetset.ttf
rename to src/exit_dash/assets/fonts/jetset.ttf
diff --git a/fonts/kenvector_future.ttf b/src/exit_dash/assets/fonts/kenvector_future.ttf
similarity index 100%
rename from fonts/kenvector_future.ttf
rename to src/exit_dash/assets/fonts/kenvector_future.ttf
diff --git a/fonts/kenvector_future_thin.ttf b/src/exit_dash/assets/fonts/kenvector_future_thin.ttf
similarity index 100%
rename from fonts/kenvector_future_thin.ttf
rename to src/exit_dash/assets/fonts/kenvector_future_thin.ttf
diff --git a/fonts/source.otf b/src/exit_dash/assets/fonts/source.otf
similarity index 100%
rename from fonts/source.otf
rename to src/exit_dash/assets/fonts/source.otf
diff --git a/src/exit_dash/assets/hud/hud_0.png b/src/exit_dash/assets/hud/hud_0.png
new file mode 100644
index 0000000..e5c0318
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_0.png differ
diff --git a/src/exit_dash/assets/hud/hud_1.png b/src/exit_dash/assets/hud/hud_1.png
new file mode 100644
index 0000000..ae91b5a
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_1.png differ
diff --git a/src/exit_dash/assets/hud/hud_2.png b/src/exit_dash/assets/hud/hud_2.png
new file mode 100644
index 0000000..2c2b400
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_2.png differ
diff --git a/src/exit_dash/assets/hud/hud_3.png b/src/exit_dash/assets/hud/hud_3.png
new file mode 100644
index 0000000..24f499a
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_3.png differ
diff --git a/src/exit_dash/assets/hud/hud_4.png b/src/exit_dash/assets/hud/hud_4.png
new file mode 100644
index 0000000..9dda3d2
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_4.png differ
diff --git a/src/exit_dash/assets/hud/hud_5.png b/src/exit_dash/assets/hud/hud_5.png
new file mode 100644
index 0000000..57fa64d
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_5.png differ
diff --git a/src/exit_dash/assets/hud/hud_6.png b/src/exit_dash/assets/hud/hud_6.png
new file mode 100644
index 0000000..01282e2
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_6.png differ
diff --git a/src/exit_dash/assets/hud/hud_7.png b/src/exit_dash/assets/hud/hud_7.png
new file mode 100644
index 0000000..6ae20d7
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_7.png differ
diff --git a/src/exit_dash/assets/hud/hud_8.png b/src/exit_dash/assets/hud/hud_8.png
new file mode 100644
index 0000000..f0eb692
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_8.png differ
diff --git a/src/exit_dash/assets/hud/hud_9.png b/src/exit_dash/assets/hud/hud_9.png
new file mode 100644
index 0000000..e33535d
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_9.png differ
diff --git a/src/exit_dash/assets/hud/hud_coins.png b/src/exit_dash/assets/hud/hud_coins.png
new file mode 100644
index 0000000..77177d8
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_coins.png differ
diff --git a/src/exit_dash/assets/hud/hud_gem_blue.png b/src/exit_dash/assets/hud/hud_gem_blue.png
new file mode 100644
index 0000000..140174b
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_gem_blue.png differ
diff --git a/src/exit_dash/assets/hud/hud_gem_green.png b/src/exit_dash/assets/hud/hud_gem_green.png
new file mode 100644
index 0000000..5becb98
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_gem_green.png differ
diff --git a/src/exit_dash/assets/hud/hud_gem_red.png b/src/exit_dash/assets/hud/hud_gem_red.png
new file mode 100644
index 0000000..fb50178
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_gem_red.png differ
diff --git a/src/exit_dash/assets/hud/hud_gem_yellow.png b/src/exit_dash/assets/hud/hud_gem_yellow.png
new file mode 100644
index 0000000..c1f3920
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_gem_yellow.png differ
diff --git a/src/exit_dash/assets/hud/hud_heartEmpty.png b/src/exit_dash/assets/hud/hud_heartEmpty.png
new file mode 100644
index 0000000..ccc5415
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_heartEmpty.png differ
diff --git a/src/exit_dash/assets/hud/hud_heartFull.png b/src/exit_dash/assets/hud/hud_heartFull.png
new file mode 100644
index 0000000..f37e551
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_heartFull.png differ
diff --git a/src/exit_dash/assets/hud/hud_heartHalf.png b/src/exit_dash/assets/hud/hud_heartHalf.png
new file mode 100644
index 0000000..ca61b79
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_heartHalf.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyBlue.png b/src/exit_dash/assets/hud/hud_keyBlue.png
new file mode 100644
index 0000000..29c7538
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyBlue.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyBlue_disabled.png b/src/exit_dash/assets/hud/hud_keyBlue_disabled.png
new file mode 100644
index 0000000..99d8772
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyBlue_disabled.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyGreem_disabled.png b/src/exit_dash/assets/hud/hud_keyGreem_disabled.png
new file mode 100644
index 0000000..4ddc362
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyGreem_disabled.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyGreen.png b/src/exit_dash/assets/hud/hud_keyGreen.png
new file mode 100644
index 0000000..ba530ac
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyGreen.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyRed.png b/src/exit_dash/assets/hud/hud_keyRed.png
new file mode 100644
index 0000000..b5e10e6
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyRed.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyRed_disabled.png b/src/exit_dash/assets/hud/hud_keyRed_disabled.png
new file mode 100644
index 0000000..c9e6e25
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyRed_disabled.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyYellow.png b/src/exit_dash/assets/hud/hud_keyYellow.png
new file mode 100644
index 0000000..cf8f5a4
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyYellow.png differ
diff --git a/src/exit_dash/assets/hud/hud_keyYellow_disabled.png b/src/exit_dash/assets/hud/hud_keyYellow_disabled.png
new file mode 100644
index 0000000..71d3964
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_keyYellow_disabled.png differ
diff --git a/src/exit_dash/assets/hud/hud_p1.png b/src/exit_dash/assets/hud/hud_p1.png
new file mode 100644
index 0000000..0073d41
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_p1.png differ
diff --git a/src/exit_dash/assets/hud/hud_p1Alt.png b/src/exit_dash/assets/hud/hud_p1Alt.png
new file mode 100644
index 0000000..3cf0642
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_p1Alt.png differ
diff --git a/src/exit_dash/assets/hud/hud_p2.png b/src/exit_dash/assets/hud/hud_p2.png
new file mode 100644
index 0000000..85557ee
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_p2.png differ
diff --git a/src/exit_dash/assets/hud/hud_p2Alt.png b/src/exit_dash/assets/hud/hud_p2Alt.png
new file mode 100644
index 0000000..6ce50a6
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_p2Alt.png differ
diff --git a/src/exit_dash/assets/hud/hud_p3.png b/src/exit_dash/assets/hud/hud_p3.png
new file mode 100644
index 0000000..01ea363
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_p3.png differ
diff --git a/src/exit_dash/assets/hud/hud_p3Alt.png b/src/exit_dash/assets/hud/hud_p3Alt.png
new file mode 100644
index 0000000..9fd5024
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_p3Alt.png differ
diff --git a/src/exit_dash/assets/hud/hud_spritesheet.png b/src/exit_dash/assets/hud/hud_spritesheet.png
new file mode 100644
index 0000000..a9d25ae
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_spritesheet.png differ
diff --git a/hud/hud_spritesheet.xml b/src/exit_dash/assets/hud/hud_spritesheet.xml
similarity index 99%
rename from hud/hud_spritesheet.xml
rename to src/exit_dash/assets/hud/hud_spritesheet.xml
index fc83392..eaba1ec 100644
--- a/hud/hud_spritesheet.xml
+++ b/src/exit_dash/assets/hud/hud_spritesheet.xml
@@ -32,4 +32,4 @@
-
\ No newline at end of file
+
diff --git a/src/exit_dash/assets/hud/hud_x.png b/src/exit_dash/assets/hud/hud_x.png
new file mode 100644
index 0000000..c0cb2fc
Binary files /dev/null and b/src/exit_dash/assets/hud/hud_x.png differ
diff --git a/src/exit_dash/assets/hud/pointer.png b/src/exit_dash/assets/hud/pointer.png
new file mode 100644
index 0000000..9e045c9
Binary files /dev/null and b/src/exit_dash/assets/hud/pointer.png differ
diff --git a/src/exit_dash/assets/hud/pointerClicked.png b/src/exit_dash/assets/hud/pointerClicked.png
new file mode 100644
index 0000000..fd0d505
Binary files /dev/null and b/src/exit_dash/assets/hud/pointerClicked.png differ
diff --git a/src/exit_dash/assets/items/bomb.png b/src/exit_dash/assets/items/bomb.png
new file mode 100644
index 0000000..f790d4d
Binary files /dev/null and b/src/exit_dash/assets/items/bomb.png differ
diff --git a/src/exit_dash/assets/items/bombFlash.png b/src/exit_dash/assets/items/bombFlash.png
new file mode 100644
index 0000000..ec58db2
Binary files /dev/null and b/src/exit_dash/assets/items/bombFlash.png differ
diff --git a/src/exit_dash/assets/items/bush.png b/src/exit_dash/assets/items/bush.png
new file mode 100644
index 0000000..0527723
Binary files /dev/null and b/src/exit_dash/assets/items/bush.png differ
diff --git a/src/exit_dash/assets/items/buttonBlue.png b/src/exit_dash/assets/items/buttonBlue.png
new file mode 100644
index 0000000..93ce12c
Binary files /dev/null and b/src/exit_dash/assets/items/buttonBlue.png differ
diff --git a/src/exit_dash/assets/items/buttonBlue_pressed.png b/src/exit_dash/assets/items/buttonBlue_pressed.png
new file mode 100644
index 0000000..8da7b6d
Binary files /dev/null and b/src/exit_dash/assets/items/buttonBlue_pressed.png differ
diff --git a/src/exit_dash/assets/items/buttonGreen.png b/src/exit_dash/assets/items/buttonGreen.png
new file mode 100644
index 0000000..fb680fe
Binary files /dev/null and b/src/exit_dash/assets/items/buttonGreen.png differ
diff --git a/src/exit_dash/assets/items/buttonGreen_pressed.png b/src/exit_dash/assets/items/buttonGreen_pressed.png
new file mode 100644
index 0000000..993ed3e
Binary files /dev/null and b/src/exit_dash/assets/items/buttonGreen_pressed.png differ
diff --git a/src/exit_dash/assets/items/buttonRed.png b/src/exit_dash/assets/items/buttonRed.png
new file mode 100644
index 0000000..6fd2dac
Binary files /dev/null and b/src/exit_dash/assets/items/buttonRed.png differ
diff --git a/src/exit_dash/assets/items/buttonRed_pressed.png b/src/exit_dash/assets/items/buttonRed_pressed.png
new file mode 100644
index 0000000..fa10375
Binary files /dev/null and b/src/exit_dash/assets/items/buttonRed_pressed.png differ
diff --git a/src/exit_dash/assets/items/buttonYellow.png b/src/exit_dash/assets/items/buttonYellow.png
new file mode 100644
index 0000000..c4220e4
Binary files /dev/null and b/src/exit_dash/assets/items/buttonYellow.png differ
diff --git a/src/exit_dash/assets/items/buttonYellow_pressed.png b/src/exit_dash/assets/items/buttonYellow_pressed.png
new file mode 100644
index 0000000..c1f14b0
Binary files /dev/null and b/src/exit_dash/assets/items/buttonYellow_pressed.png differ
diff --git a/src/exit_dash/assets/items/cactus.png b/src/exit_dash/assets/items/cactus.png
new file mode 100644
index 0000000..08bba86
Binary files /dev/null and b/src/exit_dash/assets/items/cactus.png differ
diff --git a/src/exit_dash/assets/items/chain.png b/src/exit_dash/assets/items/chain.png
new file mode 100644
index 0000000..a0743b7
Binary files /dev/null and b/src/exit_dash/assets/items/chain.png differ
diff --git a/items/cloud1.png b/src/exit_dash/assets/items/cloud1.png
similarity index 85%
rename from items/cloud1.png
rename to src/exit_dash/assets/items/cloud1.png
index a270f2b..be9772b 100644
Binary files a/items/cloud1.png and b/src/exit_dash/assets/items/cloud1.png differ
diff --git a/items/cloud2.png b/src/exit_dash/assets/items/cloud2.png
similarity index 78%
rename from items/cloud2.png
rename to src/exit_dash/assets/items/cloud2.png
index c930543..430c80a 100644
Binary files a/items/cloud2.png and b/src/exit_dash/assets/items/cloud2.png differ
diff --git a/items/cloud3.png b/src/exit_dash/assets/items/cloud3.png
similarity index 84%
rename from items/cloud3.png
rename to src/exit_dash/assets/items/cloud3.png
index c3c4b10..c5426b8 100644
Binary files a/items/cloud3.png and b/src/exit_dash/assets/items/cloud3.png differ
diff --git a/src/exit_dash/assets/items/coinBronze.png b/src/exit_dash/assets/items/coinBronze.png
new file mode 100644
index 0000000..5da245c
Binary files /dev/null and b/src/exit_dash/assets/items/coinBronze.png differ
diff --git a/src/exit_dash/assets/items/coinGold.png b/src/exit_dash/assets/items/coinGold.png
new file mode 100644
index 0000000..e1a95bd
Binary files /dev/null and b/src/exit_dash/assets/items/coinGold.png differ
diff --git a/src/exit_dash/assets/items/coinSilver.png b/src/exit_dash/assets/items/coinSilver.png
new file mode 100644
index 0000000..40771af
Binary files /dev/null and b/src/exit_dash/assets/items/coinSilver.png differ
diff --git a/src/exit_dash/assets/items/fireball.png b/src/exit_dash/assets/items/fireball.png
new file mode 100644
index 0000000..f35ec4b
Binary files /dev/null and b/src/exit_dash/assets/items/fireball.png differ
diff --git a/src/exit_dash/assets/items/flagBlue.png b/src/exit_dash/assets/items/flagBlue.png
new file mode 100644
index 0000000..96fb7a8
Binary files /dev/null and b/src/exit_dash/assets/items/flagBlue.png differ
diff --git a/src/exit_dash/assets/items/flagBlue2.png b/src/exit_dash/assets/items/flagBlue2.png
new file mode 100644
index 0000000..1735221
Binary files /dev/null and b/src/exit_dash/assets/items/flagBlue2.png differ
diff --git a/src/exit_dash/assets/items/flagBlueHanging.png b/src/exit_dash/assets/items/flagBlueHanging.png
new file mode 100644
index 0000000..b87e0ec
Binary files /dev/null and b/src/exit_dash/assets/items/flagBlueHanging.png differ
diff --git a/src/exit_dash/assets/items/flagGreen.png b/src/exit_dash/assets/items/flagGreen.png
new file mode 100644
index 0000000..702ae67
Binary files /dev/null and b/src/exit_dash/assets/items/flagGreen.png differ
diff --git a/src/exit_dash/assets/items/flagGreen2.png b/src/exit_dash/assets/items/flagGreen2.png
new file mode 100644
index 0000000..0664c5a
Binary files /dev/null and b/src/exit_dash/assets/items/flagGreen2.png differ
diff --git a/src/exit_dash/assets/items/flagGreenHanging.png b/src/exit_dash/assets/items/flagGreenHanging.png
new file mode 100644
index 0000000..4fddeda
Binary files /dev/null and b/src/exit_dash/assets/items/flagGreenHanging.png differ
diff --git a/src/exit_dash/assets/items/flagRed.png b/src/exit_dash/assets/items/flagRed.png
new file mode 100644
index 0000000..799954c
Binary files /dev/null and b/src/exit_dash/assets/items/flagRed.png differ
diff --git a/src/exit_dash/assets/items/flagRed2.png b/src/exit_dash/assets/items/flagRed2.png
new file mode 100644
index 0000000..c8ab666
Binary files /dev/null and b/src/exit_dash/assets/items/flagRed2.png differ
diff --git a/src/exit_dash/assets/items/flagRedHanging.png b/src/exit_dash/assets/items/flagRedHanging.png
new file mode 100644
index 0000000..d13310d
Binary files /dev/null and b/src/exit_dash/assets/items/flagRedHanging.png differ
diff --git a/src/exit_dash/assets/items/flagYellow.png b/src/exit_dash/assets/items/flagYellow.png
new file mode 100644
index 0000000..b5cc429
Binary files /dev/null and b/src/exit_dash/assets/items/flagYellow.png differ
diff --git a/src/exit_dash/assets/items/flagYellow2.png b/src/exit_dash/assets/items/flagYellow2.png
new file mode 100644
index 0000000..2be9b7c
Binary files /dev/null and b/src/exit_dash/assets/items/flagYellow2.png differ
diff --git a/src/exit_dash/assets/items/flagYellowHanging.png b/src/exit_dash/assets/items/flagYellowHanging.png
new file mode 100644
index 0000000..ecffb15
Binary files /dev/null and b/src/exit_dash/assets/items/flagYellowHanging.png differ
diff --git a/src/exit_dash/assets/items/gemBlue.png b/src/exit_dash/assets/items/gemBlue.png
new file mode 100644
index 0000000..b95c6c0
Binary files /dev/null and b/src/exit_dash/assets/items/gemBlue.png differ
diff --git a/src/exit_dash/assets/items/gemGreen.png b/src/exit_dash/assets/items/gemGreen.png
new file mode 100644
index 0000000..538d852
Binary files /dev/null and b/src/exit_dash/assets/items/gemGreen.png differ
diff --git a/src/exit_dash/assets/items/gemRed.png b/src/exit_dash/assets/items/gemRed.png
new file mode 100644
index 0000000..2b8092d
Binary files /dev/null and b/src/exit_dash/assets/items/gemRed.png differ
diff --git a/src/exit_dash/assets/items/gemYellow.png b/src/exit_dash/assets/items/gemYellow.png
new file mode 100644
index 0000000..cea2d48
Binary files /dev/null and b/src/exit_dash/assets/items/gemYellow.png differ
diff --git a/src/exit_dash/assets/items/items_spritesheet.png b/src/exit_dash/assets/items/items_spritesheet.png
new file mode 100644
index 0000000..8d2a1d4
Binary files /dev/null and b/src/exit_dash/assets/items/items_spritesheet.png differ
diff --git a/items/items_spritesheet.xml b/src/exit_dash/assets/items/items_spritesheet.xml
similarity index 99%
rename from items/items_spritesheet.xml
rename to src/exit_dash/assets/items/items_spritesheet.xml
index dd06085..927898c 100644
--- a/items/items_spritesheet.xml
+++ b/src/exit_dash/assets/items/items_spritesheet.xml
@@ -58,4 +58,4 @@
-
\ No newline at end of file
+
diff --git a/src/exit_dash/assets/items/keyBlue.png b/src/exit_dash/assets/items/keyBlue.png
new file mode 100644
index 0000000..b446fbc
Binary files /dev/null and b/src/exit_dash/assets/items/keyBlue.png differ
diff --git a/src/exit_dash/assets/items/keyGreen.png b/src/exit_dash/assets/items/keyGreen.png
new file mode 100644
index 0000000..717c134
Binary files /dev/null and b/src/exit_dash/assets/items/keyGreen.png differ
diff --git a/src/exit_dash/assets/items/keyRed.png b/src/exit_dash/assets/items/keyRed.png
new file mode 100644
index 0000000..92aa3c0
Binary files /dev/null and b/src/exit_dash/assets/items/keyRed.png differ
diff --git a/src/exit_dash/assets/items/keyYellow.png b/src/exit_dash/assets/items/keyYellow.png
new file mode 100644
index 0000000..90733f0
Binary files /dev/null and b/src/exit_dash/assets/items/keyYellow.png differ
diff --git a/src/exit_dash/assets/items/mushroomBrown.png b/src/exit_dash/assets/items/mushroomBrown.png
new file mode 100644
index 0000000..4fba1d8
Binary files /dev/null and b/src/exit_dash/assets/items/mushroomBrown.png differ
diff --git a/src/exit_dash/assets/items/mushroomRed.png b/src/exit_dash/assets/items/mushroomRed.png
new file mode 100644
index 0000000..be69b2d
Binary files /dev/null and b/src/exit_dash/assets/items/mushroomRed.png differ
diff --git a/src/exit_dash/assets/items/particleBrick1a.png b/src/exit_dash/assets/items/particleBrick1a.png
new file mode 100644
index 0000000..fd685d7
Binary files /dev/null and b/src/exit_dash/assets/items/particleBrick1a.png differ
diff --git a/src/exit_dash/assets/items/particleBrick1b.png b/src/exit_dash/assets/items/particleBrick1b.png
new file mode 100644
index 0000000..6a82939
Binary files /dev/null and b/src/exit_dash/assets/items/particleBrick1b.png differ
diff --git a/src/exit_dash/assets/items/particleBrick2a.png b/src/exit_dash/assets/items/particleBrick2a.png
new file mode 100644
index 0000000..4148907
Binary files /dev/null and b/src/exit_dash/assets/items/particleBrick2a.png differ
diff --git a/src/exit_dash/assets/items/particleBrick2b.png b/src/exit_dash/assets/items/particleBrick2b.png
new file mode 100644
index 0000000..52087b4
Binary files /dev/null and b/src/exit_dash/assets/items/particleBrick2b.png differ
diff --git a/src/exit_dash/assets/items/plant.png b/src/exit_dash/assets/items/plant.png
new file mode 100644
index 0000000..38f6dd2
Binary files /dev/null and b/src/exit_dash/assets/items/plant.png differ
diff --git a/src/exit_dash/assets/items/plantPurple.png b/src/exit_dash/assets/items/plantPurple.png
new file mode 100644
index 0000000..698b375
Binary files /dev/null and b/src/exit_dash/assets/items/plantPurple.png differ
diff --git a/src/exit_dash/assets/items/rock.png b/src/exit_dash/assets/items/rock.png
new file mode 100644
index 0000000..975b301
Binary files /dev/null and b/src/exit_dash/assets/items/rock.png differ
diff --git a/src/exit_dash/assets/items/snowhill.png b/src/exit_dash/assets/items/snowhill.png
new file mode 100644
index 0000000..e8959b4
Binary files /dev/null and b/src/exit_dash/assets/items/snowhill.png differ
diff --git a/src/exit_dash/assets/items/spikes.png b/src/exit_dash/assets/items/spikes.png
new file mode 100644
index 0000000..a354c38
Binary files /dev/null and b/src/exit_dash/assets/items/spikes.png differ
diff --git a/src/exit_dash/assets/items/springboardDown.png b/src/exit_dash/assets/items/springboardDown.png
new file mode 100644
index 0000000..23c2c7f
Binary files /dev/null and b/src/exit_dash/assets/items/springboardDown.png differ
diff --git a/src/exit_dash/assets/items/springboardUp.png b/src/exit_dash/assets/items/springboardUp.png
new file mode 100644
index 0000000..580320b
Binary files /dev/null and b/src/exit_dash/assets/items/springboardUp.png differ
diff --git a/src/exit_dash/assets/items/star.png b/src/exit_dash/assets/items/star.png
new file mode 100644
index 0000000..bb1b9a6
Binary files /dev/null and b/src/exit_dash/assets/items/star.png differ
diff --git a/src/exit_dash/assets/items/switchLeft.png b/src/exit_dash/assets/items/switchLeft.png
new file mode 100644
index 0000000..d0a84db
Binary files /dev/null and b/src/exit_dash/assets/items/switchLeft.png differ
diff --git a/src/exit_dash/assets/items/switchMid.png b/src/exit_dash/assets/items/switchMid.png
new file mode 100644
index 0000000..ee4eca6
Binary files /dev/null and b/src/exit_dash/assets/items/switchMid.png differ
diff --git a/src/exit_dash/assets/items/switchRight.png b/src/exit_dash/assets/items/switchRight.png
new file mode 100644
index 0000000..d8ac1fc
Binary files /dev/null and b/src/exit_dash/assets/items/switchRight.png differ
diff --git a/src/exit_dash/assets/items/weight.png b/src/exit_dash/assets/items/weight.png
new file mode 100644
index 0000000..232675b
Binary files /dev/null and b/src/exit_dash/assets/items/weight.png differ
diff --git a/src/exit_dash/assets/items/weightChained.png b/src/exit_dash/assets/items/weightChained.png
new file mode 100644
index 0000000..00e409f
Binary files /dev/null and b/src/exit_dash/assets/items/weightChained.png differ
diff --git a/levels/lvl_1.dat b/src/exit_dash/assets/levels/lvl_1.dat
similarity index 99%
rename from levels/lvl_1.dat
rename to src/exit_dash/assets/levels/lvl_1.dat
index a4b87ac..6fbb5dd 100644
--- a/levels/lvl_1.dat
+++ b/src/exit_dash/assets/levels/lvl_1.dat
@@ -160,4 +160,4 @@ Position Data For Level 1 - DO NOT MODIFY THIS FILE!
2288
1
1
-8627
\ No newline at end of file
+8627
diff --git a/levels/lvl_2.dat b/src/exit_dash/assets/levels/lvl_2.dat
similarity index 83%
rename from levels/lvl_2.dat
rename to src/exit_dash/assets/levels/lvl_2.dat
index a8a7f70..7bc596a 100644
--- a/levels/lvl_2.dat
+++ b/src/exit_dash/assets/levels/lvl_2.dat
@@ -1,163 +1,163 @@
-Position Data For Level 2 - DO NOT MODIFY THIS FILE!
-1266
-627
-1470
-2916
-463
-1050
-4094
-611
-560
-4814
-432
-1260
-6232
-235
-1680
-8022
-73
-1330
-9464
-180
-910
-10570
-16
-1190
-11923
--174
-910
-13037
--336
-700
-13900
--172
-980
-15016
--339
-1260
-16457
--544
-1400
-17966
--713
-840
-18980
--912
-490
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
-18261.0
--902.0
-0
-4467.0
-422.0
-1
-9947.0
--9.0
-0
-3440.0
-274.0
-1
-17475.0
--733.0
-0
-13315.0
--525.0
-0
-12617.0
--363.0
-0
-11360.0
--173.0
-0
-5287.0
-243.0
-0
-16001.0
--528.0
-0
-1465
-438.0
-0
-8399.0
--116.0
-0
-14110.0
--361.0
-0
-19312.0
--1101.0
-1
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
-19370
--912
-1
-1
-65418
\ No newline at end of file
+Position Data For Level 2 - DO NOT MODIFY THIS FILE!
+1266
+627
+1470
+2916
+463
+1050
+4094
+611
+560
+4814
+432
+1260
+6232
+235
+1680
+8022
+73
+1330
+9464
+180
+910
+10570
+16
+1190
+11923
+-174
+910
+13037
+-336
+700
+13900
+-172
+980
+15016
+-339
+1260
+16457
+-544
+1400
+17966
+-713
+840
+18980
+-912
+490
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+18261.0
+-902.0
+0
+4467.0
+422.0
+1
+9947.0
+-9.0
+0
+3440.0
+274.0
+1
+17475.0
+-733.0
+0
+13315.0
+-525.0
+0
+12617.0
+-363.0
+0
+11360.0
+-173.0
+0
+5287.0
+243.0
+0
+16001.0
+-528.0
+0
+1465
+438.0
+0
+8399.0
+-116.0
+0
+14110.0
+-361.0
+0
+19312.0
+-1101.0
+1
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+19370
+-912
+1
+1
+65418
diff --git a/levels/lvl_3.dat b/src/exit_dash/assets/levels/lvl_3.dat
similarity index 83%
rename from levels/lvl_3.dat
rename to src/exit_dash/assets/levels/lvl_3.dat
index 6f0ad4f..1d3db86 100644
--- a/levels/lvl_3.dat
+++ b/src/exit_dash/assets/levels/lvl_3.dat
@@ -1,163 +1,163 @@
-Position Data For Level 3 - DO NOT MODIFY THIS FILE!
-1820
-987
-980
-2915
-806
-700
-3786
-614
-420
-4417
-996
-1610
-6221
-792
-1750
-8161
-1101
-1190
-9503
-1337
-1820
-11516
-1521
-1960
-13629
-1352
-840
-14668
-1680
-1750
-16526
-1481
-1540
-18173
-1608
-770
-19128
-1450
-910
-20219
-1272
-1330
-21704
-1086
-490
-22408
-885
-1050
-23549
-1180
-910
-24666
-987
-1680
-26508
-1162
-1540
-28246
-1497
-770
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
-23743.0
-991.0
-0
-2993.0
-617.0
-0
-8292.0
-912.0
-0
-28875.0
-1308.0
-0
-19389.0
-1261.0
-0
-7329.0
-603.0
-0
-13771.0
-1163.0
-1
-16983.0
-1292.0
-1
-25237.0
-798.0
-1
-21898.0
-897.0
-0
-27727.0
-973.0
-0
-23164.0
-696.0
-0
-21200.0
-1083.0
-0
-5558.0
-807.0
-1
-15385.0
-1491.0
-0
-10520.0
-1148.0
-0
-4127.0
-425.0
-1
-18307.0
-1419.0
-0
-2184
-798.0
-0
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
--999
-28916
-1497
-0
-1
-152852
\ No newline at end of file
+Position Data For Level 3 - DO NOT MODIFY THIS FILE!
+1820
+987
+980
+2915
+806
+700
+3786
+614
+420
+4417
+996
+1610
+6221
+792
+1750
+8161
+1101
+1190
+9503
+1337
+1820
+11516
+1521
+1960
+13629
+1352
+840
+14668
+1680
+1750
+16526
+1481
+1540
+18173
+1608
+770
+19128
+1450
+910
+20219
+1272
+1330
+21704
+1086
+490
+22408
+885
+1050
+23549
+1180
+910
+24666
+987
+1680
+26508
+1162
+1540
+28246
+1497
+770
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+23743.0
+991.0
+0
+2993.0
+617.0
+0
+8292.0
+912.0
+0
+28875.0
+1308.0
+0
+19389.0
+1261.0
+0
+7329.0
+603.0
+0
+13771.0
+1163.0
+1
+16983.0
+1292.0
+1
+25237.0
+798.0
+1
+21898.0
+897.0
+0
+27727.0
+973.0
+0
+23164.0
+696.0
+0
+21200.0
+1083.0
+0
+5558.0
+807.0
+1
+15385.0
+1491.0
+0
+10520.0
+1148.0
+0
+4127.0
+425.0
+1
+18307.0
+1419.0
+0
+2184
+798.0
+0
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+-999
+28916
+1497
+0
+1
+152852
diff --git a/levels/lvl_4.dat b/src/exit_dash/assets/levels/lvl_4.dat
similarity index 84%
rename from levels/lvl_4.dat
rename to src/exit_dash/assets/levels/lvl_4.dat
index e441bd8..7fd4e22 100644
--- a/levels/lvl_4.dat
+++ b/src/exit_dash/assets/levels/lvl_4.dat
@@ -1,163 +1,163 @@
-Position Data For Level 4 - DO NOT MODIFY THIS FILE!
-1820
-1025
-980
-2974
-1371
-1750
-4899
-1198
-1890
-6909
-1002
-1330
-8399
-1319
-1330
-9841
-1145
-560
-10509
-983
-1260
-11896
-823
-840
-12919
-650
-1120
-14174
-1018
-1050
-15387
-1194
-1890
-17396
-994
-630
-18199
-1294
-840
-19186
-1118
-1680
-21001
-1364
-840
-22018
-1710
-1190
-23384
-1555
-1050
-24627
-1374
-840
-25595
-1195
-1680
-27437
-1592
-910
-28551
-1901
-770
-29456
-2072
-840
-30469
-1874
-840
-31483
-1687
-840
-32455
-1878
-1540
--999
--999
--999
--999
-10135.0
-956.0
-0
-19756.0
-929.0
-0
-4529.0
-1182.0
-0
-33303.0
-1689.0
-0
-26371.0
-1006.0
-1
-29853.0
-1883.0
-0
-9058.0
-1130.0
-0
-10845.0
-794.0
-0
-28699.0
-1712.0
-1
-18496.0
-1105.0
-0
-28184.0
-1403.0
-0
-25153.0
-1185.0
-1
-32211.0
-1498.0
-0
-17508.0
-805.0
-1
-13183.0
-461.0
-0
-23857.0
-1366.0
-0
-2109
-836.0
-0
-12175.0
-634.0
-0
-17047.0
-1005.0
-1
-30943.0
-1685.0
-1
-14841.0
-829.0
-1
-21360.0
-1175.0
-1
-22790.0
-1521.0
-1
-7537.0
-813.0
-0
--999
--999
--999
-4899
-874
-1890
-33895
-1878
-0
-1
-234216
\ No newline at end of file
+Position Data For Level 4 - DO NOT MODIFY THIS FILE!
+1820
+1025
+980
+2974
+1371
+1750
+4899
+1198
+1890
+6909
+1002
+1330
+8399
+1319
+1330
+9841
+1145
+560
+10509
+983
+1260
+11896
+823
+840
+12919
+650
+1120
+14174
+1018
+1050
+15387
+1194
+1890
+17396
+994
+630
+18199
+1294
+840
+19186
+1118
+1680
+21001
+1364
+840
+22018
+1710
+1190
+23384
+1555
+1050
+24627
+1374
+840
+25595
+1195
+1680
+27437
+1592
+910
+28551
+1901
+770
+29456
+2072
+840
+30469
+1874
+840
+31483
+1687
+840
+32455
+1878
+1540
+-999
+-999
+-999
+-999
+10135.0
+956.0
+0
+19756.0
+929.0
+0
+4529.0
+1182.0
+0
+33303.0
+1689.0
+0
+26371.0
+1006.0
+1
+29853.0
+1883.0
+0
+9058.0
+1130.0
+0
+10845.0
+794.0
+0
+28699.0
+1712.0
+1
+18496.0
+1105.0
+0
+28184.0
+1403.0
+0
+25153.0
+1185.0
+1
+32211.0
+1498.0
+0
+17508.0
+805.0
+1
+13183.0
+461.0
+0
+23857.0
+1366.0
+0
+2109
+836.0
+0
+12175.0
+634.0
+0
+17047.0
+1005.0
+1
+30943.0
+1685.0
+1
+14841.0
+829.0
+1
+21360.0
+1175.0
+1
+22790.0
+1521.0
+1
+7537.0
+813.0
+0
+-999
+-999
+-999
+4899
+874
+1890
+33895
+1878
+0
+1
+234216
diff --git a/levels/lvl_custom.dat b/src/exit_dash/assets/levels/lvl_custom.dat
similarity index 99%
rename from levels/lvl_custom.dat
rename to src/exit_dash/assets/levels/lvl_custom.dat
index 214e600..12cb65e 100644
--- a/levels/lvl_custom.dat
+++ b/src/exit_dash/assets/levels/lvl_custom.dat
@@ -160,4 +160,4 @@ Position Data For Level custom - DO NOT MODIFY THIS FILE!
658
1
1
-None
\ No newline at end of file
+None
diff --git a/src/exit_dash/assets/levels/lvlhints.dat b/src/exit_dash/assets/levels/lvlhints.dat
new file mode 100644
index 0000000..fd9e5d5
--- /dev/null
+++ b/src/exit_dash/assets/levels/lvlhints.dat
@@ -0,0 +1,2 @@
+Welcome to the Hyperion Space Centre! Use {DUCK} to duck and the arrow keys to move around.
+Hey, who turned out the lights?
diff --git a/music/char1_3.ogg b/src/exit_dash/assets/music/char1_3.ogg
similarity index 100%
rename from music/char1_3.ogg
rename to src/exit_dash/assets/music/char1_3.ogg
diff --git a/src/exit_dash/assets/music/gameover.ogg b/src/exit_dash/assets/music/gameover.ogg
new file mode 100644
index 0000000..52a4b49
Binary files /dev/null and b/src/exit_dash/assets/music/gameover.ogg differ
diff --git a/src/exit_dash/assets/music/menuloop.ogg b/src/exit_dash/assets/music/menuloop.ogg
new file mode 100644
index 0000000..bbf7651
Binary files /dev/null and b/src/exit_dash/assets/music/menuloop.ogg differ
diff --git a/src/exit_dash/assets/music/waking_devil.ogg b/src/exit_dash/assets/music/waking_devil.ogg
new file mode 100644
index 0000000..8bcd733
Binary files /dev/null and b/src/exit_dash/assets/music/waking_devil.ogg differ
diff --git a/sounds/beep_message.ogg b/src/exit_dash/assets/sounds/beep_message.ogg
similarity index 100%
rename from sounds/beep_message.ogg
rename to src/exit_dash/assets/sounds/beep_message.ogg
diff --git a/sounds/boxopen.ogg b/src/exit_dash/assets/sounds/boxopen.ogg
similarity index 100%
rename from sounds/boxopen.ogg
rename to src/exit_dash/assets/sounds/boxopen.ogg
diff --git a/sounds/click1.ogg b/src/exit_dash/assets/sounds/click1.ogg
similarity index 100%
rename from sounds/click1.ogg
rename to src/exit_dash/assets/sounds/click1.ogg
diff --git a/sounds/click2.ogg b/src/exit_dash/assets/sounds/click2.ogg
similarity index 100%
rename from sounds/click2.ogg
rename to src/exit_dash/assets/sounds/click2.ogg
diff --git a/sounds/cogs.ogg b/src/exit_dash/assets/sounds/cogs.ogg
similarity index 100%
rename from sounds/cogs.ogg
rename to src/exit_dash/assets/sounds/cogs.ogg
diff --git a/sounds/door_open.ogg b/src/exit_dash/assets/sounds/door_open.ogg
similarity index 100%
rename from sounds/door_open.ogg
rename to src/exit_dash/assets/sounds/door_open.ogg
diff --git a/sounds/kill_shoot.ogg b/src/exit_dash/assets/sounds/kill_shoot.ogg
similarity index 100%
rename from sounds/kill_shoot.ogg
rename to src/exit_dash/assets/sounds/kill_shoot.ogg
diff --git a/sounds/landing.ogg b/src/exit_dash/assets/sounds/landing.ogg
similarity index 100%
rename from sounds/landing.ogg
rename to src/exit_dash/assets/sounds/landing.ogg
diff --git a/sounds/lava.ogg b/src/exit_dash/assets/sounds/lava.ogg
similarity index 100%
rename from sounds/lava.ogg
rename to src/exit_dash/assets/sounds/lava.ogg
diff --git a/sounds/rollover1.ogg b/src/exit_dash/assets/sounds/rollover1.ogg
similarity index 100%
rename from sounds/rollover1.ogg
rename to src/exit_dash/assets/sounds/rollover1.ogg
diff --git a/sounds/rollover2.ogg b/src/exit_dash/assets/sounds/rollover2.ogg
similarity index 100%
rename from sounds/rollover2.ogg
rename to src/exit_dash/assets/sounds/rollover2.ogg
diff --git a/sounds/steps_chain.ogg b/src/exit_dash/assets/sounds/steps_chain.ogg
similarity index 100%
rename from sounds/steps_chain.ogg
rename to src/exit_dash/assets/sounds/steps_chain.ogg
diff --git a/sounds/steps_platform.ogg b/src/exit_dash/assets/sounds/steps_platform.ogg
similarity index 100%
rename from sounds/steps_platform.ogg
rename to src/exit_dash/assets/sounds/steps_platform.ogg
diff --git a/sounds/steps_platform2.ogg b/src/exit_dash/assets/sounds/steps_platform2.ogg
similarity index 100%
rename from sounds/steps_platform2.ogg
rename to src/exit_dash/assets/sounds/steps_platform2.ogg
diff --git a/sounds/steps_stairs.ogg b/src/exit_dash/assets/sounds/steps_stairs.ogg
similarity index 100%
rename from sounds/steps_stairs.ogg
rename to src/exit_dash/assets/sounds/steps_stairs.ogg
diff --git a/sounds/steps_stairs1.ogg b/src/exit_dash/assets/sounds/steps_stairs1.ogg
similarity index 100%
rename from sounds/steps_stairs1.ogg
rename to src/exit_dash/assets/sounds/steps_stairs1.ogg
diff --git a/sounds/switch2.ogg b/src/exit_dash/assets/sounds/switch2.ogg
similarity index 100%
rename from sounds/switch2.ogg
rename to src/exit_dash/assets/sounds/switch2.ogg
diff --git a/sounds/switch3.ogg b/src/exit_dash/assets/sounds/switch3.ogg
similarity index 100%
rename from sounds/switch3.ogg
rename to src/exit_dash/assets/sounds/switch3.ogg
diff --git a/sounds/synthetic_explosion_1.ogg b/src/exit_dash/assets/sounds/synthetic_explosion_1.ogg
similarity index 100%
rename from sounds/synthetic_explosion_1.ogg
rename to src/exit_dash/assets/sounds/synthetic_explosion_1.ogg
diff --git a/src/exit_dash/assets/ui/blue_boxCheckmark.png b/src/exit_dash/assets/ui/blue_boxCheckmark.png
new file mode 100644
index 0000000..65e9d0e
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_boxCheckmark.png differ
diff --git a/src/exit_dash/assets/ui/blue_boxCross.png b/src/exit_dash/assets/ui/blue_boxCross.png
new file mode 100644
index 0000000..d3eac6d
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_boxCross.png differ
diff --git a/src/exit_dash/assets/ui/blue_boxTick.png b/src/exit_dash/assets/ui/blue_boxTick.png
new file mode 100644
index 0000000..33f0f02
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_boxTick.png differ
diff --git a/src/exit_dash/assets/ui/blue_button00.png b/src/exit_dash/assets/ui/blue_button00.png
new file mode 100644
index 0000000..5e6ae40
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button00.png differ
diff --git a/src/exit_dash/assets/ui/blue_button01.png b/src/exit_dash/assets/ui/blue_button01.png
new file mode 100644
index 0000000..154ffe6
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button01.png differ
diff --git a/src/exit_dash/assets/ui/blue_button02.png b/src/exit_dash/assets/ui/blue_button02.png
new file mode 100644
index 0000000..7b59b6f
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button02.png differ
diff --git a/src/exit_dash/assets/ui/blue_button03.png b/src/exit_dash/assets/ui/blue_button03.png
new file mode 100644
index 0000000..fad1875
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button03.png differ
diff --git a/src/exit_dash/assets/ui/blue_button04.png b/src/exit_dash/assets/ui/blue_button04.png
new file mode 100644
index 0000000..987fa64
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button04.png differ
diff --git a/src/exit_dash/assets/ui/blue_button05.png b/src/exit_dash/assets/ui/blue_button05.png
new file mode 100644
index 0000000..070f3a9
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button05.png differ
diff --git a/src/exit_dash/assets/ui/blue_button06.png b/src/exit_dash/assets/ui/blue_button06.png
new file mode 100644
index 0000000..c6e3080
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button06.png differ
diff --git a/src/exit_dash/assets/ui/blue_button07.png b/src/exit_dash/assets/ui/blue_button07.png
new file mode 100644
index 0000000..3433b84
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button07.png differ
diff --git a/src/exit_dash/assets/ui/blue_button08.png b/src/exit_dash/assets/ui/blue_button08.png
new file mode 100644
index 0000000..ac89eaa
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button08.png differ
diff --git a/src/exit_dash/assets/ui/blue_button09.png b/src/exit_dash/assets/ui/blue_button09.png
new file mode 100644
index 0000000..7e5a65d
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button09.png differ
diff --git a/src/exit_dash/assets/ui/blue_button10.png b/src/exit_dash/assets/ui/blue_button10.png
new file mode 100644
index 0000000..4fbf645
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button10.png differ
diff --git a/src/exit_dash/assets/ui/blue_button11.png b/src/exit_dash/assets/ui/blue_button11.png
new file mode 100644
index 0000000..c64d3ed
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button11.png differ
diff --git a/src/exit_dash/assets/ui/blue_button12.png b/src/exit_dash/assets/ui/blue_button12.png
new file mode 100644
index 0000000..bb36abc
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button12.png differ
diff --git a/src/exit_dash/assets/ui/blue_button13.png b/src/exit_dash/assets/ui/blue_button13.png
new file mode 100644
index 0000000..2722f0d
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_button13.png differ
diff --git a/src/exit_dash/assets/ui/blue_checkmark.png b/src/exit_dash/assets/ui/blue_checkmark.png
new file mode 100644
index 0000000..cff6e8c
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_checkmark.png differ
diff --git a/src/exit_dash/assets/ui/blue_circle.png b/src/exit_dash/assets/ui/blue_circle.png
new file mode 100644
index 0000000..cb0935e
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_circle.png differ
diff --git a/src/exit_dash/assets/ui/blue_cross.png b/src/exit_dash/assets/ui/blue_cross.png
new file mode 100644
index 0000000..95beb93
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_cross.png differ
diff --git a/src/exit_dash/assets/ui/blue_panel.png b/src/exit_dash/assets/ui/blue_panel.png
new file mode 100644
index 0000000..033855f
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_panel.png differ
diff --git a/src/exit_dash/assets/ui/blue_sliderDown.png b/src/exit_dash/assets/ui/blue_sliderDown.png
new file mode 100644
index 0000000..521e780
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_sliderDown.png differ
diff --git a/src/exit_dash/assets/ui/blue_sliderLeft.png b/src/exit_dash/assets/ui/blue_sliderLeft.png
new file mode 100644
index 0000000..85d23f7
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_sliderLeft.png differ
diff --git a/src/exit_dash/assets/ui/blue_sliderRight.png b/src/exit_dash/assets/ui/blue_sliderRight.png
new file mode 100644
index 0000000..0efabab
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_sliderRight.png differ
diff --git a/src/exit_dash/assets/ui/blue_sliderUp.png b/src/exit_dash/assets/ui/blue_sliderUp.png
new file mode 100644
index 0000000..000d710
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_sliderUp.png differ
diff --git a/src/exit_dash/assets/ui/blue_tick.png b/src/exit_dash/assets/ui/blue_tick.png
new file mode 100644
index 0000000..2dc7a88
Binary files /dev/null and b/src/exit_dash/assets/ui/blue_tick.png differ
diff --git a/src/exit_dash/assets/ui/dropdownBottom.png b/src/exit_dash/assets/ui/dropdownBottom.png
new file mode 100644
index 0000000..1732183
Binary files /dev/null and b/src/exit_dash/assets/ui/dropdownBottom.png differ
diff --git a/src/exit_dash/assets/ui/dropdownMid.png b/src/exit_dash/assets/ui/dropdownMid.png
new file mode 100644
index 0000000..3744fe9
Binary files /dev/null and b/src/exit_dash/assets/ui/dropdownMid.png differ
diff --git a/src/exit_dash/assets/ui/dropdownTop.png b/src/exit_dash/assets/ui/dropdownTop.png
new file mode 100644
index 0000000..af4e353
Binary files /dev/null and b/src/exit_dash/assets/ui/dropdownTop.png differ
diff --git a/src/exit_dash/assets/ui/green_boxCheckmark.png b/src/exit_dash/assets/ui/green_boxCheckmark.png
new file mode 100644
index 0000000..348e0e9
Binary files /dev/null and b/src/exit_dash/assets/ui/green_boxCheckmark.png differ
diff --git a/src/exit_dash/assets/ui/green_boxCross.png b/src/exit_dash/assets/ui/green_boxCross.png
new file mode 100644
index 0000000..f5cad76
Binary files /dev/null and b/src/exit_dash/assets/ui/green_boxCross.png differ
diff --git a/src/exit_dash/assets/ui/green_boxTick.png b/src/exit_dash/assets/ui/green_boxTick.png
new file mode 100644
index 0000000..a406589
Binary files /dev/null and b/src/exit_dash/assets/ui/green_boxTick.png differ
diff --git a/src/exit_dash/assets/ui/green_button00.png b/src/exit_dash/assets/ui/green_button00.png
new file mode 100644
index 0000000..353de60
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button00.png differ
diff --git a/src/exit_dash/assets/ui/green_button01.png b/src/exit_dash/assets/ui/green_button01.png
new file mode 100644
index 0000000..424259b
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button01.png differ
diff --git a/src/exit_dash/assets/ui/green_button02.png b/src/exit_dash/assets/ui/green_button02.png
new file mode 100644
index 0000000..9877d60
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button02.png differ
diff --git a/src/exit_dash/assets/ui/green_button03.png b/src/exit_dash/assets/ui/green_button03.png
new file mode 100644
index 0000000..71cc453
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button03.png differ
diff --git a/src/exit_dash/assets/ui/green_button04.png b/src/exit_dash/assets/ui/green_button04.png
new file mode 100644
index 0000000..dc0cee6
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button04.png differ
diff --git a/src/exit_dash/assets/ui/green_button05.png b/src/exit_dash/assets/ui/green_button05.png
new file mode 100644
index 0000000..2832f95
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button05.png differ
diff --git a/src/exit_dash/assets/ui/green_button06.png b/src/exit_dash/assets/ui/green_button06.png
new file mode 100644
index 0000000..26aabec
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button06.png differ
diff --git a/src/exit_dash/assets/ui/green_button07.png b/src/exit_dash/assets/ui/green_button07.png
new file mode 100644
index 0000000..ba09a22
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button07.png differ
diff --git a/src/exit_dash/assets/ui/green_button08.png b/src/exit_dash/assets/ui/green_button08.png
new file mode 100644
index 0000000..a60e3ba
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button08.png differ
diff --git a/src/exit_dash/assets/ui/green_button09.png b/src/exit_dash/assets/ui/green_button09.png
new file mode 100644
index 0000000..ad08917
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button09.png differ
diff --git a/src/exit_dash/assets/ui/green_button10.png b/src/exit_dash/assets/ui/green_button10.png
new file mode 100644
index 0000000..607e1cf
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button10.png differ
diff --git a/src/exit_dash/assets/ui/green_button11.png b/src/exit_dash/assets/ui/green_button11.png
new file mode 100644
index 0000000..798e620
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button11.png differ
diff --git a/src/exit_dash/assets/ui/green_button12.png b/src/exit_dash/assets/ui/green_button12.png
new file mode 100644
index 0000000..f8b8467
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button12.png differ
diff --git a/src/exit_dash/assets/ui/green_button13.png b/src/exit_dash/assets/ui/green_button13.png
new file mode 100644
index 0000000..d788527
Binary files /dev/null and b/src/exit_dash/assets/ui/green_button13.png differ
diff --git a/src/exit_dash/assets/ui/green_checkmark.png b/src/exit_dash/assets/ui/green_checkmark.png
new file mode 100644
index 0000000..81cf17d
Binary files /dev/null and b/src/exit_dash/assets/ui/green_checkmark.png differ
diff --git a/src/exit_dash/assets/ui/green_circle.png b/src/exit_dash/assets/ui/green_circle.png
new file mode 100644
index 0000000..860e912
Binary files /dev/null and b/src/exit_dash/assets/ui/green_circle.png differ
diff --git a/src/exit_dash/assets/ui/green_cross.png b/src/exit_dash/assets/ui/green_cross.png
new file mode 100644
index 0000000..4998bf6
Binary files /dev/null and b/src/exit_dash/assets/ui/green_cross.png differ
diff --git a/src/exit_dash/assets/ui/green_panel.png b/src/exit_dash/assets/ui/green_panel.png
new file mode 100644
index 0000000..04faaad
Binary files /dev/null and b/src/exit_dash/assets/ui/green_panel.png differ
diff --git a/src/exit_dash/assets/ui/green_sliderDown.png b/src/exit_dash/assets/ui/green_sliderDown.png
new file mode 100644
index 0000000..0c88986
Binary files /dev/null and b/src/exit_dash/assets/ui/green_sliderDown.png differ
diff --git a/src/exit_dash/assets/ui/green_sliderLeft.png b/src/exit_dash/assets/ui/green_sliderLeft.png
new file mode 100644
index 0000000..4f90891
Binary files /dev/null and b/src/exit_dash/assets/ui/green_sliderLeft.png differ
diff --git a/src/exit_dash/assets/ui/green_sliderRight.png b/src/exit_dash/assets/ui/green_sliderRight.png
new file mode 100644
index 0000000..6c5721a
Binary files /dev/null and b/src/exit_dash/assets/ui/green_sliderRight.png differ
diff --git a/src/exit_dash/assets/ui/green_sliderUp.png b/src/exit_dash/assets/ui/green_sliderUp.png
new file mode 100644
index 0000000..5b81eb5
Binary files /dev/null and b/src/exit_dash/assets/ui/green_sliderUp.png differ
diff --git a/src/exit_dash/assets/ui/green_tick.png b/src/exit_dash/assets/ui/green_tick.png
new file mode 100644
index 0000000..1173f09
Binary files /dev/null and b/src/exit_dash/assets/ui/green_tick.png differ
diff --git a/src/exit_dash/assets/ui/grey_arrowDownGrey.png b/src/exit_dash/assets/ui/grey_arrowDownGrey.png
new file mode 100644
index 0000000..58af3a6
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_arrowDownGrey.png differ
diff --git a/src/exit_dash/assets/ui/grey_arrowDownWhite.png b/src/exit_dash/assets/ui/grey_arrowDownWhite.png
new file mode 100644
index 0000000..0b62356
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_arrowDownWhite.png differ
diff --git a/src/exit_dash/assets/ui/grey_arrowUpGrey.png b/src/exit_dash/assets/ui/grey_arrowUpGrey.png
new file mode 100644
index 0000000..9aa1520
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_arrowUpGrey.png differ
diff --git a/src/exit_dash/assets/ui/grey_arrowUpWhite.png b/src/exit_dash/assets/ui/grey_arrowUpWhite.png
new file mode 100644
index 0000000..4a10ddf
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_arrowUpWhite.png differ
diff --git a/src/exit_dash/assets/ui/grey_box.png b/src/exit_dash/assets/ui/grey_box.png
new file mode 100644
index 0000000..3739bf4
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_box.png differ
diff --git a/src/exit_dash/assets/ui/grey_boxCheckmark.png b/src/exit_dash/assets/ui/grey_boxCheckmark.png
new file mode 100644
index 0000000..8ea4517
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_boxCheckmark.png differ
diff --git a/src/exit_dash/assets/ui/grey_boxCross.png b/src/exit_dash/assets/ui/grey_boxCross.png
new file mode 100644
index 0000000..ed89002
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_boxCross.png differ
diff --git a/src/exit_dash/assets/ui/grey_boxTick.png b/src/exit_dash/assets/ui/grey_boxTick.png
new file mode 100644
index 0000000..7d245e5
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_boxTick.png differ
diff --git a/src/exit_dash/assets/ui/grey_button00.png b/src/exit_dash/assets/ui/grey_button00.png
new file mode 100644
index 0000000..23b55d9
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button00.png differ
diff --git a/src/exit_dash/assets/ui/grey_button01.png b/src/exit_dash/assets/ui/grey_button01.png
new file mode 100644
index 0000000..a09df8d
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button01.png differ
diff --git a/src/exit_dash/assets/ui/grey_button02.png b/src/exit_dash/assets/ui/grey_button02.png
new file mode 100644
index 0000000..eb13632
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button02.png differ
diff --git a/src/exit_dash/assets/ui/grey_button03.png b/src/exit_dash/assets/ui/grey_button03.png
new file mode 100644
index 0000000..c8ed80f
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button03.png differ
diff --git a/src/exit_dash/assets/ui/grey_button04.png b/src/exit_dash/assets/ui/grey_button04.png
new file mode 100644
index 0000000..5b5ff67
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button04.png differ
diff --git a/src/exit_dash/assets/ui/grey_button05.png b/src/exit_dash/assets/ui/grey_button05.png
new file mode 100644
index 0000000..816d01e
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button05.png differ
diff --git a/src/exit_dash/assets/ui/grey_button06.png b/src/exit_dash/assets/ui/grey_button06.png
new file mode 100644
index 0000000..fe2734e
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button06.png differ
diff --git a/src/exit_dash/assets/ui/grey_button07.png b/src/exit_dash/assets/ui/grey_button07.png
new file mode 100644
index 0000000..bea4357
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button07.png differ
diff --git a/src/exit_dash/assets/ui/grey_button08.png b/src/exit_dash/assets/ui/grey_button08.png
new file mode 100644
index 0000000..79d1cfd
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button08.png differ
diff --git a/src/exit_dash/assets/ui/grey_button09.png b/src/exit_dash/assets/ui/grey_button09.png
new file mode 100644
index 0000000..168e226
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button09.png differ
diff --git a/src/exit_dash/assets/ui/grey_button10.png b/src/exit_dash/assets/ui/grey_button10.png
new file mode 100644
index 0000000..c984b30
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button10.png differ
diff --git a/src/exit_dash/assets/ui/grey_button11.png b/src/exit_dash/assets/ui/grey_button11.png
new file mode 100644
index 0000000..ff8abb4
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button11.png differ
diff --git a/src/exit_dash/assets/ui/grey_button12.png b/src/exit_dash/assets/ui/grey_button12.png
new file mode 100644
index 0000000..c14e3fb
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button12.png differ
diff --git a/src/exit_dash/assets/ui/grey_button13.png b/src/exit_dash/assets/ui/grey_button13.png
new file mode 100644
index 0000000..a27f7ba
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button13.png differ
diff --git a/src/exit_dash/assets/ui/grey_button14.png b/src/exit_dash/assets/ui/grey_button14.png
new file mode 100644
index 0000000..0dd79b4
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button14.png differ
diff --git a/src/exit_dash/assets/ui/grey_button15.png b/src/exit_dash/assets/ui/grey_button15.png
new file mode 100644
index 0000000..47d4db2
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_button15.png differ
diff --git a/src/exit_dash/assets/ui/grey_checkmarkGrey.png b/src/exit_dash/assets/ui/grey_checkmarkGrey.png
new file mode 100644
index 0000000..74965f1
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_checkmarkGrey.png differ
diff --git a/src/exit_dash/assets/ui/grey_checkmarkWhite.png b/src/exit_dash/assets/ui/grey_checkmarkWhite.png
new file mode 100644
index 0000000..b980b7a
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_checkmarkWhite.png differ
diff --git a/src/exit_dash/assets/ui/grey_circle.png b/src/exit_dash/assets/ui/grey_circle.png
new file mode 100644
index 0000000..21dd3bc
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_circle.png differ
diff --git a/src/exit_dash/assets/ui/grey_crossGrey.png b/src/exit_dash/assets/ui/grey_crossGrey.png
new file mode 100644
index 0000000..f2476fd
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_crossGrey.png differ
diff --git a/src/exit_dash/assets/ui/grey_crossWhite.png b/src/exit_dash/assets/ui/grey_crossWhite.png
new file mode 100644
index 0000000..f77a307
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_crossWhite.png differ
diff --git a/src/exit_dash/assets/ui/grey_panel.png b/src/exit_dash/assets/ui/grey_panel.png
new file mode 100644
index 0000000..c7a1652
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_panel.png differ
diff --git a/src/exit_dash/assets/ui/grey_sliderDown.png b/src/exit_dash/assets/ui/grey_sliderDown.png
new file mode 100644
index 0000000..d6c709a
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_sliderDown.png differ
diff --git a/src/exit_dash/assets/ui/grey_sliderEnd.png b/src/exit_dash/assets/ui/grey_sliderEnd.png
new file mode 100644
index 0000000..e5ba4be
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_sliderEnd.png differ
diff --git a/src/exit_dash/assets/ui/grey_sliderHorizontal.png b/src/exit_dash/assets/ui/grey_sliderHorizontal.png
new file mode 100644
index 0000000..47ccf05
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_sliderHorizontal.png differ
diff --git a/src/exit_dash/assets/ui/grey_sliderLeft.png b/src/exit_dash/assets/ui/grey_sliderLeft.png
new file mode 100644
index 0000000..c70f511
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_sliderLeft.png differ
diff --git a/src/exit_dash/assets/ui/grey_sliderRight.png b/src/exit_dash/assets/ui/grey_sliderRight.png
new file mode 100644
index 0000000..1c952f0
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_sliderRight.png differ
diff --git a/src/exit_dash/assets/ui/grey_sliderUp.png b/src/exit_dash/assets/ui/grey_sliderUp.png
new file mode 100644
index 0000000..21f5906
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_sliderUp.png differ
diff --git a/src/exit_dash/assets/ui/grey_sliderVertical.png b/src/exit_dash/assets/ui/grey_sliderVertical.png
new file mode 100644
index 0000000..d649757
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_sliderVertical.png differ
diff --git a/src/exit_dash/assets/ui/grey_tickGrey.png b/src/exit_dash/assets/ui/grey_tickGrey.png
new file mode 100644
index 0000000..36cb7d3
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_tickGrey.png differ
diff --git a/src/exit_dash/assets/ui/grey_tickWhite.png b/src/exit_dash/assets/ui/grey_tickWhite.png
new file mode 100644
index 0000000..4556fd4
Binary files /dev/null and b/src/exit_dash/assets/ui/grey_tickWhite.png differ
diff --git a/src/exit_dash/assets/ui/license.txt b/src/exit_dash/assets/ui/license.txt
new file mode 100644
index 0000000..8609fdf
--- /dev/null
+++ b/src/exit_dash/assets/ui/license.txt
@@ -0,0 +1,14 @@
+
+###############################################################################
+
+ UI pack by Kenney Vleugels (www.kenney.nl)
+
+ ------------------------------
+
+ License (CC0)
+ http://creativecommons.org/publicdomain/zero/1.0/
+
+ You may use these graphics in personal and commercial projects.
+ Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
+
+###############################################################################
diff --git a/src/exit_dash/assets/ui/red_boxCheckmark.png b/src/exit_dash/assets/ui/red_boxCheckmark.png
new file mode 100644
index 0000000..e0b6fb7
Binary files /dev/null and b/src/exit_dash/assets/ui/red_boxCheckmark.png differ
diff --git a/src/exit_dash/assets/ui/red_boxCross.png b/src/exit_dash/assets/ui/red_boxCross.png
new file mode 100644
index 0000000..c485c1a
Binary files /dev/null and b/src/exit_dash/assets/ui/red_boxCross.png differ
diff --git a/src/exit_dash/assets/ui/red_boxTick.png b/src/exit_dash/assets/ui/red_boxTick.png
new file mode 100644
index 0000000..b5acf30
Binary files /dev/null and b/src/exit_dash/assets/ui/red_boxTick.png differ
diff --git a/src/exit_dash/assets/ui/red_button00.png b/src/exit_dash/assets/ui/red_button00.png
new file mode 100644
index 0000000..10fcf7a
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button00.png differ
diff --git a/src/exit_dash/assets/ui/red_button01.png b/src/exit_dash/assets/ui/red_button01.png
new file mode 100644
index 0000000..1349054
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button01.png differ
diff --git a/src/exit_dash/assets/ui/red_button02.png b/src/exit_dash/assets/ui/red_button02.png
new file mode 100644
index 0000000..62e5235
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button02.png differ
diff --git a/src/exit_dash/assets/ui/red_button03.png b/src/exit_dash/assets/ui/red_button03.png
new file mode 100644
index 0000000..90bfaee
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button03.png differ
diff --git a/src/exit_dash/assets/ui/red_button04.png b/src/exit_dash/assets/ui/red_button04.png
new file mode 100644
index 0000000..3d20587
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button04.png differ
diff --git a/src/exit_dash/assets/ui/red_button05.png b/src/exit_dash/assets/ui/red_button05.png
new file mode 100644
index 0000000..d1909a9
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button05.png differ
diff --git a/src/exit_dash/assets/ui/red_button06.png b/src/exit_dash/assets/ui/red_button06.png
new file mode 100644
index 0000000..26193ca
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button06.png differ
diff --git a/src/exit_dash/assets/ui/red_button07.png b/src/exit_dash/assets/ui/red_button07.png
new file mode 100644
index 0000000..143a361
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button07.png differ
diff --git a/src/exit_dash/assets/ui/red_button08.png b/src/exit_dash/assets/ui/red_button08.png
new file mode 100644
index 0000000..151bd12
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button08.png differ
diff --git a/src/exit_dash/assets/ui/red_button09.png b/src/exit_dash/assets/ui/red_button09.png
new file mode 100644
index 0000000..8a49302
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button09.png differ
diff --git a/src/exit_dash/assets/ui/red_button10.png b/src/exit_dash/assets/ui/red_button10.png
new file mode 100644
index 0000000..c8a2725
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button10.png differ
diff --git a/src/exit_dash/assets/ui/red_button11.png b/src/exit_dash/assets/ui/red_button11.png
new file mode 100644
index 0000000..cc945a8
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button11.png differ
diff --git a/src/exit_dash/assets/ui/red_button12.png b/src/exit_dash/assets/ui/red_button12.png
new file mode 100644
index 0000000..2f91aaa
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button12.png differ
diff --git a/src/exit_dash/assets/ui/red_button13.png b/src/exit_dash/assets/ui/red_button13.png
new file mode 100644
index 0000000..ffcbf88
Binary files /dev/null and b/src/exit_dash/assets/ui/red_button13.png differ
diff --git a/src/exit_dash/assets/ui/red_checkmark.png b/src/exit_dash/assets/ui/red_checkmark.png
new file mode 100644
index 0000000..bfb07e7
Binary files /dev/null and b/src/exit_dash/assets/ui/red_checkmark.png differ
diff --git a/src/exit_dash/assets/ui/red_circle.png b/src/exit_dash/assets/ui/red_circle.png
new file mode 100644
index 0000000..1f26c21
Binary files /dev/null and b/src/exit_dash/assets/ui/red_circle.png differ
diff --git a/src/exit_dash/assets/ui/red_cross.png b/src/exit_dash/assets/ui/red_cross.png
new file mode 100644
index 0000000..67df86b
Binary files /dev/null and b/src/exit_dash/assets/ui/red_cross.png differ
diff --git a/src/exit_dash/assets/ui/red_panel.png b/src/exit_dash/assets/ui/red_panel.png
new file mode 100644
index 0000000..e1bb995
Binary files /dev/null and b/src/exit_dash/assets/ui/red_panel.png differ
diff --git a/src/exit_dash/assets/ui/red_sliderDown.png b/src/exit_dash/assets/ui/red_sliderDown.png
new file mode 100644
index 0000000..04bf063
Binary files /dev/null and b/src/exit_dash/assets/ui/red_sliderDown.png differ
diff --git a/src/exit_dash/assets/ui/red_sliderLeft.png b/src/exit_dash/assets/ui/red_sliderLeft.png
new file mode 100644
index 0000000..15e0e89
Binary files /dev/null and b/src/exit_dash/assets/ui/red_sliderLeft.png differ
diff --git a/src/exit_dash/assets/ui/red_sliderRight.png b/src/exit_dash/assets/ui/red_sliderRight.png
new file mode 100644
index 0000000..2cb7037
Binary files /dev/null and b/src/exit_dash/assets/ui/red_sliderRight.png differ
diff --git a/src/exit_dash/assets/ui/red_sliderUp.png b/src/exit_dash/assets/ui/red_sliderUp.png
new file mode 100644
index 0000000..1bfc9ad
Binary files /dev/null and b/src/exit_dash/assets/ui/red_sliderUp.png differ
diff --git a/src/exit_dash/assets/ui/red_tick.png b/src/exit_dash/assets/ui/red_tick.png
new file mode 100644
index 0000000..1a52e1b
Binary files /dev/null and b/src/exit_dash/assets/ui/red_tick.png differ
diff --git a/src/exit_dash/assets/ui/yellow_boxCheckmark.png b/src/exit_dash/assets/ui/yellow_boxCheckmark.png
new file mode 100644
index 0000000..ce4e92c
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_boxCheckmark.png differ
diff --git a/src/exit_dash/assets/ui/yellow_boxCross.png b/src/exit_dash/assets/ui/yellow_boxCross.png
new file mode 100644
index 0000000..b716467
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_boxCross.png differ
diff --git a/src/exit_dash/assets/ui/yellow_boxTick.png b/src/exit_dash/assets/ui/yellow_boxTick.png
new file mode 100644
index 0000000..cc7fbc8
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_boxTick.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button00.png b/src/exit_dash/assets/ui/yellow_button00.png
new file mode 100644
index 0000000..554f1df
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button00.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button01.png b/src/exit_dash/assets/ui/yellow_button01.png
new file mode 100644
index 0000000..df5cc05
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button01.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button02.png b/src/exit_dash/assets/ui/yellow_button02.png
new file mode 100644
index 0000000..b46b638
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button02.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button03.png b/src/exit_dash/assets/ui/yellow_button03.png
new file mode 100644
index 0000000..6604fc9
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button03.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button04.png b/src/exit_dash/assets/ui/yellow_button04.png
new file mode 100644
index 0000000..f025815
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button04.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button05.png b/src/exit_dash/assets/ui/yellow_button05.png
new file mode 100644
index 0000000..a0b54fa
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button05.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button06.png b/src/exit_dash/assets/ui/yellow_button06.png
new file mode 100644
index 0000000..15785be
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button06.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button07.png b/src/exit_dash/assets/ui/yellow_button07.png
new file mode 100644
index 0000000..9fe26a4
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button07.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button08.png b/src/exit_dash/assets/ui/yellow_button08.png
new file mode 100644
index 0000000..249015a
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button08.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button09.png b/src/exit_dash/assets/ui/yellow_button09.png
new file mode 100644
index 0000000..3233b60
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button09.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button10.png b/src/exit_dash/assets/ui/yellow_button10.png
new file mode 100644
index 0000000..1c0fe22
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button10.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button11.png b/src/exit_dash/assets/ui/yellow_button11.png
new file mode 100644
index 0000000..12e51b4
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button11.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button12.png b/src/exit_dash/assets/ui/yellow_button12.png
new file mode 100644
index 0000000..44ae24e
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button12.png differ
diff --git a/src/exit_dash/assets/ui/yellow_button13.png b/src/exit_dash/assets/ui/yellow_button13.png
new file mode 100644
index 0000000..7264e37
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_button13.png differ
diff --git a/src/exit_dash/assets/ui/yellow_checkmark.png b/src/exit_dash/assets/ui/yellow_checkmark.png
new file mode 100644
index 0000000..9f09d96
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_checkmark.png differ
diff --git a/src/exit_dash/assets/ui/yellow_circle.png b/src/exit_dash/assets/ui/yellow_circle.png
new file mode 100644
index 0000000..9994afd
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_circle.png differ
diff --git a/src/exit_dash/assets/ui/yellow_cross.png b/src/exit_dash/assets/ui/yellow_cross.png
new file mode 100644
index 0000000..118e47c
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_cross.png differ
diff --git a/src/exit_dash/assets/ui/yellow_panel.png b/src/exit_dash/assets/ui/yellow_panel.png
new file mode 100644
index 0000000..585946d
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_panel.png differ
diff --git a/src/exit_dash/assets/ui/yellow_sliderDown.png b/src/exit_dash/assets/ui/yellow_sliderDown.png
new file mode 100644
index 0000000..3a88aae
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_sliderDown.png differ
diff --git a/src/exit_dash/assets/ui/yellow_sliderLeft.png b/src/exit_dash/assets/ui/yellow_sliderLeft.png
new file mode 100644
index 0000000..94f40ac
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_sliderLeft.png differ
diff --git a/src/exit_dash/assets/ui/yellow_sliderRight.png b/src/exit_dash/assets/ui/yellow_sliderRight.png
new file mode 100644
index 0000000..03c2cc5
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_sliderRight.png differ
diff --git a/src/exit_dash/assets/ui/yellow_sliderUp.png b/src/exit_dash/assets/ui/yellow_sliderUp.png
new file mode 100644
index 0000000..07028d5
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_sliderUp.png differ
diff --git a/src/exit_dash/assets/ui/yellow_tick.png b/src/exit_dash/assets/ui/yellow_tick.png
new file mode 100644
index 0000000..5a8743f
Binary files /dev/null and b/src/exit_dash/assets/ui/yellow_tick.png differ
diff --git a/src/exit_dash/core/__init__.py b/src/exit_dash/core/__init__.py
new file mode 100644
index 0000000..694a149
--- /dev/null
+++ b/src/exit_dash/core/__init__.py
@@ -0,0 +1,3 @@
+"""Engine core: the application loop, scene stack, input, settings and resources."""
+
+from __future__ import annotations
diff --git a/src/exit_dash/core/app.py b/src/exit_dash/core/app.py
new file mode 100644
index 0000000..86fc31e
--- /dev/null
+++ b/src/exit_dash/core/app.py
@@ -0,0 +1,129 @@
+"""The application: window/display setup and the fixed-timestep main loop.
+
+The loop decouples simulation from rendering. Real elapsed time accumulates, and the
+active scene is advanced in fixed ``FIXED_DT`` steps — zero or more per rendered frame —
+so physics is frame-rate independent yet behaves exactly as the original per-frame code
+did (no ``dt`` scaling inside the step, which would let fast objects tunnel through
+collisions). Rendering then happens once per frame.
+"""
+
+from __future__ import annotations
+
+import os
+
+import pygame
+
+from exit_dash.core import resources
+from exit_dash.core.constants import (
+ BLACK,
+ FIXED_DT,
+ LOGICAL_SIZE,
+ MAX_FRAME_TIME,
+ MAX_STEPS_PER_FRAME,
+ WINDOW_TITLE,
+)
+from exit_dash.core.input import InputState
+from exit_dash.core.scene import Quit, Scene, SceneManager
+
+
+class Application:
+ """Owns the pygame display and runs the fixed-timestep loop over a scene stack."""
+
+ def __init__(
+ self,
+ *,
+ headless: bool = False,
+ fullscreen: bool = True,
+ vsync: bool = True,
+ render_fps_cap: int = 0,
+ ) -> None:
+ self.headless = headless
+ self.fullscreen = fullscreen
+ self.vsync = vsync
+ self.render_fps_cap = render_fps_cap
+ self.frame_count = 0
+
+ if headless:
+ os.environ.setdefault("SDL_VIDEODRIVER", "dummy")
+ os.environ.setdefault("SDL_AUDIODRIVER", "dummy")
+
+ pygame.display.init()
+ pygame.font.init()
+ self.audio_enabled = self._init_audio()
+ self.screen = self._create_display()
+ pygame.display.set_caption(WINDOW_TITLE)
+ self.input = InputState()
+
+ def _init_audio(self) -> bool:
+ """Initialise the mixer, tolerating headless/CI environments with no audio."""
+ try:
+ pygame.mixer.init()
+ except pygame.error:
+ return False
+ return pygame.mixer.get_init() is not None
+
+ def _create_display(self) -> pygame.Surface:
+ if self.headless:
+ # The dummy SDL video driver dislikes SCALED/vsync; a plain surface is enough
+ # and still lets Surface.convert()/convert_alpha() work.
+ return pygame.display.set_mode(LOGICAL_SIZE)
+ flags = pygame.SCALED | pygame.RESIZABLE
+ if self.fullscreen:
+ flags |= pygame.FULLSCREEN
+ try:
+ return pygame.display.set_mode(LOGICAL_SIZE, flags, vsync=1 if self.vsync else 0)
+ except pygame.error:
+ # vsync isn't available on every driver; fall back without it.
+ return pygame.display.set_mode(LOGICAL_SIZE, flags)
+
+ def run(self, initial_scene: Scene, max_frames: int | None = None) -> int:
+ """Run the loop until the scene stack empties or ``max_frames`` is reached.
+
+ Returns the number of rendered frames. When ``max_frames`` is set (headless
+ tests/CI) each frame advances the simulation by exactly one fixed step, so the
+ run is deterministic and "frames == simulation steps".
+ """
+ manager = SceneManager(initial_scene)
+ clock = pygame.time.Clock()
+ accumulator = 0.0
+ deterministic = self.headless and max_frames is not None
+
+ while manager.running:
+ if max_frames is not None and self.frame_count >= max_frames:
+ break
+
+ elapsed = clock.tick(self.render_fps_cap) / 1000.0
+ frame_time = FIXED_DT if deterministic else min(elapsed, MAX_FRAME_TIME)
+ accumulator += frame_time
+
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ manager.apply(Quit())
+ else:
+ manager.handle_event(event)
+ if not manager.running:
+ break
+
+ self.input.poll()
+
+ steps = 0
+ while accumulator >= FIXED_DT and steps < MAX_STEPS_PER_FRAME and manager.running:
+ manager.update(FIXED_DT, self.input)
+ accumulator -= FIXED_DT
+ steps += 1
+ if steps == MAX_STEPS_PER_FRAME:
+ accumulator = 0.0 # drop the backlog rather than spiral
+
+ self.screen.fill(BLACK)
+ if manager.running:
+ manager.draw(self.screen, accumulator / FIXED_DT)
+ pygame.display.flip()
+ self.frame_count += 1
+
+ return self.frame_count
+
+ def quit(self) -> None:
+ # Cached surfaces/fonts are bound to this pygame session; drop them so a later
+ # session (e.g. the next test) reloads fresh assets instead of stale handles.
+ resources.clear_cache()
+ pygame.quit()
diff --git a/src/exit_dash/core/constants.py b/src/exit_dash/core/constants.py
new file mode 100644
index 0000000..3d0943b
--- /dev/null
+++ b/src/exit_dash/core/constants.py
@@ -0,0 +1,66 @@
+"""Engine-wide constants: timestep, colours, render layers and the logical resolution.
+
+Gameplay tunables (gravity, jump/run speeds, etc.) live with the entities that use
+them; this module holds only values shared across the whole engine.
+"""
+
+from __future__ import annotations
+
+from enum import IntEnum
+from typing import Final
+
+RGB = tuple[int, int, int]
+
+# --- Timestep -------------------------------------------------------------------------
+# The simulation advances in fixed steps so physics and collision behave identically
+# regardless of how fast the machine renders. 60 Hz matches the ~60-65 FPS the original
+# game was tuned for, so the per-step velocity/gravity constants carry over unchanged.
+FIXED_FPS: Final = 60
+FIXED_DT: Final = 1.0 / FIXED_FPS
+# Cap how many simulation steps a single rendered frame may run, so a long stall
+# (debugger breakpoint, window drag) can't trigger a "spiral of death".
+MAX_STEPS_PER_FRAME: Final = 5
+# Ignore frame deltas larger than this (seconds); the loop drops the backlog instead.
+MAX_FRAME_TIME: Final = 0.25
+
+# --- Logical resolution ---------------------------------------------------------------
+# The game renders at this fixed internal size; pygame.SCALED upscales it to the window
+# or monitor and auto-scales mouse coordinates, so the game looks right on any display.
+LOGICAL_WIDTH: Final = 1280
+LOGICAL_HEIGHT: Final = 720
+LOGICAL_SIZE: Final[tuple[int, int]] = (LOGICAL_WIDTH, LOGICAL_HEIGHT)
+
+WINDOW_TITLE: Final = "Exit Dash: Hyperion"
+
+# --- Colours ------------------------------------------------------------------- -------
+WHITE: Final[RGB] = (255, 255, 255)
+GREY: Final[RGB] = (185, 185, 185)
+BLACK: Final[RGB] = (0, 0, 0)
+RED: Final[RGB] = (155, 0, 0)
+BRIGHT_RED: Final[RGB] = (175, 20, 20)
+GREEN: Final[RGB] = (0, 155, 0)
+BRIGHT_GREEN: Final[RGB] = (20, 175, 20)
+BLUE: Final[RGB] = (0, 0, 155)
+BRIGHT_BLUE: Final[RGB] = (20, 20, 175)
+YELLOW: Final[RGB] = (255, 255, 0)
+
+
+class Layer(IntEnum):
+ """Draw order for the level's sprite groups (lower is drawn first).
+
+ Mirrors the original ``Game.updateAll`` blit sequence exactly.
+ """
+
+ BACKGROUND = 0
+ FAKE_DOOR = 10
+ DOOR = 20
+ POOL = 30
+ FENCE = 40
+ FOLIAGE = 50
+ TORCH = 60
+ PLATFORM = 70
+ BLOCK = 80
+ ENEMY = 90
+ SPIKE = 100
+ KEY = 110
+ PLAYER = 120
diff --git a/src/exit_dash/core/input.py b/src/exit_dash/core/input.py
new file mode 100644
index 0000000..5b10b66
--- /dev/null
+++ b/src/exit_dash/core/input.py
@@ -0,0 +1,66 @@
+"""A per-frame snapshot of keyboard and mouse state.
+
+The application polls this once per rendered frame; scenes read it during ``update``
+instead of calling pygame's input functions directly. This keeps input testable (a
+test can inject a fake snapshot) and gives edge detection ("pressed this frame") for
+free. A higher-level action map is layered on top of this in :mod:`exit_dash` later.
+"""
+
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+import pygame
+
+
+@dataclass(frozen=True)
+class PlayerInput:
+ """A frame's worth of player intent, decoupled from physical keys.
+
+ Scenes build this from an :class:`InputState` + key bindings and hand it to the
+ player, so the player's logic is testable without pygame input.
+ """
+
+ left: bool = False
+ right: bool = False
+ jump: bool = False
+ duck: bool = False
+
+
+class InputState:
+ """Held/pressed keyboard state plus mouse position and click edges."""
+
+ def __init__(self) -> None:
+ self._keys: pygame.key.ScancodeWrapper | tuple[bool, ...] = ()
+ self._prev_keys: pygame.key.ScancodeWrapper | tuple[bool, ...] = ()
+ self.mouse_pos: tuple[int, int] = (0, 0)
+ self._buttons: tuple[bool, ...] = (False, False, False)
+ self._prev_buttons: tuple[bool, ...] = (False, False, False)
+
+ def poll(self) -> None:
+ """Capture the current keyboard and mouse state, remembering the previous one."""
+ self._prev_keys = self._keys
+ self._keys = pygame.key.get_pressed()
+ self.mouse_pos = pygame.mouse.get_pos()
+ self._prev_buttons = self._buttons
+ self._buttons = pygame.mouse.get_pressed()
+
+ def held(self, key: int) -> bool:
+ """True while ``key`` (a ``pygame.K_*`` constant) is down."""
+ return bool(self._keys) and bool(self._keys[key])
+
+ def pressed(self, key: int) -> bool:
+ """True only on the frame ``key`` transitions from up to down."""
+ now = bool(self._keys) and bool(self._keys[key])
+ was = bool(self._prev_keys) and bool(self._prev_keys[key])
+ return now and not was
+
+ @property
+ def mouse_held(self) -> bool:
+ """True while the left mouse button is down."""
+ return self._buttons[0]
+
+ @property
+ def mouse_clicked(self) -> bool:
+ """True only on the frame the left mouse button transitions from up to down."""
+ return self._buttons[0] and not self._prev_buttons[0]
diff --git a/src/exit_dash/core/keybindings.py b/src/exit_dash/core/keybindings.py
new file mode 100644
index 0000000..2fa6c15
--- /dev/null
+++ b/src/exit_dash/core/keybindings.py
@@ -0,0 +1,29 @@
+"""Default key bindings and human-readable key names.
+
+This mirrors the original ``keymap.SUMMARY`` token table. It is the single source of
+truth for which physical keys map to which game tokens, used both by the input layer
+and by hint-text interpolation (``{DUCK}`` -> ``"down"``).
+"""
+
+from __future__ import annotations
+
+from collections.abc import Mapping
+
+import pygame
+
+#: Game token -> pygame key constant.
+DEFAULT_BINDINGS: dict[str, int] = {
+ "ACTION": pygame.K_UP,
+ "ACTION2": pygame.K_SPACE,
+ "LEFT": pygame.K_LEFT,
+ "RIGHT": pygame.K_RIGHT,
+ "DUCK": pygame.K_DOWN,
+ "EXIT": pygame.K_ESCAPE,
+ "EXIT2": pygame.K_q,
+}
+
+
+def key_names(bindings: Mapping[str, int] | None = None) -> dict[str, str]:
+ """Return a ``token -> human key name`` map (e.g. ``{"DUCK": "down"}``)."""
+ bindings = DEFAULT_BINDINGS if bindings is None else bindings
+ return {token: pygame.key.name(code) for token, code in bindings.items()}
diff --git a/src/exit_dash/core/paths.py b/src/exit_dash/core/paths.py
new file mode 100644
index 0000000..95708ca
--- /dev/null
+++ b/src/exit_dash/core/paths.py
@@ -0,0 +1,45 @@
+"""Locate bundled assets and the user's writable data directory.
+
+Assets are resolved relative to this package — never the current working directory —
+so the game runs from any folder, from an installed wheel, and from a PyInstaller
+bundle. User-writable state (settings, custom levels) goes in the per-user config/data
+directories provided by :mod:`platformdirs`, which are writable even when the game is
+installed read-only.
+"""
+
+from __future__ import annotations
+
+import sys
+from pathlib import Path
+
+import platformdirs
+
+_APP_NAME = "ExitDashHyperion"
+_APP_AUTHOR = "BurinCode"
+
+
+def asset_root() -> Path:
+ """Return the directory that contains the bundled ``assets`` tree."""
+ bundle_dir = getattr(sys, "_MEIPASS", None) # set by PyInstaller one-file bundles
+ if bundle_dir:
+ return Path(bundle_dir) / "exit_dash" / "assets"
+ return Path(__file__).resolve().parent.parent / "assets"
+
+
+def asset_path(*parts: str) -> Path:
+ """Return the path to a bundled asset, e.g. ``asset_path("fonts", "atari.ttf")``."""
+ return asset_root().joinpath(*parts)
+
+
+def user_config_dir() -> Path:
+ """Return (creating if needed) the per-user config directory for settings."""
+ path = Path(platformdirs.user_config_dir(_APP_NAME, _APP_AUTHOR))
+ path.mkdir(parents=True, exist_ok=True)
+ return path
+
+
+def user_data_dir() -> Path:
+ """Return (creating if needed) the per-user data directory for saves/custom levels."""
+ path = Path(platformdirs.user_data_dir(_APP_NAME, _APP_AUTHOR))
+ path.mkdir(parents=True, exist_ok=True)
+ return path
diff --git a/src/exit_dash/core/resources.py b/src/exit_dash/core/resources.py
new file mode 100644
index 0000000..e4b64ff
--- /dev/null
+++ b/src/exit_dash/core/resources.py
@@ -0,0 +1,79 @@
+"""Cached, package-anchored loading of images, fonts and sounds.
+
+All asset access goes through here so paths resolve from the package (never the CWD),
+results are cached, and a missing asset degrades to a visible magenta placeholder with a
+logged warning instead of crashing the game.
+"""
+
+from __future__ import annotations
+
+import logging
+
+import pygame
+
+from exit_dash.core.paths import asset_path
+
+_log = logging.getLogger(__name__)
+
+_images: dict[tuple[tuple[str, ...], bool], pygame.Surface] = {}
+_fonts: dict[tuple[tuple[str, ...], int], pygame.font.Font] = {}
+_sounds: dict[tuple[str, ...], pygame.mixer.Sound] = {}
+
+_PLACEHOLDER_SIZE = (32, 32)
+_PLACEHOLDER_COLOR = (255, 0, 255)
+
+
+def _placeholder() -> pygame.Surface:
+ surface = pygame.Surface(_PLACEHOLDER_SIZE)
+ surface.fill(_PLACEHOLDER_COLOR)
+ return surface
+
+
+def image(*parts: str, alpha: bool = True) -> pygame.Surface:
+ """Load and cache an image. Missing files become a magenta placeholder.
+
+ Set ``alpha=False`` for fully opaque images (uses ``convert`` instead of
+ ``convert_alpha``), matching the original's per-image choice.
+ """
+ key = (parts, alpha)
+ cached = _images.get(key)
+ if cached is not None:
+ return cached
+
+ path = asset_path(*parts)
+ try:
+ surface = pygame.image.load(str(path))
+ except (pygame.error, FileNotFoundError):
+ _log.warning("missing image asset: %s", path)
+ surface = _placeholder()
+ surface = surface.convert_alpha() if alpha else surface.convert()
+ _images[key] = surface
+ return surface
+
+
+def font(name: str, size: int) -> pygame.font.Font:
+ """Load and cache a font from the bundled ``fonts`` directory."""
+ key = ((name,), size)
+ cached = _fonts.get(key)
+ if cached is not None:
+ return cached
+ loaded = pygame.font.Font(str(asset_path("fonts", name)), size)
+ _fonts[key] = loaded
+ return loaded
+
+
+def sound(*parts: str) -> pygame.mixer.Sound:
+ """Load and cache a sound effect."""
+ cached = _sounds.get(parts)
+ if cached is not None:
+ return cached
+ loaded = pygame.mixer.Sound(str(asset_path(*parts)))
+ _sounds[parts] = loaded
+ return loaded
+
+
+def clear_cache() -> None:
+ """Drop all cached assets (e.g. after the display pixel format changes)."""
+ _images.clear()
+ _fonts.clear()
+ _sounds.clear()
diff --git a/src/exit_dash/core/scene.py b/src/exit_dash/core/scene.py
new file mode 100644
index 0000000..9d4142f
--- /dev/null
+++ b/src/exit_dash/core/scene.py
@@ -0,0 +1,133 @@
+"""The scene stack: a small state machine that replaces the original god-method loop.
+
+Each screen (title, options, a level, the editor, game-over) is a :class:`Scene`.
+A scene's :meth:`Scene.update` returns an optional :class:`Transition` telling the
+:class:`SceneManager` how to change the stack — push a screen on top, pop back to the
+previous one, replace the current one, or quit the game.
+"""
+
+from __future__ import annotations
+
+from abc import ABC, abstractmethod
+from dataclasses import dataclass
+from typing import TYPE_CHECKING
+
+if TYPE_CHECKING:
+ import pygame
+
+ from exit_dash.core.input import InputState
+
+
+class Transition:
+ """Base class for the values a scene may return from event/update handlers."""
+
+
+@dataclass(frozen=True)
+class Push(Transition):
+ """Pause the current scene and run ``scene`` on top of it."""
+
+ scene: Scene
+
+
+@dataclass(frozen=True)
+class Pop(Transition):
+ """Leave the current scene and resume the one beneath it, passing ``result`` back."""
+
+ result: object | None = None
+
+
+@dataclass(frozen=True)
+class Replace(Transition):
+ """Swap the current scene for ``scene`` (the current one does not resume)."""
+
+ scene: Scene
+
+
+@dataclass(frozen=True)
+class Quit(Transition):
+ """Tear down the whole stack and exit the game loop."""
+
+
+class Scene(ABC):
+ """One screen of the game. Subclasses override the hooks they need."""
+
+ #: Set by the manager when the scene is pushed; lets a scene start transitions.
+ manager: SceneManager
+
+ def on_enter(self) -> None: # noqa: B027 — optional hook, no-op by default
+ """Called once when the scene is first pushed/replaced onto the stack."""
+
+ def on_exit(self) -> None: # noqa: B027 — optional hook, no-op by default
+ """Called once when the scene is popped/replaced off the stack."""
+
+ def on_resume(self, result: object | None) -> None: # noqa: B027 — optional hook
+ """Called when a scene pushed on top of this one pops back, with its result."""
+
+ def handle_event(self, event: pygame.event.Event) -> Transition | None:
+ """Handle a single pygame event. Return a transition to change the stack."""
+ return None
+
+ @abstractmethod
+ def update(self, dt: float, inp: InputState) -> Transition | None:
+ """Advance the scene by one fixed step (``dt`` seconds)."""
+
+ @abstractmethod
+ def draw(self, surface: pygame.Surface, alpha: float) -> None:
+ """Render the scene. ``alpha`` is the 0..1 interpolation factor (unused for now)."""
+
+
+class SceneManager:
+ """Owns the scene stack and applies the transitions scenes request."""
+
+ def __init__(self, initial: Scene) -> None:
+ self._stack: list[Scene] = []
+ self._running = True
+ self._push(initial)
+
+ @property
+ def running(self) -> bool:
+ return self._running and bool(self._stack)
+
+ @property
+ def current(self) -> Scene:
+ return self._stack[-1]
+
+ def _push(self, scene: Scene) -> None:
+ scene.manager = self
+ self._stack.append(scene)
+ scene.on_enter()
+
+ def apply(self, transition: Transition | None) -> None:
+ """Mutate the stack according to a transition returned by the current scene."""
+ match transition:
+ case None:
+ return
+ case Push(scene=scene):
+ self._push(scene)
+ case Pop(result=result):
+ leaving = self._stack.pop()
+ leaving.on_exit()
+ if self._stack:
+ self.current.on_resume(result)
+ else:
+ self._running = False
+ case Replace(scene=scene):
+ leaving = self._stack.pop()
+ leaving.on_exit()
+ self._push(scene)
+ case Quit():
+ while self._stack:
+ self._stack.pop().on_exit()
+ self._running = False
+
+ def handle_event(self, event: pygame.event.Event) -> None:
+ if self._stack:
+ self.apply(self.current.handle_event(event))
+
+ def update(self, dt: float, inp: InputState) -> None:
+ if self._stack:
+ self.apply(self.current.update(dt, inp))
+
+ def draw(self, surface: pygame.Surface, alpha: float) -> None:
+ if self._stack:
+ self.current.draw(surface, alpha)
diff --git a/src/exit_dash/core/settings.py b/src/exit_dash/core/settings.py
new file mode 100644
index 0000000..f52c9e0
--- /dev/null
+++ b/src/exit_dash/core/settings.py
@@ -0,0 +1,102 @@
+"""Game settings: a typed dataclass persisted as JSON in the user's config directory.
+
+Replaces the original fragile positional ``settings.cfg``. On first run the old file (if
+present) is migrated to JSON; thereafter JSON is the source of truth. Unknown keys are
+ignored and missing keys fall back to defaults, so the format can evolve safely.
+
+The obsolete ``stableFPS`` and FPS-preset options are dropped — they only existed to tame
+a variable-rate loop the fixed-timestep engine no longer has.
+"""
+
+from __future__ import annotations
+
+import json
+from dataclasses import asdict, dataclass, fields
+from pathlib import Path
+from typing import Any
+
+from exit_dash.core.paths import user_config_dir
+
+SETTINGS_FILENAME = "settings.json"
+LEGACY_FILENAME = "settings.cfg"
+
+
+@dataclass
+class Settings:
+ """User-configurable game settings."""
+
+ developer_mode: bool = False
+ antialiasing: bool = True
+ decorations: bool = True
+ music_enabled: bool = True
+ fullscreen: bool = True
+ volume: float = 0.5
+ resolution: str = "1080p"
+ vsync: bool = True
+
+ def to_dict(self) -> dict[str, Any]:
+ return asdict(self)
+
+ @classmethod
+ def from_dict(cls, data: dict[str, Any]) -> Settings:
+ """Build from a dict, ignoring unknown keys and defaulting missing ones."""
+ known = {f.name for f in fields(cls)}
+ return cls(**{k: v for k, v in data.items() if k in known})
+
+ @classmethod
+ def from_legacy_cfg(cls, text: str) -> Settings:
+ """Parse the original positional ``settings.cfg`` text into :class:`Settings`.
+
+ Layout (after the header line): developerMode, antialiasing, stableFPS,
+ decorations, doPlayMusic, fullscreen, volume, resolution. Booleans were stored as
+ ``True``/``False`` and read with a substring test.
+ """
+ body = text.replace("\r\n", "\n").replace("\r", "\n").split("\n")[1:]
+
+ def as_bool(value: str) -> bool:
+ return "True" in value
+
+ return cls(
+ developer_mode=as_bool(body[0]),
+ antialiasing=as_bool(body[1]),
+ # body[2] was stableFPS — dropped.
+ decorations=as_bool(body[3]),
+ music_enabled=as_bool(body[4]),
+ fullscreen=as_bool(body[5]),
+ volume=float(body[6]),
+ resolution=body[7].strip(),
+ )
+
+
+def settings_file(config_dir: Path | None = None) -> Path:
+ return (config_dir or user_config_dir()) / SETTINGS_FILENAME
+
+
+def save_settings(settings: Settings, config_dir: Path | None = None) -> None:
+ """Persist settings as pretty JSON in the config directory."""
+ directory = config_dir or user_config_dir()
+ directory.mkdir(parents=True, exist_ok=True)
+ (directory / SETTINGS_FILENAME).write_text(
+ json.dumps(settings.to_dict(), indent=2) + "\n", encoding="utf-8"
+ )
+
+
+def load_settings(config_dir: Path | None = None, legacy_path: Path | None = None) -> Settings:
+ """Load settings, migrating a legacy ``settings.cfg`` on first run.
+
+ Resolution order: existing ``settings.json`` -> legacy ``.cfg`` (migrated and saved as
+ JSON) -> built-in defaults (saved as JSON).
+ """
+ directory = config_dir or user_config_dir()
+ json_path = directory / SETTINGS_FILENAME
+ if json_path.is_file():
+ return Settings.from_dict(json.loads(json_path.read_text(encoding="utf-8")))
+
+ legacy = legacy_path if legacy_path is not None else directory / LEGACY_FILENAME
+ if legacy.is_file():
+ settings = Settings.from_legacy_cfg(legacy.read_text(encoding="utf-8"))
+ else:
+ settings = Settings()
+
+ save_settings(settings, config_dir=directory)
+ return settings
diff --git a/src/exit_dash/entities/__init__.py b/src/exit_dash/entities/__init__.py
new file mode 100644
index 0000000..1c6ce3f
--- /dev/null
+++ b/src/exit_dash/entities/__init__.py
@@ -0,0 +1,3 @@
+"""Game entities: the player, enemies and world objects (sprites)."""
+
+from __future__ import annotations
diff --git a/src/exit_dash/entities/background.py b/src/exit_dash/entities/background.py
new file mode 100644
index 0000000..b7dccde
--- /dev/null
+++ b/src/exit_dash/entities/background.py
@@ -0,0 +1,63 @@
+"""Parallax background: two copies of an image (one flipped) tiled for seamless wrap."""
+
+from __future__ import annotations
+
+import math
+
+import pygame
+
+
+class Background:
+ def __init__(
+ self,
+ image: pygame.Surface,
+ screen_width: int,
+ screen_height: int,
+ inverted_image: pygame.Surface | None = None,
+ default_position: tuple[float, float] = (0, 0),
+ ) -> None:
+ self.image = image
+ self.inverted_image = inverted_image or pygame.transform.flip(image, True, False).convert()
+ self.target_width = screen_width
+ self.target_height = screen_height
+
+ self.width = self.image.get_width()
+ self.height = self.image.get_height()
+ self.x, self.y = default_position
+
+ self._scale_images(precise=False)
+ self.inverted_x = self.x + self.width
+
+ def _scale_images(self, precise: bool = True) -> None:
+ too_small = self.width < self.target_width or self.height < self.target_height
+ if precise and too_small:
+ width_factor = math.ceil(self.target_width / self.width)
+ height_factor = math.ceil(self.target_height / self.height)
+ factor = max(width_factor, height_factor)
+ size = (self.width * factor, self.height * factor)
+ self.image = pygame.transform.smoothscale(self.image, size)
+ self.inverted_image = pygame.transform.smoothscale(self.inverted_image, size)
+ elif too_small:
+ while self.height < self.target_height:
+ self.image = pygame.transform.scale2x(self.image)
+ self.inverted_image = pygame.transform.scale2x(self.inverted_image)
+ self.width = self.image.get_width()
+ self.height = self.image.get_height()
+
+ def update(self, surface: pygame.Surface) -> None:
+ if self.x < -self.width:
+ self.x = self.width
+ elif self.x > self.width:
+ self.x = -self.width
+ if self.inverted_x < -self.width:
+ self.inverted_x = self.width
+ elif self.inverted_x > self.width:
+ self.inverted_x = -self.width
+
+ if self.x > self.inverted_x:
+ self.x = self.inverted_x + self.width
+ elif self.inverted_x > self.x:
+ self.inverted_x = self.x + self.width
+
+ surface.blit(self.image, (self.x, 0))
+ surface.blit(self.inverted_image, (self.inverted_x, 0))
diff --git a/src/exit_dash/entities/block.py b/src/exit_dash/entities/block.py
new file mode 100644
index 0000000..e250f1d
--- /dev/null
+++ b/src/exit_dash/entities/block.py
@@ -0,0 +1,140 @@
+"""Block: a bonus box (coin / regular / explosive / locked).
+
+Hitting a block disables it and may reveal a coin, a star, a key, or trigger an
+explosion. Supports ``block[0]`` (its bounding tuple) and ``block[i>0]`` (coin-position
+components) indexing, relied on by the collision and falling-spike code.
+"""
+
+from __future__ import annotations
+
+import math
+from random import randint
+from typing import TYPE_CHECKING, Literal
+
+import pygame
+
+from exit_dash.core import resources
+
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+ from exit_dash.entities.key import Key
+
+BlockForm = Literal["locked", "coin", "regular", "explosive"]
+_ENV = ("environment", "main")
+
+
+class Block:
+ def __init__(self, x: float, y: float, form: BlockForm) -> None:
+ self.form: BlockForm = form
+ self.x = float(x)
+ self.y = float(y)
+
+ self.locked_image = resources.image(*_ENV, "lock_blue.png")
+ self.coin_block_image = resources.image(*_ENV, "boxCoin.png")
+ self.coin_block_used_image = resources.image(*_ENV, "boxCoin_disabled.png")
+ self.explosive_image = resources.image(*_ENV, "boxExplosive.png")
+ self.explosive_used_image = resources.image(*_ENV, "boxExplosive_disabled.png")
+ self.regular_image = resources.image(*_ENV, "boxItem.png")
+ self.regular_used_image = resources.image(*_ENV, "boxItem_disabled.png")
+ self.explosion = [
+ pygame.transform.scale2x(resources.image(*_ENV, f"explosion{i}.png")) for i in range(3)
+ ]
+ self.width = self.regular_image.get_width()
+ self.height = self.regular_image.get_height()
+ self.image = self.regular_image
+
+ # Sound effects need a mixer; tolerate headless/no-audio environments.
+ self._explosion_sfx = (
+ resources.sound("sounds", "synthetic_explosion_1.ogg")
+ if pygame.mixer.get_init()
+ else None
+ )
+
+ self.coin_image = resources.image(*_ENV, "coinGold.png")
+ self.coin_width = self.coin_image.get_width()
+ self.coin_height = self.coin_image.get_height()
+ self.coin_pos = self._coin_position()
+ self.coin_visible = False
+
+ self.star_image = resources.image("items", "star.png")
+ self.star_width = self.star_image.get_width()
+ self.star_height = self.star_image.get_height()
+
+ self.disabled = False
+ self.will_explode = form == "explosive"
+ self.yields_star = False
+ self.explosion_step = 0
+
+ def _coin_position(self) -> list[float]:
+ return [
+ self.x - 15,
+ self.y - self.coin_height + 10,
+ self.x + self.coin_width - 15,
+ self.y + 10,
+ ]
+
+ def __getitem__(self, i: int) -> tuple[float, float, float, float] | float:
+ if i == 0:
+ return (self.x, self.y, self.x + self.width, self.y + self.height)
+ return self.coin_pos[i - 1]
+
+ @staticmethod
+ def distance(p0: tuple[float, float], p1: tuple[float, float]) -> float:
+ return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
+
+ def update_state(self) -> None:
+ self.coin_pos = self._coin_position()
+
+ def disable(self) -> None:
+ self.coin_visible = True
+ self.disabled = True
+
+ def kill_coin(self) -> None:
+ self.coin_visible = False
+
+ def _block_image(self) -> pygame.Surface:
+ match (self.form, self.disabled):
+ case ("locked", _):
+ return self.locked_image
+ case ("coin", True):
+ return self.coin_block_used_image
+ case ("coin", False):
+ return self.coin_block_image
+ case ("regular", True):
+ return self.regular_used_image
+ case ("regular", False):
+ return self.regular_image
+ case ("explosive", True):
+ return self.explosive_used_image
+ case ("explosive", False):
+ return self.explosive_image
+ case _:
+ return self.regular_image
+
+ def draw(self, keys: Sequence[Key], surface: pygame.Surface) -> None:
+ surface.blit(self._block_image(), (self.x, self.y))
+
+ if self.form == "coin" and self.coin_visible:
+ surface.blit(self.coin_image, (self.coin_pos[0], self.coin_pos[1]))
+ if self.form == "regular":
+ for key in keys:
+ if (
+ self.coin_visible
+ and self.disabled
+ and self.distance((self.x, self.y), (key.x, key.y)) < 1.5 * key.height
+ ):
+ key.visible = True
+ self.coin_visible = False
+ if self.will_explode and self.disabled:
+ if randint(0, 2) == 0 and self.explosion_step < len(self.explosion):
+ self.explosion_step += 1
+ if self.explosion_step < len(self.explosion):
+ surface.blit(self.explosion[self.explosion_step], (self.x - 65, self.y - 135))
+ if self._explosion_sfx is not None:
+ self._explosion_sfx.play()
+ if self.yields_star and self.disabled and self.coin_visible:
+ surface.blit(self.star_image, (self.coin_pos[0] + 20, self.coin_pos[1] + 30))
+
+ def get_rect(self) -> pygame.Rect:
+ return pygame.Rect(int(self.x), int(self.y), self.width, self.height)
diff --git a/src/exit_dash/entities/character.py b/src/exit_dash/entities/character.py
new file mode 100644
index 0000000..1174be9
--- /dev/null
+++ b/src/exit_dash/entities/character.py
@@ -0,0 +1,386 @@
+"""Character: the shared physics/collision base for the player and enemies.
+
+The motion and collision arithmetic is preserved verbatim from the original game so the
+feel is unchanged; only the structure, names and types are modernized. Positions are
+floats (sub-pixel precision); the integer ``rect`` is derived for drawing. The simulation
+runs at a fixed timestep, so per-step velocity/gravity constants carry over directly and
+animation/flash timing is keyed to the fixed rate (no longer frame-rate dependent).
+"""
+
+from __future__ import annotations
+
+import math
+from typing import TYPE_CHECKING
+
+import pygame
+
+from exit_dash.core import resources
+from exit_dash.core.constants import FIXED_FPS
+
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+ from exit_dash.entities.block import Block
+ from exit_dash.entities.enemy import AICharacter
+ from exit_dash.entities.platform import Platform
+ from exit_dash.entities.pool import Pool
+ from exit_dash.entities.torch import Torch
+
+_WALK_FRAMES = 10
+_FLASH_SECONDS = 4
+_HEALTH_BY_CHARACTER = {1: 4, 2: 6}
+_DEFAULT_HEALTH = 10
+
+
+class Character:
+ GRAVITY = 2.5
+ JUMP_SPEED = 30
+ RUN_SPEED = 5
+ PLATFORM_TOLERANCE = 15
+
+ def __init__(self, x: float, y: float, which_char: int = 1, vx: float = 0.0, vy: float = 0.0):
+ self.x = float(x)
+ self.y = float(y)
+ self.vx = float(vx)
+ self.vy = float(vy)
+
+ self.gravity: float = self.GRAVITY
+ self.jump_speed: float = self.JUMP_SPEED
+ self.run_speed: float = self.RUN_SPEED
+
+ self.walk_frame = 0
+ self.mob_jumping = False
+ self.underwater = False
+ self.moving_laterally = False
+ self.jumping = False
+ self.can_jump = False
+ self.on_ground = False
+ self.has_key = False
+ self.direction = 0 # 0 = facing left, 1 = facing right
+ self.current_platform = 0
+ self.lowest_platform = 0
+
+ self.health: float = _HEALTH_BY_CHARACTER.get(which_char, _DEFAULT_HEALTH)
+ self.recovery_health: float = self.health
+ self.flashing = False
+ self.flash_timer = 0
+ self.coins = 0
+
+ self.which_char = which_char
+ self.visible = True
+ self.ducking = False
+ self.platform_tolerance = self.PLATFORM_TOLERANCE
+
+ self._load_appearance(which_char)
+ self._recompute_jump_kinematics()
+
+ # -- appearance -------------------------------------------------------------------
+
+ def _load_appearance(self, which_char: int) -> None:
+ prefix = ("character", "main")
+ stem = f"p{which_char}"
+ self.standing_image = resources.image(*prefix, f"{stem}_front.png")
+ self.jumping_image_left = resources.image(*prefix, f"{stem}_jump_l.png")
+ self.jumping_image_right = resources.image(*prefix, f"{stem}_jump.png")
+ self.duck_left = resources.image(*prefix, f"{stem}_duck_l.png")
+ self.duck_right = resources.image(*prefix, f"{stem}_duck.png")
+ self.duck_height = self.duck_left.get_height()
+ self.width = self.standing_image.get_width()
+ self.height = self.standing_image.get_height()
+ self.image = self.standing_image
+
+ self.walk_images_right: list[pygame.Surface] = []
+ self.walk_images_left: list[pygame.Surface] = []
+ for i in range(1, _WALK_FRAMES + 1):
+ frame = resources.image(*prefix, f"{stem}_walk", "PNG", f"{stem}_walk{i}.png")
+ self.walk_images_right.append(frame)
+ self.walk_images_left.append(pygame.transform.flip(frame, True, False))
+
+ def _recompute_jump_kinematics(self) -> None:
+ self.jump_time = float(self.jump_speed) / self.gravity
+ self.max_jump_height = math.floor(0.5 * self.jump_speed * self.jump_time)
+ self.max_jump_length = math.floor(self.run_speed * self.jump_time)
+
+ # -- motion -----------------------------------------------------------------------
+
+ def platform_init(self, platforms: Sequence[Platform]) -> None:
+ self.determine_lowest_platform(platforms)
+
+ def determine_lowest_platform(self, platforms: Sequence[Platform]) -> None:
+ for index in range(len(platforms)):
+ if platforms[index].y > platforms[self.lowest_platform].y:
+ self.lowest_platform = index
+
+ def jump(self, intensity: float = 1.0) -> None:
+ """Set upward velocity for a jump (does not check whether jumping is allowed)."""
+ self.vy = math.floor(-intensity * self.jump_speed)
+
+ def update_motion(self, platforms: Sequence[Platform]) -> None:
+ self.x += self.vx
+ self.y += self.vy
+ self._recompute_jump_kinematics()
+
+ terminal = platforms[0].height
+ if self.vy >= terminal:
+ self.vy = terminal - 5
+ if not self.on_ground and self.vy >= terminal - 5:
+ self.dispose()
+
+ if self.on_ground:
+ self.vy = 0
+ self.mob_jumping = False
+ else:
+ self.vy += self.gravity
+
+ # -- collision --------------------------------------------------------------------
+
+ def block_collide(self, blocks: Sequence[Block]) -> bool:
+ left = self.x + 10
+ right = self.x + self.width - 10
+ top = self.y
+ bottom = self.y + self.height
+
+ for block in blocks:
+ if not (0 <= block.x <= 2000 and 0 <= block.y <= 2000):
+ continue
+ block_left = block.x
+ block_right = block.x + block.width
+ block_top = block.y
+ block_bottom = block.y + block.height
+ block_middle_x = int(0.5 * block_left + 0.5 * block_right)
+ block_middle_y = int(0.5 * block_bottom + 0.5 * block_top)
+
+ below = (
+ right >= block_left
+ and left <= block_right
+ and block_middle_y - 20 <= top <= block_bottom
+ )
+ left_of = (
+ block_left <= right < block_middle_x and bottom > block_top and top < block_bottom
+ )
+ right_of = (
+ block_right >= left > block_middle_x and bottom > block_top and top < block_bottom
+ )
+ above = (
+ right >= block_left + 10
+ and left <= block_right - 10
+ and block_bottom > bottom >= block_top
+ )
+
+ hit = False
+ if below and self.vy <= 0:
+ self.y = block.y + block.height + 1
+ self.vy = 0
+ hit = True
+ elif left_of:
+ self.x = block_left - self.width
+ self.vx *= -1
+ return True
+ elif right_of:
+ self.x = block_right
+ self.vx *= -1
+ return True
+ elif above and self.vy >= 0:
+ self.y = block_top - self.height
+ self.on_ground = True
+ if not block.disabled and hit:
+ block.disable()
+ if block.will_explode and not self.flashing:
+ self.health -= 1
+ self.flashing = True
+ return False
+
+ def coin_collide(self, blocks: Sequence[Block]) -> None:
+ self_rect = self.get_rect()
+ for block in blocks:
+ if not (0 <= block.x <= 2000 and 0 <= block.y <= 2000):
+ continue
+ coin_pos = block.coin_pos
+ coin_rect = pygame.Rect(coin_pos[0], coin_pos[1], block.coin_width, block.coin_height)
+ star_rect = pygame.Rect(coin_pos[0], coin_pos[1], block.star_width, block.star_height)
+ if block.coin_visible and self_rect.colliderect(coin_rect) and not block.yields_star:
+ self.coins += 1
+ block.kill_coin()
+ elif block.coin_visible and self_rect.colliderect(star_rect):
+ self.coins += 10
+ self.health += 2
+ block.kill_coin()
+
+ def platform_collide(self, platforms: Sequence[Platform], pool: Pool | None) -> None:
+ tol = self.platform_tolerance
+ for i in range(len(platforms)):
+ p = platforms[i]
+ if (
+ self.x + self.width >= p[0] + tol
+ and self.x <= p[2] - tol
+ and p[1] <= self.y + self.height <= p[3] + 35
+ and self.vy >= 0
+ ):
+ self.y = p[1] - self.height
+ self.on_ground = True
+ self.current_platform = i
+ if ( # noqa: SIM102 — guard then landing-rule reads clearer than one boolean
+ self.x + self.width >= p[0] + tol
+ and self.x <= p[2] - tol
+ and p[3] >= self.y >= p[1] - tol
+ and self.vy < 0
+ ):
+ if (
+ self.x + self.width >= p[0] + p.tile_width and self.x <= p[2] - p.tile_width
+ ) or self.y <= p[1] + tol + 30:
+ self.y = p[3]
+ self.vy = 0
+
+ def ai_collide(self, ai_characters: Sequence[AICharacter]) -> None:
+ if self in ai_characters:
+ return
+ for ai in ai_characters:
+ if not (0 <= ai.x <= 2000 and 0 <= ai.y <= 2000):
+ continue
+ if self.get_rect().colliderect(ai.get_rect()) and ai.is_alive:
+ if self.vy > 0 and ai.mob_type != "fly":
+ ai.health -= 5 - self.which_char
+ self.jump(0.75)
+ self.mob_jumping = True
+ self.on_ground = False
+ elif self.vy > 0:
+ self.jump(0.8)
+ self.on_ground = False
+ ai.is_alive = False
+ elif not self.mob_jumping and self.flash_timer == 0:
+ self.health -= 1
+ self.flashing = True
+
+ def pool_collide(self, platforms: Sequence[Platform], pool: Pool | None) -> None:
+ if not pool:
+ return
+ current = platforms[self.current_platform]
+ if int(current[0]) <= self.x < int(current[2]):
+ return
+
+ left_x = self.x
+ right_x = self.x + self.width
+ bottom_y = self.y + self.height
+
+ if (
+ pool.y <= bottom_y <= pool.y + pool.tile_width
+ and (
+ (right_x - 10 >= pool.x and left_x + 10 <= pool.pool_start_x + pool.tile_width)
+ or (right_x - 10 >= pool.pool_end_x and left_x + 10 <= pool.x + pool.width)
+ )
+ and self.vy >= 0
+ ):
+ self.on_ground = True
+ self.y = pool.y - self.height
+ if (
+ left_x + 10 >= pool.pool_start_x
+ and right_x - 10 <= pool.pool_end_x + pool.tile_width
+ and pool.y + pool.height <= bottom_y <= pool.y + pool.height + pool.tile_width
+ and self.vy >= 0
+ ):
+ self.on_ground = True
+ self.y = pool.y + pool.height - self.height
+ if (
+ pool.pool_start_x + pool.tile_width >= left_x >= pool.pool_start_x
+ and pool.y < bottom_y <= pool.y + pool.height
+ ):
+ self.x = pool.pool_start_x + pool.tile_width
+ self.vx *= -1
+ if (
+ pool.pool_end_x <= right_x <= pool.pool_end_x + pool.tile_width
+ and pool.y < bottom_y <= pool.y + pool.height
+ ):
+ self.x = pool.pool_end_x - self.width
+ self.vx *= -1
+ if (
+ right_x >= pool.pool_start_x
+ and left_x <= pool.pool_end_x
+ and pool.y + pool.height >= bottom_y > pool.y
+ ):
+ self.underwater = True
+
+ def torch_collide(self, torches: Sequence[Torch] | None) -> None:
+ if not torches:
+ return
+ for torch in torches:
+ if self.get_rect().colliderect(torch.get_rect()):
+ torch.burning = True
+
+ def prep_collision_detection(self) -> None:
+ self.on_ground = False
+ self.underwater = False
+
+ def collide(
+ self,
+ platforms: Sequence[Platform],
+ blocks: Sequence[Block],
+ ai_characters: Sequence[AICharacter],
+ pool: Pool | None,
+ torches: Sequence[Torch] | None,
+ ) -> None:
+ self.prep_collision_detection()
+ self.block_collide(blocks)
+ self.coin_collide(blocks)
+ self.platform_collide(platforms, pool)
+ self.ai_collide(ai_characters)
+ self.pool_collide(platforms, pool)
+ self.torch_collide(torches)
+
+ # -- per-step orchestration -------------------------------------------------------
+
+ def step(
+ self,
+ platforms: Sequence[Platform],
+ blocks: Sequence[Block],
+ ai_characters: Sequence[AICharacter],
+ pool: Pool | None,
+ torches: Sequence[Torch] | None = None,
+ ) -> None:
+ """Advance one fixed timestep: motion, collision, then animation."""
+ if not self.visible:
+ return
+ self.update_motion(platforms)
+ self.collide(platforms, blocks, ai_characters, pool, torches)
+ self.advance_animation()
+
+ def advance_animation(self) -> None:
+ self.walk_frame = (self.walk_frame + 1) % _WALK_FRAMES
+ if self.flashing:
+ self.flash_timer += 1
+ else:
+ self.flash_timer = 0
+ if self.flash_timer >= FIXED_FPS * _FLASH_SECONDS:
+ self.flashing = False
+
+ # -- rendering --------------------------------------------------------------------
+
+ @property
+ def _visible_this_frame(self) -> bool:
+ # During invincibility the character blinks (visible ~75% of each second).
+ return self.flash_timer == 0 or self.flash_timer % FIXED_FPS < (FIXED_FPS * 0.75)
+
+ def _current_frame(self) -> tuple[pygame.Surface, tuple[float, float]]:
+ if self.ducking:
+ image = self.duck_left if self.direction == 0 else self.duck_right
+ return image, (self.x, self.y + self.height - self.duck_height)
+ if self.jumping:
+ image = self.jumping_image_right if self.direction == 1 else self.jumping_image_left
+ return image, (self.x, self.y)
+ if self.on_ground and self.moving_laterally:
+ frames = self.walk_images_right if self.direction == 1 else self.walk_images_left
+ return frames[self.walk_frame], (self.x, self.y)
+ return self.standing_image, (self.x, self.y)
+
+ def draw(self, surface: pygame.Surface) -> None:
+ if not self.visible or not self._visible_this_frame:
+ return
+ image, position = self._current_frame()
+ surface.blit(image, position)
+
+ def get_rect(self) -> pygame.Rect:
+ return pygame.Rect(
+ int(self.x + 10), int(self.y + 5), int(self.width - 10), int(self.height - 5)
+ )
+
+ def dispose(self) -> None:
+ self.visible = False
diff --git a/src/exit_dash/entities/checkpoint.py b/src/exit_dash/entities/checkpoint.py
new file mode 100644
index 0000000..f267514
--- /dev/null
+++ b/src/exit_dash/entities/checkpoint.py
@@ -0,0 +1,24 @@
+"""Checkpoint: a fence the player touches to set their respawn point."""
+
+from __future__ import annotations
+
+import pygame
+
+from exit_dash.core import resources
+
+
+class Checkpoint:
+ def __init__(self, x: float, y: float, is_broken: bool = False) -> None:
+ self.x = float(x)
+ self.y = float(y)
+ self.image = resources.image("environment", "main", "fence.png")
+ self.image_broken = resources.image("environment", "main", "fenceBroken.png")
+ self.width = self.image.get_width()
+ self.height = self.image.get_height()
+ self.broken = is_broken
+
+ def draw(self, surface: pygame.Surface) -> None:
+ surface.blit(self.image_broken if self.broken else self.image, (self.x, self.y))
+
+ def get_rect(self) -> pygame.Rect:
+ return pygame.Rect(int(self.x), int(self.y), self.width, self.height)
diff --git a/src/exit_dash/entities/door.py b/src/exit_dash/entities/door.py
new file mode 100644
index 0000000..dc55837
--- /dev/null
+++ b/src/exit_dash/entities/door.py
@@ -0,0 +1,55 @@
+"""Door: the level exit. Unlocks once the player has the key and is standing in it."""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+import pygame
+
+from exit_dash.core import resources
+
+if TYPE_CHECKING:
+ from exit_dash.entities.character import Character
+
+_ENV = ("environment", "main")
+_TOP_BLANK_SPACE = 30
+
+
+class Door:
+ def __init__(self, x: float, y: float) -> None:
+ self.x = float(x)
+ self.y = float(y)
+ self.locked = True
+
+ self.image_bottom = resources.image(*_ENV, "door_openMid.png")
+ self.image_top = resources.image(*_ENV, "door_openTop.png")
+ self.image_bottom_locked = resources.image(*_ENV, "door_closedMid.png")
+ self.image_top_locked = resources.image(*_ENV, "door_closedTop.png")
+ self.bottom_height = self.image_bottom.get_height()
+ self.top_height = self.image_top.get_height()
+ self.top_blank_space = _TOP_BLANK_SPACE
+ self.height = self.bottom_height + self.top_height - self.top_blank_space
+ self.width = self.image_bottom.get_width()
+ self.y -= self.bottom_height + self.top_height
+ self.image = self.image_top
+
+ def update(self, main_char: Character, unlockable: bool = True) -> bool:
+ """Update lock state; return True when the player exits through the door."""
+ char_rect = pygame.Rect(
+ int(main_char.x), int(main_char.y), int(main_char.width), int(main_char.height)
+ )
+ in_door = char_rect.colliderect(self.get_rect())
+ if (in_door and main_char.has_key) or not unlockable:
+ self.locked = False
+ return not self.locked and in_door and unlockable
+
+ def draw(self, surface: pygame.Surface) -> None:
+ if self.locked:
+ surface.blit(self.image_top_locked, (self.x, self.y))
+ surface.blit(self.image_bottom_locked, (self.x, self.y + self.top_height))
+ else:
+ surface.blit(self.image_top, (self.x, self.y))
+ surface.blit(self.image_bottom, (self.x, self.y + self.top_height))
+
+ def get_rect(self) -> pygame.Rect:
+ return pygame.Rect(int(self.x), int(self.y + self.top_blank_space), self.width, self.height)
diff --git a/src/exit_dash/entities/enemy.py b/src/exit_dash/entities/enemy.py
new file mode 100644
index 0000000..ff56934
--- /dev/null
+++ b/src/exit_dash/entities/enemy.py
@@ -0,0 +1,249 @@
+"""AICharacter: enemies (slime, snail, fly, fish) with simple patrol AI.
+
+Behaviour is ported verbatim from the original, including its quirks (e.g. the
+``slime or snail and ...`` operator precedence, which makes slimes always re-plan and
+snails only sometimes). Enemies reuse :class:`Character`'s physics; their own sprites and
+AI are layered on top.
+"""
+
+from __future__ import annotations
+
+import math
+from random import randint
+from typing import TYPE_CHECKING, Literal
+
+import pygame
+
+from exit_dash.entities.character import Character
+
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+ from exit_dash.entities.block import Block
+ from exit_dash.entities.platform import Platform
+ from exit_dash.entities.pool import Pool
+ from exit_dash.entities.torch import Torch
+
+MobType = Literal["slime", "snail", "fly", "fish"]
+_EXPLOSION_RADIUS = 400
+
+
+class AICharacter(Character):
+ def __init__(
+ self,
+ x: float,
+ y: float,
+ vx: float,
+ vy: float,
+ properties: tuple[MobType, int, int] = ("slime", -1, -1),
+ ) -> None:
+ self.mob_type: MobType = properties[0]
+ # Patrol bounds shift with the world camera, so they hold floats; -1 means "no limit".
+ self.limit: list[float] = [properties[1], properties[2]]
+
+ super().__init__(x, y, which_char=1, vx=vx, vy=vy)
+
+ self.colour = "Blue"
+ if self.mob_type == "slime" and randint(0, 1) == 0:
+ self.colour = "Green"
+ self._load_mob_images()
+
+ self.image_l1: pygame.Surface | None = None
+ self.image_l2: pygame.Surface | None = None
+ self.image_r1: pygame.Surface | None = None
+ self.image_r2: pygame.Surface | None = None
+ self.image_dl: pygame.Surface | None = None
+ self.image_dr: pygame.Surface | None = None
+ self.dead_width = 0
+ self.dead_height = 0
+
+ self.original_height = y
+ self.is_alive = True
+ self.health = 1
+ self.gravity = 1
+ self.run_speed = abs(self.vx)
+ self.current_step = 0
+ self.taken_action = False
+ self.update_frequency = 2
+
+ def _load_mob_images(self) -> None:
+ from exit_dash.core import resources
+
+ slime = ("enemies", "slime")
+ other = ("enemies", "other")
+ fly = ("enemies", "fly")
+ self.slime_dl = resources.image(*slime, f"slime{self.colour}_squashed.png")
+ self.slime_dr = resources.image(*slime, f"slime{self.colour}_squashedR.png")
+ self.slime_l = resources.image(*slime, f"slime{self.colour}_walk.png")
+ self.slime_r = resources.image(*slime, f"slime{self.colour}_walkR.png")
+ self.fly_dl = resources.image(*fly, "fly_dead.png")
+ self.fly_dr = resources.image(*fly, "fly_dead_r.png")
+ self.fly_l = resources.image(*fly, "fly_fly.png")
+ self.fly_r = resources.image(*fly, "fly_fly_r.png")
+ self.fish_dl = resources.image(*other, "fishGreen_dead.png")
+ self.fish_dr = resources.image(*other, "fishGreen_dead_r.png")
+ self.fish_l = resources.image(*other, "fishGreen_swim.png")
+ self.fish_r = resources.image(*other, "fishGreen_swim_r.png")
+ self.snail_l1 = resources.image(*other, "snailWalk1.png")
+ self.snail_l2 = resources.image(*other, "snailWalk2.png")
+ self.snail_r1 = resources.image(*other, "snailWalk1R.png")
+ self.snail_r2 = resources.image(*other, "snailWalk2R.png")
+ self.snail_dl = resources.image(*other, "snailShell.png")
+ self.snail_dr = resources.image(*other, "snailShellR.png")
+
+ @staticmethod
+ def distance(p0: tuple[float, float], p1: tuple[float, float]) -> float:
+ return math.sqrt((p0[0] - p1[0]) ** 2 + (p0[1] - p1[1]) ** 2)
+
+ def update_ai(self, platforms: Sequence[Platform], blocks: Sequence[Block]) -> None:
+ self.x += self.vx
+ self.y += self.vy
+
+ if self.vx > 0:
+ self.direction = 1
+ elif self.vx < 0:
+ self.direction = 0
+
+ if self.health <= 0:
+ self.is_alive = False
+
+ if self.vy >= platforms[0].height:
+ self.vy = platforms[0].height - 5
+ if (
+ not self.on_ground
+ and self.vy >= platforms[0].height - 15
+ and self.y > platforms[self.lowest_platform][1]
+ ):
+ self.dispose()
+
+ if self.on_ground:
+ self.vy = 0
+ elif ((self.mob_type == "fly" and not self.is_alive) or self.mob_type != "fly") and (
+ self.mob_type != "fish" or (self.mob_type == "fish" and not self.is_alive)
+ ):
+ self.vy += self.gravity
+
+ if self.limit[0] != -1 and self.x <= self.limit[0]:
+ self.x += self.run_speed
+ self.vx = abs(self.vx)
+ if self.limit[1] != -1 and self.x >= self.limit[1]:
+ self.x -= self.run_speed
+ self.vx = -abs(self.vx)
+
+ for block in blocks:
+ distance_from_block = self.distance(
+ (self.x + 0.5 * self.width, self.y + 0.5 * self.height),
+ (block.x + 0.5 * block.width, block.y + 0.5 * block.height),
+ )
+ if (
+ block.disabled
+ and block.will_explode
+ and block.explosion_step == 1
+ and distance_from_block < _EXPLOSION_RADIUS
+ ):
+ self.health = 0
+
+ if self.mob_type in ("slime", "snail"):
+ self._avoid_falling_off_lowest(platforms)
+
+ # NOTE: the original precedence is preserved: slimes always re-plan, snails sometimes.
+ if self.mob_type == "slime" or (
+ self.mob_type == "snail" and randint(0, 10 - self.update_frequency) == 0
+ ):
+ self._replan_ground_patrol(platforms)
+ elif (
+ self.mob_type == "fly" and self.is_alive and randint(0, 10 - self.update_frequency) == 0
+ ):
+ self._replan_fly_patrol(platforms)
+
+ self.walk_frame = (self.walk_frame + 1) % 2
+
+ def _avoid_falling_off_lowest(self, platforms: Sequence[Platform]) -> None:
+ test_left = self.x - 25
+ test_right = self.x + 25 + self.width
+ lowest = platforms[self.lowest_platform]
+ on_lowest = self.current_platform == self.lowest_platform
+ if on_lowest and test_left <= lowest[0] and self.vx < 0:
+ self.x += self.run_speed
+ self.vx *= -1
+ elif on_lowest and test_right >= lowest[2] and self.vx > 0:
+ self.x -= self.run_speed
+ self.vx *= -1
+
+ def _replan_ground_patrol(self, platforms: Sequence[Platform]) -> None:
+ current = platforms[self.current_platform]
+ current_height = current[1]
+ limit_backup = [self.limit[0], self.limit[1]]
+ self.limit[0] = int(current[0] + 5)
+ self.limit[1] = int(current[2] - 40)
+ below = [p for p in platforms if p[1] > current_height]
+ safe_left = any(p[0] < current[0] < p[2] for p in below)
+ safe_right = any(p[0] < current[2] and p[2] > current[2] for p in below)
+ if safe_left:
+ self.limit[0] = limit_backup[0]
+ if safe_right:
+ self.limit[1] = limit_backup[1]
+
+ def _replan_fly_patrol(self, platforms: Sequence[Platform]) -> None:
+ self.limit[0] = int(platforms[0][0])
+ for p in platforms:
+ if self.x + self.width + 5 >= p[0] and self.x <= p[2] and p[1] <= self.y <= p[3]:
+ self.limit[1] = int(p[0])
+ self.vx *= -1
+ self.x -= self.run_speed
+
+ def step(
+ self,
+ platforms: Sequence[Platform],
+ blocks: Sequence[Block],
+ ai_characters: Sequence[AICharacter],
+ pool: Pool | None,
+ torches: Sequence[Torch] | None = None,
+ ) -> None:
+ """Advance one fixed timestep: collide first, then run AI/motion (original order)."""
+ self.collide(platforms, blocks, ai_characters, pool, torches)
+ self.update_ai(platforms, blocks)
+
+ def _ensure_images(self) -> None:
+ if self.image_l1 is not None:
+ return
+ if self.mob_type == "slime":
+ self.image_l1 = self.image_l2 = self.slime_l
+ self.image_r1 = self.image_r2 = self.slime_r
+ self.image_dl, self.image_dr = self.slime_dl, self.slime_dr
+ elif self.mob_type == "fly":
+ self.image_l1 = self.image_l2 = self.fly_l
+ self.image_r1 = self.image_r2 = self.fly_r
+ self.image_dl, self.image_dr = self.fly_dl, self.fly_dr
+ elif self.mob_type == "fish":
+ self.image_l1 = self.image_l2 = self.fish_l
+ self.image_r1 = self.image_r2 = self.fish_r
+ self.image_dl, self.image_dr = self.fish_dl, self.fish_dr
+ elif self.mob_type == "snail":
+ self.image_l1, self.image_l2 = self.snail_l1, self.snail_l2
+ self.image_r1, self.image_r2 = self.snail_r1, self.snail_r2
+ self.image_dl, self.image_dr = self.snail_dl, self.snail_dr
+
+ def draw(self, surface: pygame.Surface) -> None:
+ if not self.visible:
+ return
+ self._ensure_images()
+ assert self.image_l1 and self.image_dl # for type-checkers; set by _ensure_images
+ self.width = self.image_l1.get_width()
+ self.height = self.image_l1.get_height()
+ self.dead_width = self.image_dl.get_width()
+ self.dead_height = self.image_dl.get_height()
+
+ if self.is_alive and self.walk_frame == 0:
+ image = self.image_r1 if self.direction == 1 else self.image_l1
+ elif self.is_alive:
+ image = self.image_r2 if self.direction == 1 else self.image_l2
+ else:
+ image = self.image_dr if self.direction == 1 else self.image_dl
+ if image is not None:
+ surface.blit(image, (self.x, self.y))
+
+ if not self.is_alive:
+ self.width = self.dead_width
+ self.height = self.dead_height
+ self.vx = 0
diff --git a/src/exit_dash/entities/foliage.py b/src/exit_dash/entities/foliage.py
new file mode 100644
index 0000000..1d4ea14
--- /dev/null
+++ b/src/exit_dash/entities/foliage.py
@@ -0,0 +1,27 @@
+"""BackgroundFoliage: a decorative rock/hill/plant/bush placed near platforms."""
+
+from __future__ import annotations
+
+from random import choice
+
+import pygame
+
+from exit_dash.core import resources
+
+
+class BackgroundFoliage:
+ def __init__(self, x: float, y: float) -> None:
+ self.x = float(x)
+ self.y = float(y)
+ self.images = [
+ resources.image("items", "rock.png"),
+ resources.image("environment", "main", "hill_smallAlt.png"),
+ resources.image("items", "plant.png"),
+ resources.image("items", "bush.png"),
+ ]
+ self.image = choice(self.images)
+ self.width = self.image.get_width()
+ self.height = self.image.get_height()
+
+ def draw(self, surface: pygame.Surface) -> None:
+ surface.blit(self.image, (self.x, self.y))
diff --git a/src/exit_dash/entities/key.py b/src/exit_dash/entities/key.py
new file mode 100644
index 0000000..45526ea
--- /dev/null
+++ b/src/exit_dash/entities/key.py
@@ -0,0 +1,35 @@
+"""Key: collecting it lets the player open the level's door."""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+import pygame
+
+from exit_dash.core import resources
+
+if TYPE_CHECKING:
+ from exit_dash.entities.character import Character
+
+
+class Key:
+ def __init__(self, x: float, y: float, colour: str) -> None:
+ self.x = float(x)
+ self.y = float(y)
+ self.visible = False
+ self.image = resources.image("environment", "main", f"key{colour}.png")
+ self.width = self.image.get_width()
+ self.height = self.image.get_height()
+
+ def update(self, main_char: Character) -> None:
+ key_rect = pygame.Rect(int(self.x), int(self.y), self.width, self.height)
+ char_rect = pygame.Rect(
+ int(main_char.x), int(main_char.y), int(main_char.width), int(main_char.height)
+ )
+ if key_rect.colliderect(char_rect):
+ main_char.has_key = True
+ self.visible = False
+
+ def draw(self, surface: pygame.Surface) -> None:
+ if self.visible:
+ surface.blit(self.image, (self.x, self.y))
diff --git a/src/exit_dash/entities/platform.py b/src/exit_dash/entities/platform.py
new file mode 100644
index 0000000..d08c982
--- /dev/null
+++ b/src/exit_dash/entities/platform.py
@@ -0,0 +1,93 @@
+"""Platform: a tiled, walkable surface.
+
+Supports ``platform[0..3]`` indexing (left, top, right, bottom) because the collision
+code treats platforms like rects — preserved verbatim from the original. The full tiled
+surface is composited once into ``image`` for fast drawing.
+"""
+
+from __future__ import annotations
+
+import pygame
+
+from exit_dash.core import resources
+
+
+class Platform:
+ def __init__(
+ self,
+ x: float,
+ y: float,
+ width: float,
+ *,
+ vx: float = 0.0,
+ vy: float = 0.0,
+ style: str = "grass",
+ ) -> None:
+ self.x = float(x)
+ self.y = float(y)
+ self.vx = vx
+ self.vy = vy
+ self.style = style
+ self.width = float(width)
+ self._correct_reversed_coords()
+
+ tile = resources.image("environment", "main", f"{style}Mid.png")
+ self.tile_width = tile.get_width()
+ # Snap width to a whole number of tiles, as the original did.
+ self.width -= self.width % self.tile_width
+ self.height = tile.get_height()
+
+ left = resources.image("environment", "main", f"{style}CliffLeft.png")
+ right = resources.image("environment", "main", f"{style}CliffRight.png")
+
+ self.image = pygame.Surface((int(self.width), self.height), pygame.SRCALPHA)
+ self.image.blit(left, (0, 0))
+ self.image.blit(right, (int(self.width - self.tile_width), 0))
+ for i in range(self.tile_width, int(self.width - self.tile_width), self.tile_width):
+ self.image.blit(tile, (i, 0))
+
+ def _correct_reversed_coords(self) -> None:
+ if self.width < 0:
+ self.x += self.width
+ self.width *= -1
+
+ def __getitem__(self, i: int) -> float:
+ # 0..3 -> left x, top y, right x, bottom y.
+ if i == 0:
+ return self.x
+ if i == 1:
+ return self.y
+ if i == 2:
+ return self.x + self.width
+ if i == 3:
+ return self.y + self.height
+ return i
+
+ def __setitem__(self, k: int, v: float) -> None:
+ if k == 0:
+ self.x = v
+ elif k == 1:
+ self.y = v
+ elif k == 2:
+ self.x = v - self.width
+ elif k == 3:
+ self.y = v - self.height
+
+ def update_motion(self, borders: tuple[float, float, float, float]) -> None:
+ """Move by velocity, wrapping around the level borders (left, top, right, bottom)."""
+ self.x += self.vx
+ self.y += self.vy
+ if self.x >= borders[2] and self.vx > 0:
+ self.x = borders[0] - self.width
+ elif (self.x - self.width) <= borders[0] and self.vx < 0:
+ self.x = borders[2]
+ elif self.y >= borders[3] and self.vy > 0:
+ self.y = borders[1] - self.height
+ elif (self.y + self.height) <= borders[1] and self.vy < 0:
+ self.y = borders[3]
+
+ def draw(self, surface: pygame.Surface) -> None:
+ surface.blit(self.image, (self.x, self.y))
+
+ def get_rect(self) -> pygame.Rect:
+ return pygame.Rect(int(self.x), int(self.y), int(self.width), int(self.height))
diff --git a/src/exit_dash/entities/player.py b/src/exit_dash/entities/player.py
new file mode 100644
index 0000000..0b73828
--- /dev/null
+++ b/src/exit_dash/entities/player.py
@@ -0,0 +1,314 @@
+"""PlayableCharacter: the player. Adds input-driven movement, the move-the-world camera,
+the HUD, checkpoints, autoscroll and respawning on top of :class:`Character`.
+
+The camera follows the "move the world" model from the original: rather than offsetting
+at draw time, the player stays near screen-centre and every other object's world
+coordinates shift. This is preserved deliberately — the AI patrol limits, parallax
+offsets and the ``0 <= x <= 2000`` activation gates all depend on it.
+"""
+
+from __future__ import annotations
+
+import math
+from random import randint
+from typing import TYPE_CHECKING
+
+import pygame
+
+from exit_dash.core import resources
+from exit_dash.core.input import PlayerInput
+from exit_dash.entities.character import Character
+
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+ from exit_dash.entities.checkpoint import Checkpoint
+ from exit_dash.entities.enemy import AICharacter
+ from exit_dash.entities.platform import Platform
+
+
+class PlayableCharacter(Character):
+ def __init__(self, x: float, y: float, vx: float = 0.0, vy: float = 0.0, which_char: int = 1):
+ super().__init__(x, y, which_char=which_char, vx=vx, vy=vy)
+
+ hud = ("hud",)
+ self.heart_empty = resources.image(*hud, "hud_heartEmpty.png")
+ self.heart_half = resources.image(*hud, "hud_heartHalf.png")
+ self.heart_full = resources.image(*hud, "hud_heartFull.png")
+ self.heart_width = self.heart_full.get_width()
+ self.heart_height = self.heart_full.get_height()
+ self.coin_image = resources.image(*hud, "hud_coins.png")
+ self.coin_image_width = self.coin_image.get_width()
+ self.coins_multiplier = resources.image(*hud, "hud_x.png")
+ self.hud_numbers = [resources.image(*hud, f"hud_{i}.png") for i in range(10)]
+ self.hud_text_width = self.hud_numbers[0].get_width()
+ self.player_icon = resources.image(*hud, f"hud_p{which_char}.png")
+ self.key_icon = resources.image(*hud, "hud_keyBlue.png")
+ self.no_key_icon = resources.image(*hud, "hud_keyBlue_disabled.png")
+
+ self.spacing = 10
+ self.coins = 0
+ self.player_icon_coords = (self.spacing, self.spacing)
+ self.health_interval = self.spacing + self.heart_width
+
+ if which_char == 1:
+ self.jump_speed = 35
+ self.run_speed = 8.5
+ self.lives = 9
+ else:
+ self.jump_speed = 36
+ self.run_speed = 9.0
+ self.lives = 4
+ self._recompute_jump_kinematics()
+
+ self.world_shift_coefficient = 1.5
+ self.cpu_controlled = False
+ self.longest_platform: int | None = None
+ self.respawn_point: list[float] | None = None
+
+ # -- checkpoints ------------------------------------------------------------------
+
+ def collide_checkpoint(self, checkpoints: Sequence[Checkpoint] | None) -> None:
+ if not checkpoints:
+ return
+ for fence in checkpoints:
+ if self.get_rect().colliderect(fence.get_rect()) and not fence.broken:
+ self.respawn_point = [fence.x + 20, fence.y - 70]
+ fence.broken = True
+
+ # -- move-the-world camera --------------------------------------------------------
+
+ def increment_map_h(
+ self,
+ ai_characters: Sequence[AICharacter],
+ movable_objects: Sequence[object],
+ amount: float,
+ move_self: bool = True,
+ ) -> None:
+ if move_self:
+ self.x += amount
+ if self.respawn_point:
+ self.respawn_point[0] += amount
+ for obj in movable_objects:
+ obj.x += amount # type: ignore[attr-defined]
+ if hasattr(obj, "inverted_x"):
+ obj.inverted_x += amount
+ for ai in ai_characters:
+ if ai.limit[0] != -1:
+ ai.limit[0] += amount
+ if ai.limit[1] != -1:
+ ai.limit[1] += amount
+
+ def increment_map_v(
+ self, movable_objects: Sequence[object], amount: float, move_self: bool = True
+ ) -> None:
+ if move_self:
+ self.y += amount
+ if self.respawn_point:
+ self.respawn_point[1] += amount
+ for obj in movable_objects:
+ obj.y += amount # type: ignore[attr-defined]
+
+ def set_map_obj_x(
+ self,
+ ai_characters: Sequence[AICharacter],
+ movable_objects: Sequence[object],
+ platforms: Sequence[Platform],
+ new_x: float,
+ ) -> None:
+ """Shift the whole world so platform 0's left edge lands at ``new_x``."""
+ shift = new_x - platforms[0][0]
+ self.x += shift
+ if self.respawn_point:
+ self.respawn_point[0] += shift
+ for obj in movable_objects:
+ obj.x += shift # type: ignore[attr-defined]
+ for ai in ai_characters:
+ if ai.limit[0] != -1:
+ ai.limit[0] += shift
+ if ai.limit[1] != -1:
+ ai.limit[1] += shift
+
+ def get_next_platform(self, platforms: Sequence[Platform]) -> Platform:
+ assert self.longest_platform is not None
+ current_x = platforms[self.current_platform].x
+ longest_x = platforms[self.longest_platform].x
+ if current_x == longest_x and self.longest_platform + 1 < len(platforms):
+ return platforms[self.longest_platform + 1]
+ if self.current_platform >= len(platforms) - 1:
+ return platforms[self.current_platform]
+ return platforms[self.current_platform + 1]
+
+ def init_spawnpoint(
+ self, autoscroll: bool, platforms: Sequence[Platform], next_platform: Platform
+ ) -> None:
+ if not autoscroll and not self.respawn_point:
+ self.respawn_point = [
+ 0.5 * platforms[0][0] + 0.5 * platforms[0][2],
+ platforms[0][1] - self.height - 10,
+ ]
+ elif autoscroll:
+ self.respawn_point = [
+ next_platform[0] + 0.5 * next_platform.width,
+ next_platform[1] - self.height - 10,
+ ]
+
+ def respawn(self, x: float, y: float, lose_life: bool = True) -> None:
+ self.x = int(x)
+ self.y = int(y)
+ self.vx = self.vy = 0
+ self.health = self.recovery_health
+ if lose_life:
+ self.flashing = True
+ self.lives -= 1
+
+ def determine_longest_platform(self, platforms: Sequence[Platform]) -> None:
+ if self.longest_platform is not None:
+ return
+ self.longest_platform = 0
+ for i in range(1, len(platforms)):
+ if platforms[i].width > platforms[self.longest_platform].width:
+ self.longest_platform = i
+ for i in range(len(platforms)):
+ if (
+ platforms[i][0] == platforms[self.longest_platform][0]
+ and platforms[i][1] >= platforms[self.longest_platform][1]
+ ):
+ self.longest_platform = i
+
+ def scan_world(
+ self,
+ ai_characters: Sequence[AICharacter],
+ autoscroll: bool,
+ movable_objects: Sequence[object],
+ next_platform: Platform,
+ scr_h: int,
+ scr_w: int,
+ ) -> None:
+ right_edge = int(0.5 * scr_w) + 2
+ left_edge = int(0.5 * scr_w) - 2
+ bottom_edge = int(0.25 * scr_h) if self.ducking else int(0.7 * scr_h) + 5
+ top_edge = int(0.3 * scr_h) - 5
+ shift = int(self.world_shift_coefficient * self.run_speed)
+ if self.y <= scr_h and not autoscroll:
+ self.increment_map_h(ai_characters, movable_objects, -self.vx, move_self=False)
+ if self.x >= right_edge:
+ self.increment_map_h(ai_characters, movable_objects, -shift)
+ if self.x <= left_edge:
+ self.increment_map_h(ai_characters, movable_objects, shift)
+ if self.y <= scr_h:
+ if self.y <= top_edge:
+ self.increment_map_v(movable_objects, shift)
+ if self.y >= bottom_edge or next_platform[3] >= scr_h:
+ self.increment_map_v(movable_objects, -shift)
+ elif randint(0, 10) == 0:
+ self.health -= 1
+
+ def handle_world_scrolling(
+ self,
+ ai_characters: Sequence[AICharacter],
+ autoscroll: bool,
+ movable_objects: Sequence[object],
+ scr_w: int,
+ ) -> None:
+ if autoscroll and self.x + self.width >= 0:
+ self.increment_map_h(ai_characters, movable_objects, -0.5 * self.run_speed)
+ self.x += self.vx
+ elif autoscroll and self.health > 0:
+ self.health -= 0.5
+ self.world_shift_coefficient = 20 if (self.x <= 0 or self.x >= scr_w) else 1.5
+
+ # -- input-driven movement --------------------------------------------------------
+
+ def enable_horizontal_movement(self, controls: PlayerInput) -> None:
+ movable = not self.cpu_controlled
+ if controls.left and movable:
+ self.vx = -self.run_speed
+ if controls.right and movable:
+ self.vx = self.run_speed
+ if not controls.left and not controls.right and movable:
+ self.vx = 0
+ self.moving_laterally = False
+ if self.vx > 0:
+ self.direction = 1
+ self.moving_laterally = True
+ elif self.vx < 0:
+ self.direction = 0
+ self.moving_laterally = True
+ else:
+ self.direction = 2
+ if controls.duck and movable:
+ self.ducking = True
+ self.vx = 0
+ else:
+ self.ducking = False
+
+ def allow_jumping(self, controls: PlayerInput) -> None:
+ if self.jumping and self.on_ground:
+ self.jumping = False
+ if controls.jump and self.can_jump and self.on_ground:
+ self.jump()
+ self.jumping = True
+ self.can_jump = False
+ self.on_ground = False
+ if not controls.jump and self.on_ground:
+ self.can_jump = True
+
+ def move(
+ self,
+ controls: PlayerInput,
+ platforms: Sequence[Platform],
+ movable_objects: Sequence[object],
+ ai_characters: Sequence[AICharacter],
+ scr_w: int,
+ scr_h: int,
+ autoscroll: bool,
+ ) -> bool:
+ """Advance the player one fixed step. Returns False when the game is over."""
+ self.update_motion(platforms)
+ self.x -= self.vx # horizontal motion is expressed by scrolling the world instead
+
+ self.enable_horizontal_movement(controls)
+ self.determine_longest_platform(platforms)
+ next_platform = self.get_next_platform(platforms)
+ self.scan_world(ai_characters, autoscroll, movable_objects, next_platform, scr_h, scr_w)
+ self.handle_world_scrolling(ai_characters, autoscroll, movable_objects, scr_w)
+ self.allow_jumping(controls)
+ self.init_spawnpoint(autoscroll, platforms, next_platform)
+
+ if self.health <= 0 and self.respawn_point is not None:
+ self.respawn(self.respawn_point[0], self.respawn_point[1])
+ return not (self.lives <= 0 and self.x != 0)
+
+ # -- rendering --------------------------------------------------------------------
+
+ def draw(self, surface: pygame.Surface) -> None:
+ super().draw(surface)
+ self.draw_hud(surface)
+
+ def draw_hud(self, surface: pygame.Surface) -> None:
+ s = self.spacing
+ surface.blit(self.player_icon, self.player_icon_coords)
+ surface.blit(self.coins_multiplier, (s + self.heart_width, int(2.5 * s)))
+ surface.blit(self.hud_numbers[self.lives], (5 * s + self.heart_width, int(1.5 * s)))
+
+ health = self.health / 2.0
+ for filled in range(1, math.floor(health) + 1):
+ if health >= 0:
+ surface.blit(self.heart_full, (self.health_interval * filled - 55, 7 * s))
+ if math.floor(health) != health and health >= 0:
+ surface.blit(self.heart_half, (self.health_interval * math.ceil(health) - 55, 7 * s))
+
+ surface.blit(self.coin_image, (s, 8 * s + self.heart_height))
+ surface.blit(self.coins_multiplier, (s + self.heart_width, 8 * s + self.heart_height + 15))
+ for i, digit in enumerate(str(self.coins)):
+ surface.blit(
+ self.hud_numbers[int(digit)],
+ (
+ 3 * s + self.coin_image_width + self.hud_text_width * (i + 1),
+ 7 * s + self.heart_height + 15,
+ ),
+ )
+
+ icon = self.key_icon if self.has_key else self.no_key_icon
+ surface.blit(icon, (s, 13 * s + self.heart_height + 15))
diff --git a/src/exit_dash/entities/pool.py b/src/exit_dash/entities/pool.py
new file mode 100644
index 0000000..33096d5
--- /dev/null
+++ b/src/exit_dash/entities/pool.py
@@ -0,0 +1,70 @@
+"""Pool: a water hazard with walkable platform edges and an open middle."""
+
+from __future__ import annotations
+
+import pygame
+
+from exit_dash.core import resources
+
+_ENV = ("environment", "main")
+
+
+class Pool:
+ def __init__(
+ self, x: float, y: float, width: float, height: float, style: str = "grass"
+ ) -> None:
+ self.x = float(x)
+ self.y = float(y)
+ self.vx = 0.0
+ self.vy = 0.0
+ self.width = float(width)
+ self.height = float(height)
+
+ self.image = resources.image(*_ENV, f"{style}Mid.png")
+ self.plain_image = resources.image(*_ENV, f"{style}Center.png")
+ self.left_image = resources.image(*_ENV, f"{style}CliffLeft.png")
+ self.right_image = resources.image(*_ENV, f"{style}CliffRight.png")
+ self.tile_width = self.image.get_width()
+
+ self.water_filled = resources.image(*_ENV, "liquidWater.png")
+ self.water_top = resources.image(*_ENV, "liquidWaterTop_mid.png")
+
+ self.width -= self.width % self.tile_width
+ self.height -= self.height % self.tile_width
+ self.tiles_on_either_side = 2
+ self.pool_start_x = int(self.x + self.tiles_on_either_side * self.tile_width)
+ self.pool_end_x = int(self.x + self.width - 2 * self.tile_width)
+
+ def update_motion(self) -> None:
+ self.x += self.vx
+ self.y += self.vy
+
+ def draw(self, surface: pygame.Surface) -> None:
+ surface.blit(self.left_image, (self.x, self.y))
+ surface.blit(self.right_image, (self.x + self.width - self.tile_width, self.y))
+
+ self.pool_start_x = int(self.x + self.tiles_on_either_side * self.tile_width)
+ self.pool_end_x = int(
+ self.x + self.width - (1 + self.tiles_on_either_side) * self.tile_width
+ )
+ for x in range(
+ int(self.x) + self.tile_width, self.pool_start_x + self.tile_width, self.tile_width
+ ):
+ surface.blit(self.image, (x, self.y))
+ for x in range(
+ self.pool_end_x, int(self.x + self.width - self.tile_width), self.tile_width
+ ):
+ surface.blit(self.image, (x, self.y))
+
+ for y in range(int(self.y + self.tile_width), int(self.y + self.height), self.tile_width):
+ surface.blit(self.plain_image, (self.pool_start_x, y))
+ surface.blit(self.plain_image, (self.pool_end_x, y))
+
+ for x in range(self.pool_start_x, self.pool_end_x + self.tile_width, self.tile_width):
+ surface.blit(self.plain_image, (x, self.y + self.height))
+
+ for y in range(int(self.y + self.tile_width), int(self.y + self.height), self.tile_width):
+ for x in range(self.pool_start_x + self.tile_width, self.pool_end_x, self.tile_width):
+ surface.blit(self.water_filled, (x, y))
+ for x in range(self.pool_start_x + self.tile_width, self.pool_end_x, self.tile_width):
+ surface.blit(self.water_top, (x, self.y))
diff --git a/src/exit_dash/entities/spike.py b/src/exit_dash/entities/spike.py
new file mode 100644
index 0000000..6944813
--- /dev/null
+++ b/src/exit_dash/entities/spike.py
@@ -0,0 +1,81 @@
+"""FallingSpike: an icicle that dislodges and falls when the player passes beneath it."""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+import pygame
+
+from exit_dash.core import resources
+
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+ from exit_dash.entities.block import Block
+ from exit_dash.entities.character import Character
+ from exit_dash.entities.platform import Platform
+
+_GRAVITY_ACCELERATION = 1.5
+
+
+class FallingSpike:
+ def __init__(self, x: float, y: float) -> None:
+ # ``x`` is the centre x of the spike.
+ self.x = float(x)
+ self.y = float(y)
+ self.vx = 0.0
+ self.vy = 0.0
+
+ self.image = resources.image("environment", "main", "spikeTop.png", alpha=False)
+ self.width = self.image.get_width()
+ self.height = self.image.get_height()
+ self.x -= int(0.5 * self.width)
+
+ self.visible = True
+ self.gravity_acceleration = _GRAVITY_ACCELERATION
+ self.dislodged = False
+
+ def collide(self, chars: Sequence[Character], platforms: Sequence[Platform]) -> None:
+ centre = (int(self.x + self.width / 2), self.y + int(0.5 * self.height))
+ for char in chars:
+ char_rect = pygame.Rect(int(char.x), int(char.y), int(char.width), int(char.height))
+ if char_rect.collidepoint(centre) and self.visible and not char.flashing:
+ char.health -= 1
+ char.flashing = True
+ self.visible = False
+
+ def update_motion(self, chars: Sequence[Character], platforms: Sequence[Platform]) -> None:
+ self.x += self.vx
+ self.y += int(self.vy)
+ if not (0 <= self.x <= 2000 and 0 <= self.y <= 2000):
+ return
+ for char in chars:
+ if char.x + char.width >= self.x and char.x <= self.x + self.width and char.y >= self.y:
+ self.dislodged = True
+ if self.vy >= platforms[0].height:
+ self.vy = platforms[0][3] - platforms[0][1] - 5
+ if self.dislodged:
+ self.vy += self.gravity_acceleration
+
+ def draw(
+ self,
+ platforms: Sequence[Platform],
+ blocks: Sequence[Block],
+ surface: pygame.Surface,
+ ) -> None:
+ if self.visible:
+ surface.blit(self.image, (self.x, self.y))
+ if self.visible and self.dislodged and 0 <= self.x <= 2000 and 0 <= self.y <= 2000:
+ for platform in platforms:
+ if (
+ self.y + 0.5 * self.height >= platform[1] > self.y
+ and platform[0] <= self.x <= platform[2]
+ ):
+ self.visible = False
+ for block in blocks:
+ if (
+ self.y + 0.5 * self.height >= block.y
+ and self.x + self.width >= block.x
+ and self.x <= block.x + block.width
+ ):
+ self.visible = False
diff --git a/src/exit_dash/entities/torch.py b/src/exit_dash/entities/torch.py
new file mode 100644
index 0000000..249fc37
--- /dev/null
+++ b/src/exit_dash/entities/torch.py
@@ -0,0 +1,35 @@
+"""Torch: a wall light that the player can ignite to illuminate dark levels."""
+
+from __future__ import annotations
+
+from random import randint
+
+import pygame
+
+from exit_dash.core import resources
+
+_ENV = ("environment", "main")
+
+
+class Torch:
+ def __init__(self, x: float, y: float) -> None:
+ self.x = float(x)
+ self.y = float(y)
+ self.burning = False
+ self.on_image_1 = resources.image(*_ENV, "torchLit.png")
+ self.on_image_2 = resources.image(*_ENV, "torchLit2.png")
+ self.off_image = resources.image(*_ENV, "torch.png")
+ self.width = self.off_image.get_width()
+ self.height = self.off_image.get_height()
+ self.image = self.off_image
+
+ def draw(self, surface: pygame.Surface) -> None:
+ if not self.burning:
+ surface.blit(self.off_image, (self.x, self.y))
+ elif randint(0, 1) == 1:
+ surface.blit(self.on_image_1, (self.x, self.y))
+ else:
+ surface.blit(self.on_image_2, (self.x, self.y))
+
+ def get_rect(self) -> pygame.Rect:
+ return pygame.Rect(int(self.x), int(self.y), self.width, self.height)
diff --git a/src/exit_dash/py.typed b/src/exit_dash/py.typed
new file mode 100644
index 0000000..e69de29
diff --git a/src/exit_dash/scenes/__init__.py b/src/exit_dash/scenes/__init__.py
new file mode 100644
index 0000000..196306b
--- /dev/null
+++ b/src/exit_dash/scenes/__init__.py
@@ -0,0 +1,3 @@
+"""Game scenes: the screens managed by the scene stack."""
+
+from __future__ import annotations
diff --git a/src/exit_dash/scenes/gameover.py b/src/exit_dash/scenes/gameover.py
new file mode 100644
index 0000000..8d08c63
--- /dev/null
+++ b/src/exit_dash/scenes/gameover.py
@@ -0,0 +1,57 @@
+"""GameOverScene: shown when the player wins or runs out of lives. Any key returns to title."""
+
+from __future__ import annotations
+
+import pygame
+
+from exit_dash.core import resources
+from exit_dash.core.constants import (
+ BLACK,
+ BRIGHT_GREEN,
+ BRIGHT_RED,
+ LOGICAL_HEIGHT,
+ LOGICAL_WIDTH,
+ WHITE,
+)
+from exit_dash.core.input import InputState
+from exit_dash.core.paths import asset_path
+from exit_dash.core.scene import Replace, Scene, Transition
+from exit_dash.core.settings import Settings
+
+
+class GameOverScene(Scene):
+ def __init__(self, won: bool, settings: Settings, *, audio: bool = True) -> None:
+ self.won = won
+ self.settings = settings
+ self.audio = audio
+ self._title_font = resources.font("jetset.ttf", 72)
+ self._font = resources.font("jetset.ttf", 28)
+
+ def on_enter(self) -> None:
+ if not (self.audio and self.settings.music_enabled and pygame.mixer.get_init()):
+ return
+ track = "char1_3.ogg" if self.won else "gameover.ogg"
+ try:
+ pygame.mixer.music.load(str(asset_path("music", track)))
+ pygame.mixer.music.set_volume(self.settings.volume)
+ pygame.mixer.music.play(-1 if self.won else 0)
+ except pygame.error:
+ pass
+
+ def handle_event(self, event: pygame.event.Event) -> Transition | None:
+ if event.type == pygame.KEYDOWN:
+ from exit_dash.scenes.title import TitleScene
+
+ return Replace(TitleScene(self.settings, audio=self.audio))
+ return None
+
+ def update(self, dt: float, inp: InputState) -> Transition | None:
+ return None
+
+ def draw(self, surface: pygame.Surface, alpha: float) -> None:
+ surface.fill(BLACK)
+ message, color = ("You Win!", BRIGHT_GREEN) if self.won else ("Game Over", BRIGHT_RED)
+ label = self._title_font.render(message, True, color)
+ surface.blit(label, label.get_rect(center=(LOGICAL_WIDTH // 2, LOGICAL_HEIGHT // 2 - 30)))
+ prompt = self._font.render("Press any key to return to the title", True, WHITE)
+ surface.blit(prompt, prompt.get_rect(center=(LOGICAL_WIDTH // 2, LOGICAL_HEIGHT // 2 + 50)))
diff --git a/src/exit_dash/scenes/level.py b/src/exit_dash/scenes/level.py
new file mode 100644
index 0000000..4944edb
--- /dev/null
+++ b/src/exit_dash/scenes/level.py
@@ -0,0 +1,244 @@
+"""LevelScene: plays one level. The per-frame simulation and rendering loop.
+
+Update advances the simulation by one fixed step in the original game's order (enemies,
+icicles, then the player, which also scrolls the move-the-world camera); draw renders
+everything in the original blit order. Reaching the door advances to the next level;
+running out of lives ends the run.
+"""
+
+from __future__ import annotations
+
+import random
+
+import pygame
+
+from exit_dash.core import resources
+from exit_dash.core.constants import BLACK, FIXED_FPS, LOGICAL_HEIGHT, LOGICAL_WIDTH, WHITE
+from exit_dash.core.input import InputState, PlayerInput
+from exit_dash.core.keybindings import DEFAULT_BINDINGS, key_names
+from exit_dash.core.paths import asset_path
+from exit_dash.core.scene import Quit, Replace, Scene, Transition
+from exit_dash.core.settings import Settings
+from exit_dash.entities.background import Background
+from exit_dash.entities.player import PlayableCharacter
+from exit_dash.world import hints, loader
+from exit_dash.world.world import World
+
+MAX_SHIPPED_LEVEL = 4
+_HINT_FRAMES = 13 * FIXED_FPS # show the level/hint banner for ~13s, like the original
+_BACKGROUND_BY_THEME = {
+ "stone": "bg_grasslands.png",
+ "snow": "bg_castle.png",
+ "castle": "bg_castle.png",
+ "desert": "bg_desert.png",
+}
+
+
+class LevelScene(Scene):
+ def __init__(
+ self,
+ level: int,
+ which_char: int,
+ settings: Settings,
+ *,
+ audio: bool = True,
+ final_level: int = MAX_SHIPPED_LEVEL,
+ ) -> None:
+ self.level = level
+ self.which_char = which_char
+ self.settings = settings
+ self.audio = audio
+ self.final_level = final_level
+ self.theme = "stone"
+ self.player = PlayableCharacter(0, 0, which_char=which_char)
+ self.world: World = self._build_world(level)
+ self._banner_frames = _HINT_FRAMES
+ self._allow_kill_bonus = True
+ self._med_font = resources.font("jetset.ttf", 28)
+ self._small_font = resources.font("atari.ttf", 16)
+
+ # -- setup ------------------------------------------------------------------------
+
+ def _make_background(self) -> Background:
+ name = _BACKGROUND_BY_THEME.get(self.theme, "bg_grasslands.png")
+ image = resources.image("backgrounds", "main", name, alpha=False)
+ return Background(image, LOGICAL_WIDTH, LOGICAL_HEIGHT)
+
+ def _build_world(self, level: int) -> World:
+ background = self._make_background()
+ rng = random.Random(level)
+ level_path = asset_path("levels", f"lvl_{level}.dat")
+ hint = hints.hint_for_level(level, key_names())
+ if level_path.is_file() and level <= MAX_SHIPPED_LEVEL:
+ data = loader.read_level(level_path)
+ return World.from_level_data(
+ data,
+ player=self.player,
+ screen_w=LOGICAL_WIDTH,
+ screen_h=LOGICAL_HEIGHT,
+ theme=self.theme,
+ level=level,
+ decorations=self.settings.decorations,
+ rng=rng,
+ background=background,
+ hint=hint,
+ )
+ world = World(
+ self.player,
+ LOGICAL_WIDTH,
+ LOGICAL_HEIGHT,
+ theme=self.theme,
+ level=level,
+ decorations=self.settings.decorations,
+ rng=rng,
+ background=background,
+ )
+ world.level_hint = hint
+ return world.generate(5 + 5 * level, seed=level)
+
+ def on_enter(self) -> None:
+ self._start_music()
+
+ def _start_music(self) -> None:
+ if not (self.audio and self.settings.music_enabled and pygame.mixer.get_init()):
+ return
+ try:
+ pygame.mixer.music.load(str(asset_path("music", "char1_3.ogg")))
+ pygame.mixer.music.set_volume(self.settings.volume)
+ pygame.mixer.music.play(-1)
+ except pygame.error:
+ pass
+
+ # -- input ------------------------------------------------------------------------
+
+ @staticmethod
+ def _player_input(inp: InputState) -> PlayerInput:
+ b = DEFAULT_BINDINGS
+ return PlayerInput(
+ left=inp.held(b["LEFT"]),
+ right=inp.held(b["RIGHT"]),
+ jump=inp.held(b["ACTION"]) or inp.held(b["ACTION2"]),
+ duck=inp.held(b["DUCK"]),
+ )
+
+ def handle_event(self, event: pygame.event.Event) -> Transition | None:
+ if event.type == pygame.KEYDOWN and event.key in (
+ DEFAULT_BINDINGS["EXIT"],
+ DEFAULT_BINDINGS["EXIT2"],
+ ):
+ return Quit()
+ return None
+
+ # -- update -----------------------------------------------------------------------
+
+ def update(self, dt: float, inp: InputState) -> Transition | None:
+ world = self.world
+ platforms = world.platforms
+ controls = self._player_input(inp)
+
+ # Hand control to the player once the intro CPU walk-in reaches mid-platform.
+ if self.player.x >= platforms[0][0] + 0.5 * platforms[0].width:
+ self.player.vx = 0
+ self.player.cpu_controlled = False
+
+ reached_exit = world.door.update(self.player) if world.door else False
+ if world.fakedoor:
+ world.fakedoor.update(self.player, unlockable=False)
+
+ for platform in platforms:
+ platform.update_motion((0, 0, world.screen_w, world.screen_h))
+ for block in world.blocks:
+ block.update_state()
+ for enemy in world.enemies:
+ enemy.step(platforms, world.blocks, world.enemies, world.pool, world.torches)
+ for spike in world.icicles:
+ spike.update_motion([self.player], platforms)
+ spike.collide([self.player], platforms)
+
+ self.player.collide(platforms, world.blocks, world.enemies, world.pool, world.torches)
+ self.player.collide_checkpoint(world.fences)
+ alive = self.player.move(
+ controls,
+ platforms,
+ world.movable_objects,
+ world.enemies,
+ world.screen_w,
+ world.screen_h,
+ world.autoscroll,
+ )
+ for key in world.keys:
+ key.update(self.player)
+
+ self._update_kill_bonus()
+ if self._banner_frames > 0:
+ self._banner_frames -= 1
+
+ if not alive:
+ return self._game_over(won=False)
+ if reached_exit:
+ return self._advance_level()
+ return None
+
+ def _game_over(self, *, won: bool) -> Transition:
+ from exit_dash.scenes.gameover import GameOverScene
+
+ return Replace(GameOverScene(won, self.settings, audio=self.audio))
+
+ def _update_kill_bonus(self) -> None:
+ if self.player.mob_jumping and self._allow_kill_bonus:
+ self._allow_kill_bonus = False
+ self.player.coins += 2
+ elif not self.player.mob_jumping:
+ self._allow_kill_bonus = True
+
+ def _advance_level(self) -> Transition | None:
+ self.level += 1
+ if self.level > self.final_level:
+ return self._game_over(won=True)
+ self.player.has_key = False
+ self.world = self._build_world(self.level)
+ self._banner_frames = _HINT_FRAMES
+ return None
+
+ # -- draw -------------------------------------------------------------------------
+
+ def draw(self, surface: pygame.Surface, alpha: float) -> None:
+ surface.fill(BLACK)
+ world = self.world
+ if world.background:
+ world.background.update(surface)
+ if world.fakedoor:
+ world.fakedoor.draw(surface)
+ if world.door:
+ world.door.draw(surface)
+ if world.pool:
+ world.pool.draw(surface)
+ for fence in world.fences:
+ fence.draw(surface)
+ for foliage in world.foliage:
+ foliage.draw(surface)
+ for torch in world.torches:
+ torch.draw(surface)
+ for platform in world.platforms:
+ platform.draw(surface)
+ for block in world.blocks:
+ block.draw(world.keys, surface)
+ for enemy in world.enemies:
+ enemy.draw(surface)
+ for spike in world.icicles:
+ spike.draw(world.platforms, world.blocks, surface)
+ self.player.draw(surface)
+ for key in world.keys:
+ key.draw(surface)
+
+ if self._banner_frames > 0:
+ self._draw_banner(surface)
+ if world.level_dark:
+ world.darken(surface, 130)
+
+ def _draw_banner(self, surface: pygame.Surface) -> None:
+ level_label = self._med_font.render(f"Level {self.level}", True, WHITE)
+ surface.blit(level_label, (LOGICAL_WIDTH - 170, 40))
+ if self.world.level_hint:
+ hint_label = self._small_font.render(self.world.level_hint, True, WHITE)
+ surface.blit(hint_label, (60, 180))
diff --git a/src/exit_dash/scenes/title.py b/src/exit_dash/scenes/title.py
new file mode 100644
index 0000000..4b9e951
--- /dev/null
+++ b/src/exit_dash/scenes/title.py
@@ -0,0 +1,86 @@
+"""TitleScene: the entry screen. Pick a character (1/2/3) to start, Esc to quit."""
+
+from __future__ import annotations
+
+import pygame
+
+from exit_dash.core import resources
+from exit_dash.core.constants import (
+ BLACK,
+ LOGICAL_HEIGHT,
+ LOGICAL_WIDTH,
+ WHITE,
+ WINDOW_TITLE,
+ YELLOW,
+)
+from exit_dash.core.input import InputState
+from exit_dash.core.paths import asset_path
+from exit_dash.core.scene import Quit, Replace, Scene, Transition
+from exit_dash.core.settings import Settings
+
+_CHARACTER_KEYS = {pygame.K_1: 1, pygame.K_2: 2, pygame.K_3: 3}
+
+
+class TitleScene(Scene):
+ def __init__(self, settings: Settings, *, audio: bool = True) -> None:
+ self.settings = settings
+ self.audio = audio
+ self._background = resources.image("backgrounds", "main", "title.jpg", alpha=False)
+ self._background = pygame.transform.smoothscale(
+ self._background, (LOGICAL_WIDTH, LOGICAL_HEIGHT)
+ )
+ self._title_font = resources.font("jetset.ttf", 72)
+ self._font = resources.font("jetset.ttf", 28)
+ self._small = resources.font("atari.ttf", 16)
+ self._character_previews = [
+ resources.image("character", "main", f"p{i}_front.png") for i in (1, 2, 3)
+ ]
+
+ def on_enter(self) -> None:
+ if self.audio and self.settings.music_enabled and pygame.mixer.get_init():
+ try:
+ pygame.mixer.music.load(str(asset_path("music", "menuloop.ogg")))
+ pygame.mixer.music.set_volume(self.settings.volume)
+ pygame.mixer.music.play(-1)
+ except pygame.error:
+ pass
+
+ def handle_event(self, event: pygame.event.Event) -> Transition | None:
+ if event.type != pygame.KEYDOWN:
+ return None
+ if event.key in (pygame.K_ESCAPE, pygame.K_q):
+ return Quit()
+ if event.key in _CHARACTER_KEYS:
+ from exit_dash.scenes.level import LevelScene
+
+ char = _CHARACTER_KEYS[event.key]
+ return Replace(LevelScene(1, char, self.settings, audio=self.audio))
+ return None
+
+ def update(self, dt: float, inp: InputState) -> Transition | None:
+ return None
+
+ def draw(self, surface: pygame.Surface, alpha: float) -> None:
+ surface.fill(BLACK)
+ surface.blit(self._background, (0, 0))
+
+ title = self._title_font.render(WINDOW_TITLE, True, WHITE)
+ surface.blit(title, title.get_rect(center=(LOGICAL_WIDTH // 2, 140)))
+
+ prompt = self._font.render("Choose your character — press 1, 2 or 3", True, YELLOW)
+ surface.blit(prompt, prompt.get_rect(center=(LOGICAL_WIDTH // 2, LOGICAL_HEIGHT - 150)))
+
+ # Character previews with their number.
+ spacing = 220
+ start_x = LOGICAL_WIDTH // 2 - spacing
+ for i, preview in enumerate(self._character_previews):
+ x = start_x + i * spacing
+ rect = preview.get_rect(center=(x, LOGICAL_HEIGHT // 2))
+ surface.blit(preview, rect)
+ label = self._font.render(str(i + 1), True, WHITE)
+ surface.blit(label, label.get_rect(center=(x, rect.bottom + 24)))
+
+ footer = self._small.render(
+ "Arrows move · Up/Space jump · Down duck · Esc quit", True, WHITE
+ )
+ surface.blit(footer, footer.get_rect(center=(LOGICAL_WIDTH // 2, LOGICAL_HEIGHT - 60)))
diff --git a/src/exit_dash/world/__init__.py b/src/exit_dash/world/__init__.py
new file mode 100644
index 0000000..64b31f0
--- /dev/null
+++ b/src/exit_dash/world/__init__.py
@@ -0,0 +1,3 @@
+"""Level data, the world container, the camera, the procedural generator and hints."""
+
+from __future__ import annotations
diff --git a/src/exit_dash/world/hints.py b/src/exit_dash/world/hints.py
new file mode 100644
index 0000000..cca2ac5
--- /dev/null
+++ b/src/exit_dash/world/hints.py
@@ -0,0 +1,48 @@
+"""Per-level hint text and ``{TOKEN}`` key-name interpolation.
+
+A hint may embed one binding token in braces, e.g. ``"Use {DUCK} to duck"``, which is
+replaced with the quoted human key name (``Use "down" to duck``). This reproduces the
+original ``interpretHintString`` behavior: the *last* ``{...}`` pair is substituted, the
+literal string ``"None"`` becomes empty, and text without braces is returned unchanged.
+"""
+
+from __future__ import annotations
+
+from collections.abc import Mapping, Sequence
+from pathlib import Path
+
+from exit_dash.core.paths import asset_path
+
+
+def interpret_hint(hint: str, names: Mapping[str, str]) -> str:
+ """Substitute a ``{TOKEN}`` in ``hint`` with the quoted key name from ``names``."""
+ hint = str(hint)
+ if hint == "None":
+ return ""
+ start_brace = hint.rfind("{")
+ if start_brace == -1:
+ return hint
+ end_brace = hint.rfind("}")
+ if end_brace <= start_brace:
+ return hint
+ token = hint[start_brace + 1 : end_brace]
+ name = names.get(token, token)
+ return f'{hint[:start_brace]}"{name}"{hint[end_brace + 1 :]}'
+
+
+def hint_lines(path: Path | None = None) -> list[str]:
+ """Return the raw hint lines (one per level), or an empty list if the file is absent."""
+ path = asset_path("levels", "lvlhints.dat") if path is None else path
+ if not path.is_file():
+ return []
+ text = path.read_text(encoding="utf-8").replace("\r\n", "\n").replace("\r", "\n")
+ return text.split("\n")
+
+
+def hint_for_level(level: int, names: Mapping[str, str], lines: Sequence[str] | None = None) -> str:
+ """Return the interpreted hint for a 1-based ``level``, or ``""`` if none exists."""
+ if lines is None:
+ lines = hint_lines()
+ if not 1 <= level <= len(lines):
+ return ""
+ return interpret_hint(lines[level - 1], names)
diff --git a/src/exit_dash/world/level.py b/src/exit_dash/world/level.py
new file mode 100644
index 0000000..fd7a14b
--- /dev/null
+++ b/src/exit_dash/world/level.py
@@ -0,0 +1,70 @@
+"""Typed, format-agnostic level data.
+
+These records describe everything a level needs, decoupled from both the on-disk ``.dat``
+format (see :mod:`exit_dash.world.loader`) and the live sprite entities (built in
+:mod:`exit_dash.world`). Keeping them as plain dataclasses makes level I/O trivially
+testable without a display.
+"""
+
+from __future__ import annotations
+
+from dataclasses import dataclass, field
+
+
+@dataclass(frozen=True)
+class PlatformRec:
+ """A platform: top-left ``(x, y)`` and a ``width`` (height is tile-derived)."""
+
+ x: float
+ y: float
+ width: float
+
+
+@dataclass(frozen=True)
+class PoolRec:
+ """A water pool occupying a rectangle."""
+
+ x: float
+ y: float
+ width: float
+ height: float
+
+
+@dataclass(frozen=True)
+class BlockRec:
+ """A bonus block. ``coin`` distinguishes a coin block (type 0) from a regular one."""
+
+ x: float
+ y: float
+ coin: bool
+
+
+@dataclass(frozen=True)
+class LedgeRec:
+ """A snow ledge that spawns falling icicles along its span."""
+
+ x: float
+ y: float
+ width: float
+
+
+@dataclass(frozen=True)
+class DoorRec:
+ """The level-exit door. ``x``/``y`` are the raw stored coordinates."""
+
+ x: float
+ y: float
+
+
+@dataclass
+class LevelData:
+ """A complete level definition."""
+
+ door: DoorRec
+ platforms: list[PlatformRec] = field(default_factory=list)
+ blocks: list[BlockRec] = field(default_factory=list)
+ pool: PoolRec | None = None
+ ledge: LedgeRec | None = None
+ fences: bool = True
+ foliage: bool = True
+ seed: float = 0.0
diff --git a/src/exit_dash/world/loader.py b/src/exit_dash/world/loader.py
new file mode 100644
index 0000000..e4fc1bb
--- /dev/null
+++ b/src/exit_dash/world/loader.py
@@ -0,0 +1,169 @@
+"""Read and write the level ``.dat`` format.
+
+The format is a header line followed by newline-separated numbers in fixed positions:
+
+* 25 platform slots, each ``(x, y, width)``
+* 1 pool ``(x, y, width, height)``
+* 25 block slots, each ``(x, y, kind)`` where ``kind`` is ``0`` (coin) or ``1`` (regular)
+* 1 ledge ``(x, y, width)``
+* 1 door ``(x, y)``
+* fences flag, foliage flag, seed
+
+Unused slots are filled with the sentinel ``-999``. The reader normalizes line endings
+(historically files mixed CRLF and LF) and skips blank lines, so it is robust to the
+inconsistencies in the original data files. The writer always emits ``\\n`` line endings.
+"""
+
+from __future__ import annotations
+
+from pathlib import Path
+
+from exit_dash.world.level import (
+ BlockRec,
+ DoorRec,
+ LedgeRec,
+ LevelData,
+ PlatformRec,
+ PoolRec,
+)
+
+EMPTY = -999.0
+MAX_PLATFORMS = 25
+MAX_BLOCKS = 25
+_PLATFORM_FIELDS = 3
+_POOL_FIELDS = 4
+_BLOCK_FIELDS = 3
+_LEDGE_FIELDS = 3
+_DOOR_FIELDS = 2
+#: Total number of numeric values expected after the header line.
+EXPECTED_VALUES = (
+ MAX_PLATFORMS * _PLATFORM_FIELDS
+ + _POOL_FIELDS
+ + MAX_BLOCKS * _BLOCK_FIELDS
+ + _LEDGE_FIELDS
+ + _DOOR_FIELDS
+ + 3 # fences flag, foliage flag, seed
+)
+
+
+def _is_empty(value: float) -> bool:
+ return value == EMPTY
+
+
+def loads(text: str) -> LevelData:
+ """Parse level text (header + numbers) into :class:`LevelData`."""
+ normalized = text.replace("\r\n", "\n").replace("\r", "\n")
+ lines = [ln.strip() for ln in normalized.split("\n")]
+ # Drop the header (first non-empty line) and any blank lines.
+ numbers: list[float] = []
+ for line in lines[1:]:
+ if line:
+ numbers.append(float(line))
+
+ if len(numbers) < EXPECTED_VALUES:
+ raise ValueError(
+ f"level data has {len(numbers)} values, expected at least {EXPECTED_VALUES}"
+ )
+
+ cursor = 0
+
+ platforms: list[PlatformRec] = []
+ for _ in range(MAX_PLATFORMS):
+ x, y, width = numbers[cursor : cursor + _PLATFORM_FIELDS]
+ if not _is_empty(x):
+ platforms.append(PlatformRec(x, y, width))
+ cursor += _PLATFORM_FIELDS
+
+ pool: PoolRec | None = None
+ px, py, pw, ph = numbers[cursor : cursor + _POOL_FIELDS]
+ if not _is_empty(px):
+ pool = PoolRec(px, py, pw, ph)
+ cursor += _POOL_FIELDS
+
+ blocks: list[BlockRec] = []
+ for _ in range(MAX_BLOCKS):
+ x, y, kind = numbers[cursor : cursor + _BLOCK_FIELDS]
+ if not _is_empty(x):
+ blocks.append(BlockRec(x, y, coin=(kind == 0)))
+ cursor += _BLOCK_FIELDS
+
+ ledge: LedgeRec | None = None
+ lx, ly, lw = numbers[cursor : cursor + _LEDGE_FIELDS]
+ if not _is_empty(lx):
+ ledge = LedgeRec(lx, ly, lw)
+ cursor += _LEDGE_FIELDS
+
+ door = DoorRec(numbers[cursor], numbers[cursor + 1])
+ cursor += _DOOR_FIELDS
+
+ fences = numbers[cursor] != 0
+ foliage = numbers[cursor + 1] != 0
+ seed = numbers[cursor + 2]
+
+ return LevelData(
+ door=door,
+ platforms=platforms,
+ blocks=blocks,
+ pool=pool,
+ ledge=ledge,
+ fences=fences,
+ foliage=foliage,
+ seed=seed,
+ )
+
+
+def _fmt(value: float) -> str:
+ """Format a number, dropping a trailing ``.0`` from whole values to keep files tidy."""
+ return str(int(value)) if float(value).is_integer() else repr(float(value))
+
+
+def dumps(level: LevelData, *, level_number: int = 0) -> str:
+ """Serialize :class:`LevelData` back to the ``.dat`` text format."""
+ out: list[str] = [f"Position Data For Level {level_number} - DO NOT MODIFY THIS FILE!"]
+ empty = _fmt(EMPTY)
+
+ for i in range(MAX_PLATFORMS):
+ if i < len(level.platforms):
+ p = level.platforms[i]
+ out += [_fmt(p.x), _fmt(p.y), _fmt(p.width)]
+ else:
+ out += [empty] * _PLATFORM_FIELDS
+
+ if level.pool is not None:
+ out += [
+ _fmt(level.pool.x),
+ _fmt(level.pool.y),
+ _fmt(level.pool.width),
+ _fmt(level.pool.height),
+ ]
+ else:
+ out += [empty] * _POOL_FIELDS
+
+ for i in range(MAX_BLOCKS):
+ if i < len(level.blocks):
+ b = level.blocks[i]
+ out += [_fmt(b.x), _fmt(b.y), "0" if b.coin else "1"]
+ else:
+ out += [empty] * _BLOCK_FIELDS
+
+ if level.ledge is not None:
+ out += [_fmt(level.ledge.x), _fmt(level.ledge.y), _fmt(level.ledge.width)]
+ else:
+ out += [empty] * _LEDGE_FIELDS
+
+ out += [_fmt(level.door.x), _fmt(level.door.y)]
+ out.append("1" if level.fences else "0")
+ out.append("1" if level.foliage else "0")
+ out.append(_fmt(level.seed))
+
+ return "\n".join(out) + "\n"
+
+
+def read_level(path: Path) -> LevelData:
+ """Read a level from a ``.dat`` file."""
+ return loads(path.read_text(encoding="utf-8"))
+
+
+def write_level(path: Path, level: LevelData, *, level_number: int = 0) -> None:
+ """Write a level to a ``.dat`` file (always LF line endings)."""
+ path.write_text(dumps(level, level_number=level_number), encoding="utf-8", newline="\n")
diff --git a/src/exit_dash/world/world.py b/src/exit_dash/world/world.py
new file mode 100644
index 0000000..70ea224
--- /dev/null
+++ b/src/exit_dash/world/world.py
@@ -0,0 +1,466 @@
+"""The World: every entity in a level, plus assembly from data or procedural generation.
+
+This ports the original game's level-assembly methods (``loadLevel`` /
+``generateRandomLevel`` and their shared helpers) onto one object. Randomness flows
+through an injected ``random.Random`` so generated levels are reproducible from a seed
+and tests are deterministic. The per-frame update/draw loop lives in
+:class:`exit_dash.scenes.level.LevelScene`; this class owns the data and how it is built.
+"""
+
+from __future__ import annotations
+
+import math
+import random
+from typing import TYPE_CHECKING
+
+import pygame
+
+from exit_dash.entities.background import Background
+from exit_dash.entities.block import Block
+from exit_dash.entities.checkpoint import Checkpoint
+from exit_dash.entities.door import Door
+from exit_dash.entities.enemy import AICharacter, MobType
+from exit_dash.entities.foliage import BackgroundFoliage
+from exit_dash.entities.key import Key
+from exit_dash.entities.platform import Platform
+from exit_dash.entities.pool import Pool
+from exit_dash.entities.spike import FallingSpike
+from exit_dash.entities.torch import Torch
+
+if TYPE_CHECKING:
+ from exit_dash.entities.player import PlayableCharacter
+ from exit_dash.world.level import LevelData
+
+DEFAULT_VALUE = -999
+_MAX_TORCH_DISTANCE = 490
+
+
+def _distance(a: tuple[float, float], b: tuple[float, float]) -> float:
+ return math.sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
+
+
+class World:
+ def __init__(
+ self,
+ player: PlayableCharacter,
+ screen_w: int,
+ screen_h: int,
+ *,
+ theme: str = "stone",
+ level: int = 1,
+ decorations: bool = True,
+ rng: random.Random | None = None,
+ background: Background | None = None,
+ ) -> None:
+ self.player = player
+ self.screen_w = screen_w
+ self.screen_h = screen_h
+ self.theme = theme
+ self.level = level
+ self.decorations = decorations
+ self.rng = rng if rng is not None else random.Random()
+ self.background = background
+
+ self.platforms: list[Platform] = []
+ self.blocks: list[Block] = []
+ self.keys: list[Key] = []
+ self.enemies: list[AICharacter] = []
+ self.mobs: list[AICharacter] = []
+ self.icicles: list[FallingSpike] = []
+ self.fences: list[Checkpoint] = []
+ self.foliage: list[BackgroundFoliage] = []
+ self.torches: list[Torch] = []
+ self.pool: Pool | None = None
+ self.door: Door | None = None
+ self.fakedoor: Door | None = None
+ self.movable_objects: list[object] = []
+
+ self.autoscroll = False
+ self.level_dark = False
+ self.level_hint = ""
+ self.seed: float = 0.0
+
+ # Populated by gather_platform_info.
+ self.longest_platform: Platform | None = None
+ self.farthest_platform: Platform | None = None
+
+ # -- shared assembly helpers (used by both load and generate) ---------------------
+
+ def gather_platform_info(self) -> None:
+ ref = self.platforms[1]
+ topmost = lowest = shortest = longest = farthest = ref
+ for p in self.platforms:
+ if p[1] < topmost[1]:
+ topmost = p
+ if p[1] > lowest[1]:
+ lowest = p
+ if p.width > longest.width and p[0] != self.platforms[0][0]:
+ longest = p
+ if p[2] - p[0] < shortest[2] - shortest[0]:
+ shortest = p
+ if p[2] > farthest[2]:
+ farthest = p
+ self.longest_platform = longest
+ self.farthest_platform = farthest
+
+ def finalize_blocks(self) -> None:
+ for block in self.blocks:
+ if block.form == "regular" and not self.keys and not block.yields_star:
+ key = Key(block.x, block.y - 80, "blue")
+ self.keys.append(key)
+ self.movable_objects.append(key)
+ elif block.form == "regular" and self.rng.randint(0, 2) == 0:
+ block.will_explode = True
+ elif block.form == "regular":
+ block.yields_star = True
+ self.movable_objects.append(block)
+
+ def _platform_collision(self, obj: object) -> bool:
+ test_rect: pygame.Rect = obj.get_rect() # type: ignore[attr-defined]
+ return any(test_rect.colliderect(p.get_rect()) for p in self.platforms)
+
+ def generate_mobs(self, longest: Platform, farthest: Platform) -> None:
+ quantity = len(self.platforms) - 1
+ sample = AICharacter(0, 0, 0, 0, ("slime", -1, -1))
+ self.mobs = []
+ for _ in range(quantity):
+ which = self.rng.randint(1, len(self.platforms) - 1)
+ while self.platforms[which][0] == longest[0]:
+ which = self.rng.randint(1, len(self.platforms) - 1)
+ p = self.platforms[which]
+ mob_type: MobType = "slime" if self.rng.randint(0, 1) == 0 else "snail"
+ self.mobs.append(
+ AICharacter(
+ self.rng.randint(int(p[0]), int(p[2])),
+ p[3] - sample.height,
+ int(0.7 * self.player.run_speed),
+ 0,
+ (mob_type, -1, -1),
+ )
+ )
+ self.mobs.append(
+ AICharacter(
+ 70,
+ self.platforms[0][1] - 750,
+ 5,
+ 0,
+ ("fly", int(self.platforms[0][0]), int(farthest[2])),
+ )
+ )
+ if self.pool:
+ self.mobs.append(
+ AICharacter(
+ self.pool.pool_start_x + self.pool.tile_width,
+ self.pool.y + self.pool.tile_width,
+ 5,
+ 0,
+ ("fish", -1, -1),
+ )
+ )
+ self.enemies.extend(self.mobs)
+ self.movable_objects.extend(self.mobs)
+
+ def generate_fences(self) -> None:
+ sample = Checkpoint(DEFAULT_VALUE, DEFAULT_VALUE)
+ self.fences = []
+ for i in range(1, len(self.platforms), 5):
+ if self.platforms[i].width >= 2 * sample.width and not self.autoscroll:
+ self.fences.append(
+ Checkpoint(self.platforms[i][0] + 20, self.platforms[i][1] - sample.height)
+ )
+ self.movable_objects.extend(self.fences)
+
+ def generate_foliage(self) -> None:
+ self.foliage = []
+ for platform in self.platforms:
+ for x in range(int(platform.x), int(platform.x + platform.width - 100), 100):
+ if self.rng.randint(0, 10) == 0 and self.decorations:
+ decoration = BackgroundFoliage(x, platform.y)
+ decoration.y -= decoration.height
+ self.movable_objects.append(decoration)
+ self.foliage.append(decoration)
+
+ def generate_torches(self) -> None:
+ if not self.level_dark:
+ return
+ assert self.farthest_platform is not None
+ for block in self.blocks:
+ torch = Torch(block.x, block.y - self.player.height - 25)
+ if not self._platform_collision(torch) and torch.x <= self.farthest_platform[2]:
+ self.torches.append(torch)
+ for torch1 in list(self.torches):
+ for torch2 in list(self.torches):
+ if (
+ torch1 is not torch2
+ and _distance((torch1.x, torch1.y), (torch2.x, torch2.y)) < _MAX_TORCH_DISTANCE
+ and torch2 in self.torches
+ ):
+ self.torches.remove(torch2)
+ self.movable_objects.extend(self.torches)
+
+ def decide_dark(self) -> None:
+ self.level_dark = (self.rng.randint(0, 2) == 0 and self.level > 2) or self.level == 2
+
+ def finalize_level(self, farthest: Platform) -> None:
+ for key in self.keys:
+ key.visible = False
+ if not self.keys or self.autoscroll:
+ key = Key(int(0.5 * (farthest[0] + farthest[2])), farthest[1] - 80, "blue")
+ key.visible = True
+ self.keys.append(key)
+ self.movable_objects.append(key)
+ self.player.x = self.platforms[0][0] + 20
+ self.player.y = self.platforms[0][1] - self.player.height
+ self.player.vx = 5
+ self.player.cpu_controlled = True
+ for c in [self.player, *self.mobs]:
+ c.platform_init(self.platforms)
+ self.player.set_map_obj_x(
+ self.enemies, self.movable_objects, self.platforms, self.screen_w - 100
+ )
+ if self.background is not None:
+ self.movable_objects.append(self.background)
+ self.decide_dark()
+ self.generate_torches()
+
+ # -- build from saved level data --------------------------------------------------
+
+ @classmethod
+ def from_level_data(
+ cls,
+ data: LevelData,
+ *,
+ player: PlayableCharacter,
+ screen_w: int,
+ screen_h: int,
+ theme: str = "stone",
+ level: int = 1,
+ decorations: bool = True,
+ rng: random.Random | None = None,
+ background: Background | None = None,
+ hint: str = "",
+ ) -> World:
+ world = cls(
+ player,
+ screen_w,
+ screen_h,
+ theme=theme,
+ level=level,
+ decorations=decorations,
+ rng=rng,
+ background=background,
+ )
+ world.level_hint = hint
+ world.seed = data.seed
+
+ for rec in data.platforms:
+ world.platforms.append(Platform(rec.x, rec.y, rec.width, style=theme))
+ world.movable_objects.extend(world.platforms)
+ world.gather_platform_info()
+
+ if data.pool is not None:
+ world.pool = Pool(data.pool.x, data.pool.y, data.pool.width, data.pool.height, theme)
+ world.movable_objects.append(world.pool)
+
+ for block_rec in data.blocks:
+ world.blocks.append(
+ Block(block_rec.x, block_rec.y, "coin" if block_rec.coin else "regular")
+ )
+ world.finalize_blocks()
+
+ if data.ledge is not None:
+ ledge = Platform(data.ledge.x, data.ledge.y, data.ledge.width, style="snow")
+ world.platforms.append(ledge)
+ world.movable_objects.append(ledge)
+ for i in range(
+ int(ledge[0] + ledge.tile_width * 2), int(ledge[2] - ledge.tile_width * 2), 40
+ ):
+ world.icicles.append(FallingSpike(i, ledge[3]))
+ world.movable_objects.extend(world.icicles)
+
+ assert world.longest_platform is not None and world.farthest_platform is not None
+ world.generate_mobs(world.longest_platform, world.farthest_platform)
+
+ world.door = Door(data.door.x, data.door.y)
+ world.movable_objects.append(world.door)
+ world.fakedoor = Door(world.platforms[0][0] + 10, world.platforms[0][1])
+ world.movable_objects.append(world.fakedoor)
+
+ if data.fences:
+ world.generate_fences()
+ world.autoscroll = False
+ elif world.rng.randint(0, 3) == 0:
+ world.autoscroll = True
+
+ if data.foliage:
+ world.generate_foliage()
+
+ world.finalize_level(world.farthest_platform)
+ return world
+
+ # -- procedural generation --------------------------------------------------------
+
+ def generate(self, num_platforms: int, seed: float | None = None) -> World:
+ """Procedurally build a level (used when no saved level file exists)."""
+ if seed is not None:
+ self.rng.seed(seed)
+ self.seed = seed
+ player = self.player
+ theme = self.theme
+
+ # Step 1: lay out platforms with an iterative reachability-aware walk.
+ first = Platform(
+ self.rng.randint(-300, 500),
+ self.rng.randint(self.screen_h - 200, self.screen_h - 50),
+ self.rng.randint(800, 1500),
+ style=theme,
+ )
+ overlap = True
+ attempts = 3 * num_platforms
+ max_h = player.max_jump_height - 10
+ max_w = player.max_jump_length * 2
+ while overlap and attempts >= 0:
+ overlap = False
+ attempts -= 1
+ self.platforms = [first]
+ for i in range(1, num_platforms):
+ direction = [1, self.rng.randint(0, 1)]
+ width = self.rng.randint(400, 2000)
+ prev = self.platforms[i - 1]
+ if direction[0] == 0 and direction[1] == 0:
+ right = prev[0] - self.rng.randint(int(0.5 * max_w), max_w)
+ left = right - width
+ top = prev[1] + self.rng.randint(int(0.75 * max_h), max_h)
+ elif direction[0] == 0 and direction[1] == 1:
+ right = prev[0] - self.rng.randint(int(0.5 * max_w), max_w)
+ left = right - width
+ top = prev[1] - self.rng.randint(int(0.75 * max_h), max_h)
+ elif direction[0] == 1 and direction[1] == 1:
+ left = prev[2] + self.rng.randint(int(0.5 * max_w), max_w)
+ top = prev[1] - self.rng.randint(int(0.75 * max_h), max_h)
+ else:
+ left = prev[2] + self.rng.randint(int(1.2 * player.width), max_w)
+ top = prev[1] + self.rng.randint(int(0.5 * max_h), int(0.4 * self.screen_h))
+ self.platforms.append(Platform(left, top, width, style=theme))
+ overlap = self._platform_collision(self.platforms[i])
+ self.movable_objects.extend(self.platforms)
+
+ # Step 2: platform stats.
+ self.gather_platform_info()
+ assert self.longest_platform is not None and self.farthest_platform is not None
+ focus_height = self.longest_platform[1] - 324
+
+ # Step 3: a rare water pool (or a chance of autoscroll instead).
+ self.pool = None
+ if self.rng.randint(0, 2) == 0 or self.level <= 1:
+ self.pool = Pool(
+ self.farthest_platform[2] + int(0.9 * player.max_jump_length),
+ self.farthest_platform[1],
+ self.rng.randint(700, 900),
+ 4 * player.height,
+ theme,
+ )
+ self.movable_objects.append(self.pool)
+ elif self.rng.randint(0, 1) == 0:
+ self.autoscroll = True
+
+ # Step 4: bonus blocks.
+ sample_block = Block(0, 0, "regular")
+ block_height = math.floor(1.3 * player.height + sample_block.height)
+ self.blocks = [
+ Block(
+ self.rng.randint(int(self.platforms[0][0] + 50), int(self.platforms[0][2] - 50)),
+ self.platforms[0][1] - block_height,
+ "coin",
+ )
+ ]
+ self.keys = []
+ for i in range(1, num_platforms):
+ y = self.platforms[i][1] - block_height
+ if self.platforms[i].x != self.longest_platform.x and self.rng.randint(0, 3) != 0:
+ spread = int(0.4 * self.platforms[i].width)
+ x = (
+ 0.5 * self.platforms[i][0]
+ + 0.5 * self.platforms[i][2]
+ + self.rng.randint(-spread, spread)
+ )
+ self.blocks.append(Block(x, y, "coin"))
+ elif self.platforms[i].x != self.longest_platform.x and not self.keys:
+ spread = int(0.4 * self.platforms[i].width)
+ x = (
+ 0.5 * self.platforms[i][0]
+ + 0.5 * self.platforms[i][2]
+ + self.rng.randint(-spread, spread)
+ )
+ self.blocks.append(Block(x, y, "regular"))
+ for block in self.blocks:
+ for platform in self.platforms:
+ if block.get_rect().colliderect(platform.get_rect()):
+ block.x += 550
+ if self.pool:
+ pool_block = Block(
+ self.pool.pool_start_x + self.pool.tile_width,
+ self.pool.y + self.pool.height - block_height,
+ "regular",
+ )
+ pool_block.yields_star = True
+ pool_block.will_explode = False
+ self.blocks.append(pool_block)
+ self.rng.shuffle(self.blocks)
+ self.finalize_blocks()
+
+ # Step 5: a snow ledge with icicles.
+ self.icicles = []
+ if self.longest_platform.y != self.platforms[0].y and (
+ self.level == 1 or self.rng.randint(0, 1) == 0
+ ):
+ ledge = Platform(
+ self.longest_platform[0], focus_height, self.longest_platform.width, style="snow"
+ )
+ for platform in self.platforms:
+ if platform.get_rect().colliderect(ledge.get_rect()):
+ ledge.x, ledge.y = DEFAULT_VALUE, DEFAULT_VALUE
+ self.platforms.append(ledge)
+ self.movable_objects.append(ledge)
+ for i in range(
+ int(ledge[0] + ledge.tile_width * 2), int(ledge[2] - ledge.tile_width * 2), 40
+ ):
+ self.icicles.append(FallingSpike(i, ledge[3]))
+ self.movable_objects.extend(self.icicles)
+
+ # Steps 6-9: foliage, mobs, door, fences.
+ self.generate_foliage()
+ self.generate_mobs(self.longest_platform, self.farthest_platform)
+ self.door = Door(self.farthest_platform[2] - 100, self.farthest_platform[1])
+ self.movable_objects.append(self.door)
+ self.fakedoor = Door(self.platforms[0].x + 10, self.platforms[0].y)
+ self.movable_objects.append(self.fakedoor)
+ self.generate_fences()
+
+ # Step 10: finalize positions, camera and darkness.
+ self.finalize_level(self.farthest_platform)
+ return self
+
+ # -- darkness rendering -----------------------------------------------------------
+
+ @staticmethod
+ def _illuminate(target: pygame.Surface, x: float, y: float, rng: random.Random) -> None:
+ ix, iy = int(x), int(y)
+ rad = rng.randint(215, 245)
+ transp = 255
+ delta = 3
+ clr = 0
+ while rad > 50:
+ pygame.draw.circle(target, (clr, clr, 0, transp), (ix, iy), rad)
+ rad -= delta
+ transp -= delta
+ clr += delta
+ pygame.draw.circle(target, (clr, clr, 0, transp), (ix, iy), rad)
+
+ def darken(self, surface: pygame.Surface, value: int) -> None:
+ dark = pygame.Surface(surface.get_size(), pygame.SRCALPHA)
+ dark.set_alpha(value)
+ for torch in self.torches:
+ if torch.burning:
+ self._illuminate(dark, torch.x + 0.5 * torch.width, torch.y + 5, self.rng)
+ surface.blit(dark, (0, 0))
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..cf288fa
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,29 @@
+"""Shared pytest configuration.
+
+Forces pygame to run with no real display or audio so the whole suite is headless and
+CI-friendly. These environment variables must be set before pygame is first imported.
+"""
+
+from __future__ import annotations
+
+import os
+
+os.environ.setdefault("SDL_VIDEODRIVER", "dummy")
+os.environ.setdefault("SDL_AUDIODRIVER", "dummy")
+os.environ.setdefault("PYGAME_HIDE_SUPPORT_PROMPT", "1")
+
+import pygame
+import pytest
+
+
+@pytest.fixture
+def pygame_ready():
+ """Ensure pygame and a (dummy) display surface are initialized for the test.
+
+ Robust to a prior test having torn pygame down (e.g. the app smoke test).
+ """
+ if not pygame.get_init():
+ pygame.init()
+ if pygame.display.get_surface() is None:
+ pygame.display.set_mode((64, 64))
+ yield
diff --git a/tests/test_assets.py b/tests/test_assets.py
new file mode 100644
index 0000000..9bd751c
--- /dev/null
+++ b/tests/test_assets.py
@@ -0,0 +1,76 @@
+"""Asset existence: every referenced asset is present on disk, case-sensitively.
+
+This guards against two real bugs: (1) case-mismatched filenames that work on macOS/Windows
+but break on Linux, and (2) deleting an asset during the prune/optimize pass that the game
+actually loads via a dynamically-constructed path (which static scans miss). The dynamic
+families below are expanded explicitly.
+"""
+
+from __future__ import annotations
+
+import pytest
+
+from exit_dash.core.paths import asset_root
+
+THEMES = ["castle", "dirt", "grass", "sand", "snow", "stone"]
+KEY_COLORS = ["blue", "green", "red", "yellow"]
+SLIME_COLORS = ["Blue", "Green"]
+PLAYERS = [1, 2, 3]
+
+
+def _exists_case_sensitive(*parts: str) -> bool:
+ """True only if every path component exists with exactly this case under the assets root."""
+ current = asset_root()
+ for part in parts:
+ if not current.is_dir():
+ return False
+ if part not in {child.name for child in current.iterdir()}:
+ return False
+ current = current / part
+ return True
+
+
+def _check(*parts: str) -> None:
+ assert _exists_case_sensitive(*parts), f"missing asset: {'/'.join(parts)}"
+
+
+def test_asset_root_exists():
+ assert asset_root().is_dir()
+
+
+@pytest.mark.parametrize("theme", THEMES)
+def test_terrain_tiles(theme):
+ for suffix in ("Mid", "CliffLeft", "CliffRight"):
+ _check("environment", "main", f"{theme}{suffix}.png")
+
+
+@pytest.mark.parametrize("color", KEY_COLORS)
+def test_keys(color):
+ _check("environment", "main", f"key{color}.png")
+
+
+def test_doors():
+ for piece in ("door_openMid", "door_openTop", "door_closedMid", "door_closedTop"):
+ _check("environment", "main", f"{piece}.png")
+
+
+def test_hud_digits():
+ for digit in range(10):
+ _check("hud", f"hud_{digit}.png")
+
+
+def test_explosion_frames():
+ for frame in range(3):
+ _check("environment", "main", f"explosion{frame}.png")
+
+
+@pytest.mark.parametrize("color", SLIME_COLORS)
+def test_slime_frames(color):
+ for suffix in ("walk", "walkR", "squashed", "squashedR"):
+ _check("enemies", "slime", f"slime{color}_{suffix}.png")
+
+
+@pytest.mark.parametrize("player", PLAYERS)
+def test_player_sprites(player):
+ _check("character", "main", f"p{player}_front.png")
+ _check("character", "main", f"p{player}_walk", "PNG", f"p{player}_walk1.png")
diff --git a/tests/test_audio.py b/tests/test_audio.py
new file mode 100644
index 0000000..f60d0bd
--- /dev/null
+++ b/tests/test_audio.py
@@ -0,0 +1,38 @@
+"""Audio assets: the curated music tracks and sound effects load in pygame.
+
+Guards the MP3/WAV->OGG conversion done in the asset pipeline. Skips automatically if no
+audio mixer is available (some CI containers).
+"""
+
+from __future__ import annotations
+
+import pygame
+import pytest
+
+from exit_dash.core.paths import asset_path
+
+MUSIC = ["char1_3.ogg", "waking_devil.ogg", "gameover.ogg", "menuloop.ogg"]
+SOUND_EFFECTS = ["synthetic_explosion_1.ogg"]
+
+
+@pytest.fixture(scope="module")
+def mixer():
+ try:
+ pygame.mixer.init()
+ except pygame.error:
+ pytest.skip("audio mixer unavailable")
+ if pygame.mixer.get_init() is None:
+ pytest.skip("audio mixer unavailable")
+ yield
+ pygame.mixer.quit()
+
+
+@pytest.mark.parametrize("name", MUSIC)
+def test_music_track_loads(mixer, name):
+ pygame.mixer.music.load(str(asset_path("music", name)))
+
+
+@pytest.mark.parametrize("name", SOUND_EFFECTS)
+def test_sound_effect_loads(mixer, name):
+ sound = pygame.mixer.Sound(str(asset_path("sounds", name)))
+ assert sound.get_length() > 0
diff --git a/tests/test_entities.py b/tests/test_entities.py
new file mode 100644
index 0000000..31e5eec
--- /dev/null
+++ b/tests/test_entities.py
@@ -0,0 +1,73 @@
+"""Smoke-construct every entity headless to catch missing assets and import errors."""
+
+from __future__ import annotations
+
+import pytest
+
+from exit_dash.entities.background import Background
+from exit_dash.entities.block import Block
+from exit_dash.entities.character import Character
+from exit_dash.entities.checkpoint import Checkpoint
+from exit_dash.entities.door import Door
+from exit_dash.entities.enemy import AICharacter
+from exit_dash.entities.foliage import BackgroundFoliage
+from exit_dash.entities.key import Key
+from exit_dash.entities.platform import Platform
+from exit_dash.entities.player import PlayableCharacter
+from exit_dash.entities.pool import Pool
+from exit_dash.entities.spike import FallingSpike
+from exit_dash.entities.torch import Torch
+
+
+@pytest.mark.parametrize("which_char", [1, 2, 3])
+def test_player_and_character_construct(pygame_ready, which_char):
+ char = Character(0, 0, which_char=which_char)
+ assert char.width > 0 and char.height > 0
+ player = PlayableCharacter(0, 0, which_char=which_char)
+ assert player.lives > 0
+
+
+@pytest.mark.parametrize("mob", ["slime", "snail", "fly", "fish"])
+def test_enemy_constructs_and_draws(pygame_ready, mob):
+ import pygame
+
+ enemy = AICharacter(0, 0, 2, 0, properties=(mob, -1, -1))
+ surface = pygame.Surface((64, 64))
+ enemy.draw(surface) # forces lazy image selection for this mob type
+ assert enemy.width > 0
+
+
+def test_world_objects_construct(pygame_ready):
+ Platform(0, 500, 300, style="stone")
+ Block(100, 100, "coin")
+ Block(100, 100, "explosive")
+ Pool(0, 500, 300, 120, style="stone")
+ FallingSpike(50, 50)
+ Door(100, 500)
+ Key(100, 100, "blue")
+ Checkpoint(100, 100)
+ BackgroundFoliage(100, 100)
+ Torch(100, 100)
+
+
+def test_background_constructs(pygame_ready):
+ import pygame
+
+ Background(pygame.Surface((200, 150)), 1280, 720)
+
+
+def test_player_jump_and_hud_draw(pygame_ready):
+ import pygame
+
+ from exit_dash.core.input import PlayerInput
+
+ player = PlayableCharacter(100, 400, which_char=1)
+ platform = Platform(0, 500, 600, style="stone")
+ player.on_ground = True
+ player.can_jump = True # jump was released on a prior frame (the latch is armed)
+ # Pressing jump from the ground should launch the player.
+ player.move(PlayerInput(jump=True), [platform], [], [], 1280, 720, autoscroll=False)
+ assert player.jumping is True
+ assert player.vy == -35 # PlayableCharacter jump_speed for char 1
+ surface = pygame.Surface((1280, 720))
+ player.draw(surface) # HUD draw must not raise
diff --git a/tests/test_hints.py b/tests/test_hints.py
new file mode 100644
index 0000000..548d565
--- /dev/null
+++ b/tests/test_hints.py
@@ -0,0 +1,46 @@
+"""Hint text: ``{TOKEN}`` interpolation and per-level lookup."""
+
+from __future__ import annotations
+
+from exit_dash.core.keybindings import key_names
+from exit_dash.world.hints import hint_for_level, interpret_hint
+
+FAKE_NAMES = {"DUCK": "down", "ACTION": "up", "LEFT": "left", "RIGHT": "right"}
+
+
+def test_token_is_substituted_and_quoted():
+ assert interpret_hint("Use {DUCK} to duck", FAKE_NAMES) == 'Use "down" to duck'
+
+
+def test_none_becomes_empty():
+ assert interpret_hint("None", FAKE_NAMES) == ""
+
+
+def test_text_without_token_is_unchanged():
+ assert interpret_hint("Hey, who turned out the lights?", FAKE_NAMES) == (
+ "Hey, who turned out the lights?"
+ )
+
+
+def test_token_only():
+ assert interpret_hint("{ACTION}", FAKE_NAMES) == '"up"'
+
+
+def test_trailing_newline_preserved():
+ assert interpret_hint("Jump with {ACTION}\n", FAKE_NAMES) == 'Jump with "up"\n'
+
+
+def test_key_names_resolve_real_keys(pygame_ready):
+ names = key_names()
+ assert names["DUCK"] == "down"
+ assert names["ACTION"] == "up"
+
+
+def test_level_1_hint_substitutes_token(pygame_ready):
+ hint = hint_for_level(1, key_names())
+ assert hint # level 1 has a hint
+ assert "{" not in hint and "}" not in hint # token was substituted
+
+
+def test_out_of_range_level_returns_empty(pygame_ready):
+ assert hint_for_level(999, key_names()) == ""
diff --git a/tests/test_level_scene.py b/tests/test_level_scene.py
new file mode 100644
index 0000000..f9b0080
--- /dev/null
+++ b/tests/test_level_scene.py
@@ -0,0 +1,24 @@
+"""LevelScene integration: a real level boots and runs headless without the player dying."""
+
+from __future__ import annotations
+
+import pytest
+
+from exit_dash.core.app import Application
+from exit_dash.core.settings import Settings
+from exit_dash.scenes.level import LevelScene
+
+
+@pytest.mark.parametrize("level", [1, 2])
+def test_level_runs_headless(level):
+ settings = Settings(music_enabled=False, developer_mode=False, decorations=True)
+ app = Application(headless=True)
+ scene = LevelScene(level, which_char=1, settings=settings, audio=False)
+ try:
+ frames = app.run(scene, max_frames=200)
+ finally:
+ app.quit()
+
+ assert frames == 200, "the level loop should run to completion without crashing"
+ assert scene.player.visible, "player should not have fallen out of the world"
+ assert scene.player.lives > 0, "player should survive the intro walk-in with no input"
diff --git a/tests/test_levels.py b/tests/test_levels.py
new file mode 100644
index 0000000..1f9d0a5
--- /dev/null
+++ b/tests/test_levels.py
@@ -0,0 +1,48 @@
+"""Level ``.dat`` parsing: shipped levels load, round-trip, and tolerate line endings."""
+
+from __future__ import annotations
+
+import pytest
+
+from exit_dash.core.paths import asset_path
+from exit_dash.world import loader
+from exit_dash.world.level import LevelData
+
+SHIPPED_LEVELS = [1, 2, 3, 4]
+
+
+def _level_path(n: int):
+ return asset_path("levels", f"lvl_{n}.dat")
+
+
+@pytest.mark.parametrize("n", SHIPPED_LEVELS)
+def test_shipped_level_loads(n):
+ level = loader.read_level(_level_path(n))
+ assert isinstance(level, LevelData)
+ assert level.platforms, "every level has at least one platform"
+ assert level.door is not None
+
+
+@pytest.mark.parametrize("n", SHIPPED_LEVELS)
+def test_semantic_round_trip(n):
+ level = loader.read_level(_level_path(n))
+ reparsed = loader.loads(loader.dumps(level, level_number=n))
+ assert reparsed == level
+
+
+def test_level_1_known_values():
+ level = loader.read_level(_level_path(1))
+ first = level.platforms[0]
+ assert (first.x, first.y, first.width) == (1820.0, 894.0, 1050.0)
+
+
+def test_loads_is_line_ending_agnostic():
+ lf = loader.dumps(loader.read_level(_level_path(1)), level_number=1)
+ crlf = lf.replace("\n", "\r\n")
+ cr = lf.replace("\n", "\r")
+ assert loader.loads(lf) == loader.loads(crlf) == loader.loads(cr)
+
+
+def test_too_short_raises():
+ with pytest.raises(ValueError, match="expected at least"):
+ loader.loads("header\n1\n2\n3\n")
diff --git a/tests/test_physics.py b/tests/test_physics.py
new file mode 100644
index 0000000..3247834
--- /dev/null
+++ b/tests/test_physics.py
@@ -0,0 +1,70 @@
+"""Golden physics tests: the ported motion/collision must match the original exactly.
+
+The fixed-timestep integration is deterministic, so the jump arc has exact expected
+values. Terminal velocity (capped at ``platform.height - 5``) stays below the landing
+band height (``platform.height + 35``), which is what prevents tunnelling — verified here.
+"""
+
+from __future__ import annotations
+
+import pytest
+
+from exit_dash.entities.character import Character
+from exit_dash.entities.platform import Platform
+
+
+@pytest.fixture
+def platform(pygame_ready):
+ # Wide stone platform with its top at y=500.
+ return Platform(0, 500, 600, style="stone")
+
+
+def test_jump_sets_expected_velocity(platform):
+ char = Character(100, 100, which_char=1)
+ char.on_ground = False
+ char.jump()
+ assert char.vy == -30 # floor(-1.0 * JUMP_SPEED)
+
+
+def test_jump_arc_apex_is_deterministic(platform):
+ char = Character(100, 100, which_char=1)
+ char.on_ground = False
+ char.jump()
+ start_y = char.y
+
+ # vy goes -30, -27.5, ... reaching 0 after 12 steps; total rise = 2.5*(1+..+12) = 195.
+ for _ in range(12):
+ char.update_motion([platform])
+
+ assert char.vy == 0.0
+ assert char.y == start_y - 195
+
+
+def test_lands_on_platform_without_tunnelling(platform):
+ char = Character(100, 0, which_char=1)
+ char.on_ground = False
+ # Feet just above the platform top, falling near terminal velocity.
+ char.y = platform.y - char.height - 5
+ char.vy = 60
+
+ char.update_motion([platform])
+ char.collide([platform], [], [], None, None)
+
+ assert char.on_ground is True
+ assert char.y == platform.y - char.height # resting exactly on top, no overshoot
+
+
+def test_terminal_velocity_is_capped(platform):
+ char = Character(100, 0, which_char=1)
+ char.on_ground = False
+ char.vy = platform.height + 100 # way over terminal
+ char.update_motion([platform])
+ # Capped to platform.height - 5, then gravity is added once.
+ assert char.vy == (platform.height - 5) + char.gravity
+
+
+def test_max_jump_height_matches_kinematics(platform):
+ char = Character(100, 100, which_char=1)
+ # jump_time = 30 / 2.5 = 12; max_jump_height = floor(0.5 * 30 * 12) = 180.
+ assert char.jump_time == 12.0
+ assert char.max_jump_height == 180
diff --git a/tests/test_scenes.py b/tests/test_scenes.py
new file mode 100644
index 0000000..459ad25
--- /dev/null
+++ b/tests/test_scenes.py
@@ -0,0 +1,45 @@
+"""Scene-stack transitions between title, level and game-over screens."""
+
+from __future__ import annotations
+
+import pygame
+
+from exit_dash.core.scene import SceneManager
+from exit_dash.core.settings import Settings
+from exit_dash.scenes.gameover import GameOverScene
+from exit_dash.scenes.level import LevelScene
+from exit_dash.scenes.title import TitleScene
+
+
+def _settings() -> Settings:
+ return Settings(music_enabled=False, developer_mode=False)
+
+
+def test_title_starts_chosen_character(pygame_ready):
+ manager = SceneManager(TitleScene(_settings(), audio=False))
+ manager.handle_event(pygame.event.Event(pygame.KEYDOWN, key=pygame.K_2))
+ assert isinstance(manager.current, LevelScene)
+ assert manager.current.which_char == 2
+
+
+def test_title_quits_on_escape(pygame_ready):
+ manager = SceneManager(TitleScene(_settings(), audio=False))
+ manager.handle_event(pygame.event.Event(pygame.KEYDOWN, key=pygame.K_ESCAPE))
+ assert not manager.running
+
+
+def test_gameover_returns_to_title(pygame_ready):
+ manager = SceneManager(GameOverScene(won=True, settings=_settings(), audio=False))
+ manager.handle_event(pygame.event.Event(pygame.KEYDOWN, key=pygame.K_RETURN))
+ assert isinstance(manager.current, TitleScene)
+
+
+def test_level_win_goes_to_gameover(pygame_ready):
+ scene = LevelScene(1, 1, _settings(), audio=False, final_level=1)
+ # Completing the final level should hand off to a "won" game-over screen.
+ transition = scene._advance_level()
+ from exit_dash.core.scene import Replace
+
+ assert isinstance(transition, Replace)
+ assert isinstance(transition.scene, GameOverScene)
+ assert transition.scene.won is True
diff --git a/tests/test_settings.py b/tests/test_settings.py
new file mode 100644
index 0000000..dc46ad1
--- /dev/null
+++ b/tests/test_settings.py
@@ -0,0 +1,66 @@
+"""Settings: JSON round-trip, tolerant parsing, and legacy ``.cfg`` migration."""
+
+from __future__ import annotations
+
+from exit_dash.core.settings import (
+ LEGACY_FILENAME,
+ SETTINGS_FILENAME,
+ Settings,
+ load_settings,
+ save_settings,
+)
+
+# The actual values from the original repo's settings.cfg.
+LEGACY_CFG = (
+ "Game Settings Configuration - DO NOT MODIFY THIS FILE! Change settings in-game!\n"
+ "True\nTrue\nTrue\nTrue\nTrue\nTrue\n0.926315789474\n1080p"
+)
+
+
+def test_json_round_trip(tmp_path):
+ settings = Settings(developer_mode=True, volume=0.3, resolution="720p", fullscreen=False)
+ save_settings(settings, config_dir=tmp_path)
+ assert load_settings(config_dir=tmp_path) == settings
+
+
+def test_from_dict_ignores_unknown_and_defaults_missing():
+ settings = Settings.from_dict({"volume": 0.7, "totally_unknown_key": 123})
+ assert settings.volume == 0.7
+ assert settings.antialiasing is True # default preserved
+
+
+def test_legacy_cfg_migration(tmp_path):
+ (tmp_path / LEGACY_FILENAME).write_text(LEGACY_CFG, encoding="utf-8")
+
+ settings = load_settings(config_dir=tmp_path)
+
+ assert settings.developer_mode is True
+ assert settings.antialiasing is True
+ assert settings.decorations is True
+ assert settings.music_enabled is True
+ assert settings.fullscreen is True
+ assert abs(settings.volume - 0.926315789474) < 1e-9
+ assert settings.resolution == "1080p"
+
+ # Migration writes JSON and is sticky: a second load reads JSON and matches.
+ assert (tmp_path / SETTINGS_FILENAME).is_file()
+ assert load_settings(config_dir=tmp_path) == settings
+
+
+def test_from_legacy_cfg_parses_false_and_skips_stablefps():
+ # body: developerMode, antialiasing, stableFPS, decorations, doPlayMusic, fullscreen, volume, resolution
+ text = "header\nFalse\nFalse\nTrue\nFalse\nFalse\nTrue\n0.5\n720p"
+ settings = Settings.from_legacy_cfg(text)
+ assert settings.developer_mode is False
+ assert settings.antialiasing is False
+ assert settings.decorations is False # body[3]
+ assert settings.music_enabled is False # body[4]
+ assert settings.fullscreen is True # body[5]
+ assert settings.volume == 0.5
+ assert settings.resolution == "720p"
+
+
+def test_defaults_written_when_nothing_exists(tmp_path):
+ settings = load_settings(config_dir=tmp_path)
+ assert settings == Settings()
+ assert (tmp_path / SETTINGS_FILENAME).is_file()
diff --git a/tests/test_smoke.py b/tests/test_smoke.py
new file mode 100644
index 0000000..482a41f
--- /dev/null
+++ b/tests/test_smoke.py
@@ -0,0 +1,35 @@
+"""Smoke test: the engine boots headless and runs a bounded, deterministic loop."""
+
+from __future__ import annotations
+
+import pygame
+
+from exit_dash.core.app import Application
+from exit_dash.core.input import InputState
+from exit_dash.core.scene import Scene, Transition
+
+
+class _NullScene(Scene):
+ """A scene that counts its fixed-step updates and draws a solid fill."""
+
+ def __init__(self) -> None:
+ self.updates = 0
+
+ def update(self, dt: float, inp: InputState) -> Transition | None:
+ self.updates += 1
+ return None
+
+ def draw(self, surface: pygame.Surface, alpha: float) -> None:
+ surface.fill((0, 0, 0))
+
+
+def test_headless_runs_exact_frame_count():
+ app = Application(headless=True)
+ scene = _NullScene()
+ try:
+ frames = app.run(scene, max_frames=120)
+ finally:
+ app.quit()
+ # Deterministic headless mode advances exactly one fixed step per rendered frame.
+ assert frames == 120
+ assert scene.updates == 120
diff --git a/tests/test_world.py b/tests/test_world.py
new file mode 100644
index 0000000..01bc893
--- /dev/null
+++ b/tests/test_world.py
@@ -0,0 +1,64 @@
+"""World assembly from saved level data (the load path)."""
+
+from __future__ import annotations
+
+import random
+
+import pytest
+
+from exit_dash.core.paths import asset_path
+from exit_dash.entities.player import PlayableCharacter
+from exit_dash.world import loader
+from exit_dash.world.world import World
+
+
+@pytest.fixture
+def player(pygame_ready):
+ return PlayableCharacter(0, 0, which_char=1)
+
+
+@pytest.mark.parametrize("level", [1, 2, 3, 4])
+def test_world_builds_from_shipped_level(player, level):
+ data = loader.read_level(asset_path("levels", f"lvl_{level}.dat"))
+ world = World.from_level_data(
+ data,
+ player=player,
+ screen_w=1280,
+ screen_h=720,
+ theme="stone",
+ level=level,
+ rng=random.Random(level),
+ )
+
+ assert len(world.platforms) >= 1
+ assert world.door is not None
+ assert world.fakedoor is not None
+ assert world.keys, "a level must have at least one key to win"
+ assert world.enemies, "generate_mobs places at least the patrol fly"
+ # Player is placed on the first platform and starts as a CPU-driven walk-in.
+ assert world.player.cpu_controlled is True
+ # Everything that scrolls is registered with the camera's movable set.
+ assert world.background is None or world.background in world.movable_objects
+
+
+def test_world_is_deterministic_for_fixed_seed(player):
+ data = loader.read_level(asset_path("levels", "lvl_1.dat"))
+ p2 = PlayableCharacter(0, 0, which_char=1)
+ w1 = World.from_level_data(
+ data, player=player, screen_w=1280, screen_h=720, rng=random.Random(7)
+ )
+ w2 = World.from_level_data(data, player=p2, screen_w=1280, screen_h=720, rng=random.Random(7))
+ assert len(w1.enemies) == len(w2.enemies)
+ assert [e.mob_type for e in w1.enemies] == [e.mob_type for e in w2.enemies]
+ assert w1.autoscroll == w2.autoscroll
+
+
+def test_generated_level_is_reproducible_from_seed(player):
+ p2 = PlayableCharacter(0, 0, which_char=1)
+ w1 = World(player, 1280, 720, theme="stone", level=3, rng=random.Random()).generate(15, seed=42)
+ w2 = World(p2, 1280, 720, theme="stone", level=3, rng=random.Random()).generate(15, seed=42)
+ assert len(w1.platforms) == len(w2.platforms)
+ assert [round(p.x, 3) for p in w1.platforms] == [round(p.x, 3) for p in w2.platforms]
+ assert len(w1.blocks) == len(w2.blocks)
+ assert [e.mob_type for e in w1.enemies] == [e.mob_type for e in w2.enemies]
+ assert w1.door is not None and w1.keys
diff --git a/ui/blue_boxCheckmark.png b/ui/blue_boxCheckmark.png
deleted file mode 100644
index 386ba50..0000000
Binary files a/ui/blue_boxCheckmark.png and /dev/null differ
diff --git a/ui/blue_boxCross.png b/ui/blue_boxCross.png
deleted file mode 100644
index 873ced7..0000000
Binary files a/ui/blue_boxCross.png and /dev/null differ
diff --git a/ui/blue_boxTick.png b/ui/blue_boxTick.png
deleted file mode 100644
index 234e09f..0000000
Binary files a/ui/blue_boxTick.png and /dev/null differ
diff --git a/ui/blue_button00.png b/ui/blue_button00.png
deleted file mode 100644
index 835f3a7..0000000
Binary files a/ui/blue_button00.png and /dev/null differ
diff --git a/ui/blue_button01.png b/ui/blue_button01.png
deleted file mode 100644
index 412e901..0000000
Binary files a/ui/blue_button01.png and /dev/null differ
diff --git a/ui/blue_button02.png b/ui/blue_button02.png
deleted file mode 100644
index 4cd391f..0000000
Binary files a/ui/blue_button02.png and /dev/null differ
diff --git a/ui/blue_button03.png b/ui/blue_button03.png
deleted file mode 100644
index a613356..0000000
Binary files a/ui/blue_button03.png and /dev/null differ
diff --git a/ui/blue_button04.png b/ui/blue_button04.png
deleted file mode 100644
index 0228cd1..0000000
Binary files a/ui/blue_button04.png and /dev/null differ
diff --git a/ui/blue_button05.png b/ui/blue_button05.png
deleted file mode 100644
index 0f1eece..0000000
Binary files a/ui/blue_button05.png and /dev/null differ
diff --git a/ui/blue_button06.png b/ui/blue_button06.png
deleted file mode 100644
index 73dcfd0..0000000
Binary files a/ui/blue_button06.png and /dev/null differ
diff --git a/ui/blue_button07.png b/ui/blue_button07.png
deleted file mode 100644
index 60a1055..0000000
Binary files a/ui/blue_button07.png and /dev/null differ
diff --git a/ui/blue_button08.png b/ui/blue_button08.png
deleted file mode 100644
index f146c5d..0000000
Binary files a/ui/blue_button08.png and /dev/null differ
diff --git a/ui/blue_button09.png b/ui/blue_button09.png
deleted file mode 100644
index 5ec356a..0000000
Binary files a/ui/blue_button09.png and /dev/null differ
diff --git a/ui/blue_button10.png b/ui/blue_button10.png
deleted file mode 100644
index dc9d311..0000000
Binary files a/ui/blue_button10.png and /dev/null differ
diff --git a/ui/blue_button11.png b/ui/blue_button11.png
deleted file mode 100644
index c843825..0000000
Binary files a/ui/blue_button11.png and /dev/null differ
diff --git a/ui/blue_button12.png b/ui/blue_button12.png
deleted file mode 100644
index 779c042..0000000
Binary files a/ui/blue_button12.png and /dev/null differ
diff --git a/ui/blue_button13.png b/ui/blue_button13.png
deleted file mode 100644
index ecab5b0..0000000
Binary files a/ui/blue_button13.png and /dev/null differ
diff --git a/ui/blue_checkmark.png b/ui/blue_checkmark.png
deleted file mode 100644
index 8cdea35..0000000
Binary files a/ui/blue_checkmark.png and /dev/null differ
diff --git a/ui/blue_circle.png b/ui/blue_circle.png
deleted file mode 100644
index 04018c5..0000000
Binary files a/ui/blue_circle.png and /dev/null differ
diff --git a/ui/blue_cross.png b/ui/blue_cross.png
deleted file mode 100644
index d242c33..0000000
Binary files a/ui/blue_cross.png and /dev/null differ
diff --git a/ui/blue_panel.png b/ui/blue_panel.png
deleted file mode 100644
index c4cea90..0000000
Binary files a/ui/blue_panel.png and /dev/null differ
diff --git a/ui/blue_sliderDown.png b/ui/blue_sliderDown.png
deleted file mode 100644
index 44f95d1..0000000
Binary files a/ui/blue_sliderDown.png and /dev/null differ
diff --git a/ui/blue_sliderLeft.png b/ui/blue_sliderLeft.png
deleted file mode 100644
index 11a1276..0000000
Binary files a/ui/blue_sliderLeft.png and /dev/null differ
diff --git a/ui/blue_sliderRight.png b/ui/blue_sliderRight.png
deleted file mode 100644
index 59888e8..0000000
Binary files a/ui/blue_sliderRight.png and /dev/null differ
diff --git a/ui/blue_sliderUp.png b/ui/blue_sliderUp.png
deleted file mode 100644
index 1c58fa1..0000000
Binary files a/ui/blue_sliderUp.png and /dev/null differ
diff --git a/ui/blue_tick.png b/ui/blue_tick.png
deleted file mode 100644
index efaf87c..0000000
Binary files a/ui/blue_tick.png and /dev/null differ
diff --git a/ui/dropdownBottom.png b/ui/dropdownBottom.png
deleted file mode 100644
index e3d692a..0000000
Binary files a/ui/dropdownBottom.png and /dev/null differ
diff --git a/ui/dropdownMid.png b/ui/dropdownMid.png
deleted file mode 100644
index 2424f7e..0000000
Binary files a/ui/dropdownMid.png and /dev/null differ
diff --git a/ui/dropdownTop.png b/ui/dropdownTop.png
deleted file mode 100644
index 775ea78..0000000
Binary files a/ui/dropdownTop.png and /dev/null differ
diff --git a/ui/green_boxCheckmark.png b/ui/green_boxCheckmark.png
deleted file mode 100644
index 7affa02..0000000
Binary files a/ui/green_boxCheckmark.png and /dev/null differ
diff --git a/ui/green_boxCross.png b/ui/green_boxCross.png
deleted file mode 100644
index f189734..0000000
Binary files a/ui/green_boxCross.png and /dev/null differ
diff --git a/ui/green_boxTick.png b/ui/green_boxTick.png
deleted file mode 100644
index ffe9bb4..0000000
Binary files a/ui/green_boxTick.png and /dev/null differ
diff --git a/ui/green_button00.png b/ui/green_button00.png
deleted file mode 100644
index 6441c4e..0000000
Binary files a/ui/green_button00.png and /dev/null differ
diff --git a/ui/green_button01.png b/ui/green_button01.png
deleted file mode 100644
index d16167d..0000000
Binary files a/ui/green_button01.png and /dev/null differ
diff --git a/ui/green_button02.png b/ui/green_button02.png
deleted file mode 100644
index 07bf056..0000000
Binary files a/ui/green_button02.png and /dev/null differ
diff --git a/ui/green_button03.png b/ui/green_button03.png
deleted file mode 100644
index 195fa3b..0000000
Binary files a/ui/green_button03.png and /dev/null differ
diff --git a/ui/green_button04.png b/ui/green_button04.png
deleted file mode 100644
index 2c5d3cb..0000000
Binary files a/ui/green_button04.png and /dev/null differ
diff --git a/ui/green_button05.png b/ui/green_button05.png
deleted file mode 100644
index 5fb6f49..0000000
Binary files a/ui/green_button05.png and /dev/null differ
diff --git a/ui/green_button06.png b/ui/green_button06.png
deleted file mode 100644
index 8ec8548..0000000
Binary files a/ui/green_button06.png and /dev/null differ
diff --git a/ui/green_button07.png b/ui/green_button07.png
deleted file mode 100644
index 9aac193..0000000
Binary files a/ui/green_button07.png and /dev/null differ
diff --git a/ui/green_button08.png b/ui/green_button08.png
deleted file mode 100644
index 5fa91be..0000000
Binary files a/ui/green_button08.png and /dev/null differ
diff --git a/ui/green_button09.png b/ui/green_button09.png
deleted file mode 100644
index 1da6a09..0000000
Binary files a/ui/green_button09.png and /dev/null differ
diff --git a/ui/green_button10.png b/ui/green_button10.png
deleted file mode 100644
index 0a3ad79..0000000
Binary files a/ui/green_button10.png and /dev/null differ
diff --git a/ui/green_button11.png b/ui/green_button11.png
deleted file mode 100644
index 7bca526..0000000
Binary files a/ui/green_button11.png and /dev/null differ
diff --git a/ui/green_button12.png b/ui/green_button12.png
deleted file mode 100644
index c2215a7..0000000
Binary files a/ui/green_button12.png and /dev/null differ
diff --git a/ui/green_button13.png b/ui/green_button13.png
deleted file mode 100644
index 61eb60e..0000000
Binary files a/ui/green_button13.png and /dev/null differ
diff --git a/ui/green_checkmark.png b/ui/green_checkmark.png
deleted file mode 100644
index 3ad298e..0000000
Binary files a/ui/green_checkmark.png and /dev/null differ
diff --git a/ui/green_circle.png b/ui/green_circle.png
deleted file mode 100644
index 0e31c2e..0000000
Binary files a/ui/green_circle.png and /dev/null differ
diff --git a/ui/green_cross.png b/ui/green_cross.png
deleted file mode 100644
index 89af6fa..0000000
Binary files a/ui/green_cross.png and /dev/null differ
diff --git a/ui/green_panel.png b/ui/green_panel.png
deleted file mode 100644
index ef443df..0000000
Binary files a/ui/green_panel.png and /dev/null differ
diff --git a/ui/green_sliderDown.png b/ui/green_sliderDown.png
deleted file mode 100644
index 329cfdc..0000000
Binary files a/ui/green_sliderDown.png and /dev/null differ
diff --git a/ui/green_sliderLeft.png b/ui/green_sliderLeft.png
deleted file mode 100644
index 27e1c70..0000000
Binary files a/ui/green_sliderLeft.png and /dev/null differ
diff --git a/ui/green_sliderRight.png b/ui/green_sliderRight.png
deleted file mode 100644
index bc22a14..0000000
Binary files a/ui/green_sliderRight.png and /dev/null differ
diff --git a/ui/green_sliderUp.png b/ui/green_sliderUp.png
deleted file mode 100644
index 2e4761f..0000000
Binary files a/ui/green_sliderUp.png and /dev/null differ
diff --git a/ui/green_tick.png b/ui/green_tick.png
deleted file mode 100644
index f0c945d..0000000
Binary files a/ui/green_tick.png and /dev/null differ
diff --git a/ui/grey_arrowDownGrey.png b/ui/grey_arrowDownGrey.png
deleted file mode 100644
index b81aef7..0000000
Binary files a/ui/grey_arrowDownGrey.png and /dev/null differ
diff --git a/ui/grey_arrowDownWhite.png b/ui/grey_arrowDownWhite.png
deleted file mode 100644
index 75b4c3a..0000000
Binary files a/ui/grey_arrowDownWhite.png and /dev/null differ
diff --git a/ui/grey_arrowUpGrey.png b/ui/grey_arrowUpGrey.png
deleted file mode 100644
index fff76a1..0000000
Binary files a/ui/grey_arrowUpGrey.png and /dev/null differ
diff --git a/ui/grey_arrowUpWhite.png b/ui/grey_arrowUpWhite.png
deleted file mode 100644
index 80c42bc..0000000
Binary files a/ui/grey_arrowUpWhite.png and /dev/null differ
diff --git a/ui/grey_box.png b/ui/grey_box.png
deleted file mode 100644
index f17bb8f..0000000
Binary files a/ui/grey_box.png and /dev/null differ
diff --git a/ui/grey_boxCheckmark.png b/ui/grey_boxCheckmark.png
deleted file mode 100644
index 3afdaf4..0000000
Binary files a/ui/grey_boxCheckmark.png and /dev/null differ
diff --git a/ui/grey_boxCross.png b/ui/grey_boxCross.png
deleted file mode 100644
index 48fa219..0000000
Binary files a/ui/grey_boxCross.png and /dev/null differ
diff --git a/ui/grey_boxTick.png b/ui/grey_boxTick.png
deleted file mode 100644
index 42baa8a..0000000
Binary files a/ui/grey_boxTick.png and /dev/null differ
diff --git a/ui/grey_button00.png b/ui/grey_button00.png
deleted file mode 100644
index 1a365e7..0000000
Binary files a/ui/grey_button00.png and /dev/null differ
diff --git a/ui/grey_button01.png b/ui/grey_button01.png
deleted file mode 100644
index 5ea9408..0000000
Binary files a/ui/grey_button01.png and /dev/null differ
diff --git a/ui/grey_button02.png b/ui/grey_button02.png
deleted file mode 100644
index 662b16a..0000000
Binary files a/ui/grey_button02.png and /dev/null differ
diff --git a/ui/grey_button03.png b/ui/grey_button03.png
deleted file mode 100644
index cf556e1..0000000
Binary files a/ui/grey_button03.png and /dev/null differ
diff --git a/ui/grey_button04.png b/ui/grey_button04.png
deleted file mode 100644
index 3d0049d..0000000
Binary files a/ui/grey_button04.png and /dev/null differ
diff --git a/ui/grey_button05.png b/ui/grey_button05.png
deleted file mode 100644
index 7dc23c6..0000000
Binary files a/ui/grey_button05.png and /dev/null differ
diff --git a/ui/grey_button06.png b/ui/grey_button06.png
deleted file mode 100644
index 96de926..0000000
Binary files a/ui/grey_button06.png and /dev/null differ
diff --git a/ui/grey_button07.png b/ui/grey_button07.png
deleted file mode 100644
index caa8978..0000000
Binary files a/ui/grey_button07.png and /dev/null differ
diff --git a/ui/grey_button08.png b/ui/grey_button08.png
deleted file mode 100644
index a8666ab..0000000
Binary files a/ui/grey_button08.png and /dev/null differ
diff --git a/ui/grey_button09.png b/ui/grey_button09.png
deleted file mode 100644
index 186cf0d..0000000
Binary files a/ui/grey_button09.png and /dev/null differ
diff --git a/ui/grey_button10.png b/ui/grey_button10.png
deleted file mode 100644
index ff929a1..0000000
Binary files a/ui/grey_button10.png and /dev/null differ
diff --git a/ui/grey_button11.png b/ui/grey_button11.png
deleted file mode 100644
index 5842207..0000000
Binary files a/ui/grey_button11.png and /dev/null differ
diff --git a/ui/grey_button12.png b/ui/grey_button12.png
deleted file mode 100644
index dcdd394..0000000
Binary files a/ui/grey_button12.png and /dev/null differ
diff --git a/ui/grey_button13.png b/ui/grey_button13.png
deleted file mode 100644
index d25f99e..0000000
Binary files a/ui/grey_button13.png and /dev/null differ
diff --git a/ui/grey_button14.png b/ui/grey_button14.png
deleted file mode 100644
index 9919f34..0000000
Binary files a/ui/grey_button14.png and /dev/null differ
diff --git a/ui/grey_button15.png b/ui/grey_button15.png
deleted file mode 100644
index 6f0223d..0000000
Binary files a/ui/grey_button15.png and /dev/null differ
diff --git a/ui/grey_checkmarkGrey.png b/ui/grey_checkmarkGrey.png
deleted file mode 100644
index a57f994..0000000
Binary files a/ui/grey_checkmarkGrey.png and /dev/null differ
diff --git a/ui/grey_checkmarkWhite.png b/ui/grey_checkmarkWhite.png
deleted file mode 100644
index 02d04cc..0000000
Binary files a/ui/grey_checkmarkWhite.png and /dev/null differ
diff --git a/ui/grey_circle.png b/ui/grey_circle.png
deleted file mode 100644
index 877a3e0..0000000
Binary files a/ui/grey_circle.png and /dev/null differ
diff --git a/ui/grey_crossGrey.png b/ui/grey_crossGrey.png
deleted file mode 100644
index 725b7ad..0000000
Binary files a/ui/grey_crossGrey.png and /dev/null differ
diff --git a/ui/grey_crossWhite.png b/ui/grey_crossWhite.png
deleted file mode 100644
index 03f8189..0000000
Binary files a/ui/grey_crossWhite.png and /dev/null differ
diff --git a/ui/grey_panel.png b/ui/grey_panel.png
deleted file mode 100644
index 3d6f82c..0000000
Binary files a/ui/grey_panel.png and /dev/null differ
diff --git a/ui/grey_sliderDown.png b/ui/grey_sliderDown.png
deleted file mode 100644
index 0ec6a81..0000000
Binary files a/ui/grey_sliderDown.png and /dev/null differ
diff --git a/ui/grey_sliderEnd.png b/ui/grey_sliderEnd.png
deleted file mode 100644
index fe0856b..0000000
Binary files a/ui/grey_sliderEnd.png and /dev/null differ
diff --git a/ui/grey_sliderHorizontal.png b/ui/grey_sliderHorizontal.png
deleted file mode 100644
index d28abb9..0000000
Binary files a/ui/grey_sliderHorizontal.png and /dev/null differ
diff --git a/ui/grey_sliderLeft.png b/ui/grey_sliderLeft.png
deleted file mode 100644
index a70821e..0000000
Binary files a/ui/grey_sliderLeft.png and /dev/null differ
diff --git a/ui/grey_sliderRight.png b/ui/grey_sliderRight.png
deleted file mode 100644
index 33ad48d..0000000
Binary files a/ui/grey_sliderRight.png and /dev/null differ
diff --git a/ui/grey_sliderUp.png b/ui/grey_sliderUp.png
deleted file mode 100644
index 257bf33..0000000
Binary files a/ui/grey_sliderUp.png and /dev/null differ
diff --git a/ui/grey_sliderVertical.png b/ui/grey_sliderVertical.png
deleted file mode 100644
index 9b6b304..0000000
Binary files a/ui/grey_sliderVertical.png and /dev/null differ
diff --git a/ui/grey_tickGrey.png b/ui/grey_tickGrey.png
deleted file mode 100644
index 906de74..0000000
Binary files a/ui/grey_tickGrey.png and /dev/null differ
diff --git a/ui/grey_tickWhite.png b/ui/grey_tickWhite.png
deleted file mode 100644
index 38934b4..0000000
Binary files a/ui/grey_tickWhite.png and /dev/null differ
diff --git a/ui/license.txt b/ui/license.txt
deleted file mode 100644
index 7c85974..0000000
--- a/ui/license.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-
-###############################################################################
-
- UI pack by Kenney Vleugels (www.kenney.nl)
-
- ------------------------------
-
- License (CC0)
- http://creativecommons.org/publicdomain/zero/1.0/
-
- You may use these graphics in personal and commercial projects.
- Credit (Kenney or www.kenney.nl) would be nice but is not mandatory.
-
-###############################################################################
\ No newline at end of file
diff --git a/ui/red_boxCheckmark.png b/ui/red_boxCheckmark.png
deleted file mode 100644
index 3c319f1..0000000
Binary files a/ui/red_boxCheckmark.png and /dev/null differ
diff --git a/ui/red_boxCross.png b/ui/red_boxCross.png
deleted file mode 100644
index e1da5fe..0000000
Binary files a/ui/red_boxCross.png and /dev/null differ
diff --git a/ui/red_boxTick.png b/ui/red_boxTick.png
deleted file mode 100644
index b75045b..0000000
Binary files a/ui/red_boxTick.png and /dev/null differ
diff --git a/ui/red_button00.png b/ui/red_button00.png
deleted file mode 100644
index 32f5f4c..0000000
Binary files a/ui/red_button00.png and /dev/null differ
diff --git a/ui/red_button01.png b/ui/red_button01.png
deleted file mode 100644
index eb660d0..0000000
Binary files a/ui/red_button01.png and /dev/null differ
diff --git a/ui/red_button02.png b/ui/red_button02.png
deleted file mode 100644
index 5bc305f..0000000
Binary files a/ui/red_button02.png and /dev/null differ
diff --git a/ui/red_button03.png b/ui/red_button03.png
deleted file mode 100644
index e771c39..0000000
Binary files a/ui/red_button03.png and /dev/null differ
diff --git a/ui/red_button04.png b/ui/red_button04.png
deleted file mode 100644
index 41d9deb..0000000
Binary files a/ui/red_button04.png and /dev/null differ
diff --git a/ui/red_button05.png b/ui/red_button05.png
deleted file mode 100644
index edd5094..0000000
Binary files a/ui/red_button05.png and /dev/null differ
diff --git a/ui/red_button06.png b/ui/red_button06.png
deleted file mode 100644
index 7263038..0000000
Binary files a/ui/red_button06.png and /dev/null differ
diff --git a/ui/red_button07.png b/ui/red_button07.png
deleted file mode 100644
index ef3b48e..0000000
Binary files a/ui/red_button07.png and /dev/null differ
diff --git a/ui/red_button08.png b/ui/red_button08.png
deleted file mode 100644
index 4be7f06..0000000
Binary files a/ui/red_button08.png and /dev/null differ
diff --git a/ui/red_button09.png b/ui/red_button09.png
deleted file mode 100644
index b716bb5..0000000
Binary files a/ui/red_button09.png and /dev/null differ
diff --git a/ui/red_button10.png b/ui/red_button10.png
deleted file mode 100644
index 61c182b..0000000
Binary files a/ui/red_button10.png and /dev/null differ
diff --git a/ui/red_button11.png b/ui/red_button11.png
deleted file mode 100644
index 328a3e2..0000000
Binary files a/ui/red_button11.png and /dev/null differ
diff --git a/ui/red_button12.png b/ui/red_button12.png
deleted file mode 100644
index 9dc95fc..0000000
Binary files a/ui/red_button12.png and /dev/null differ
diff --git a/ui/red_button13.png b/ui/red_button13.png
deleted file mode 100644
index c4b5cda..0000000
Binary files a/ui/red_button13.png and /dev/null differ
diff --git a/ui/red_checkmark.png b/ui/red_checkmark.png
deleted file mode 100644
index e0c5255..0000000
Binary files a/ui/red_checkmark.png and /dev/null differ
diff --git a/ui/red_circle.png b/ui/red_circle.png
deleted file mode 100644
index f303f97..0000000
Binary files a/ui/red_circle.png and /dev/null differ
diff --git a/ui/red_cross.png b/ui/red_cross.png
deleted file mode 100644
index 219abee..0000000
Binary files a/ui/red_cross.png and /dev/null differ
diff --git a/ui/red_panel.png b/ui/red_panel.png
deleted file mode 100644
index 8096abe..0000000
Binary files a/ui/red_panel.png and /dev/null differ
diff --git a/ui/red_sliderDown.png b/ui/red_sliderDown.png
deleted file mode 100644
index 33d356c..0000000
Binary files a/ui/red_sliderDown.png and /dev/null differ
diff --git a/ui/red_sliderLeft.png b/ui/red_sliderLeft.png
deleted file mode 100644
index a4735b7..0000000
Binary files a/ui/red_sliderLeft.png and /dev/null differ
diff --git a/ui/red_sliderRight.png b/ui/red_sliderRight.png
deleted file mode 100644
index 0a44bf1..0000000
Binary files a/ui/red_sliderRight.png and /dev/null differ
diff --git a/ui/red_sliderUp.png b/ui/red_sliderUp.png
deleted file mode 100644
index 232dd5a..0000000
Binary files a/ui/red_sliderUp.png and /dev/null differ
diff --git a/ui/red_tick.png b/ui/red_tick.png
deleted file mode 100644
index 6db675b..0000000
Binary files a/ui/red_tick.png and /dev/null differ
diff --git a/ui/yellow_boxCheckmark.png b/ui/yellow_boxCheckmark.png
deleted file mode 100644
index 72fe388..0000000
Binary files a/ui/yellow_boxCheckmark.png and /dev/null differ
diff --git a/ui/yellow_boxCross.png b/ui/yellow_boxCross.png
deleted file mode 100644
index be0df40..0000000
Binary files a/ui/yellow_boxCross.png and /dev/null differ
diff --git a/ui/yellow_boxTick.png b/ui/yellow_boxTick.png
deleted file mode 100644
index 5be09e6..0000000
Binary files a/ui/yellow_boxTick.png and /dev/null differ
diff --git a/ui/yellow_button00.png b/ui/yellow_button00.png
deleted file mode 100644
index b25aceb..0000000
Binary files a/ui/yellow_button00.png and /dev/null differ
diff --git a/ui/yellow_button01.png b/ui/yellow_button01.png
deleted file mode 100644
index b9da991..0000000
Binary files a/ui/yellow_button01.png and /dev/null differ
diff --git a/ui/yellow_button02.png b/ui/yellow_button02.png
deleted file mode 100644
index 15b1f3d..0000000
Binary files a/ui/yellow_button02.png and /dev/null differ
diff --git a/ui/yellow_button03.png b/ui/yellow_button03.png
deleted file mode 100644
index 70ee720..0000000
Binary files a/ui/yellow_button03.png and /dev/null differ
diff --git a/ui/yellow_button04.png b/ui/yellow_button04.png
deleted file mode 100644
index 43e2aae..0000000
Binary files a/ui/yellow_button04.png and /dev/null differ
diff --git a/ui/yellow_button05.png b/ui/yellow_button05.png
deleted file mode 100644
index 1523ad5..0000000
Binary files a/ui/yellow_button05.png and /dev/null differ
diff --git a/ui/yellow_button06.png b/ui/yellow_button06.png
deleted file mode 100644
index 4f53cb1..0000000
Binary files a/ui/yellow_button06.png and /dev/null differ
diff --git a/ui/yellow_button07.png b/ui/yellow_button07.png
deleted file mode 100644
index 71622ea..0000000
Binary files a/ui/yellow_button07.png and /dev/null differ
diff --git a/ui/yellow_button08.png b/ui/yellow_button08.png
deleted file mode 100644
index 77a23b4..0000000
Binary files a/ui/yellow_button08.png and /dev/null differ
diff --git a/ui/yellow_button09.png b/ui/yellow_button09.png
deleted file mode 100644
index e00e7e3..0000000
Binary files a/ui/yellow_button09.png and /dev/null differ
diff --git a/ui/yellow_button10.png b/ui/yellow_button10.png
deleted file mode 100644
index 4c431d6..0000000
Binary files a/ui/yellow_button10.png and /dev/null differ
diff --git a/ui/yellow_button11.png b/ui/yellow_button11.png
deleted file mode 100644
index f3f236a..0000000
Binary files a/ui/yellow_button11.png and /dev/null differ
diff --git a/ui/yellow_button12.png b/ui/yellow_button12.png
deleted file mode 100644
index 8b271b0..0000000
Binary files a/ui/yellow_button12.png and /dev/null differ
diff --git a/ui/yellow_button13.png b/ui/yellow_button13.png
deleted file mode 100644
index f75b3a1..0000000
Binary files a/ui/yellow_button13.png and /dev/null differ
diff --git a/ui/yellow_checkmark.png b/ui/yellow_checkmark.png
deleted file mode 100644
index 95b43cc..0000000
Binary files a/ui/yellow_checkmark.png and /dev/null differ
diff --git a/ui/yellow_circle.png b/ui/yellow_circle.png
deleted file mode 100644
index 1459858..0000000
Binary files a/ui/yellow_circle.png and /dev/null differ
diff --git a/ui/yellow_cross.png b/ui/yellow_cross.png
deleted file mode 100644
index cdd77e0..0000000
Binary files a/ui/yellow_cross.png and /dev/null differ
diff --git a/ui/yellow_panel.png b/ui/yellow_panel.png
deleted file mode 100644
index a377f8c..0000000
Binary files a/ui/yellow_panel.png and /dev/null differ
diff --git a/ui/yellow_sliderDown.png b/ui/yellow_sliderDown.png
deleted file mode 100644
index 5b8f9d6..0000000
Binary files a/ui/yellow_sliderDown.png and /dev/null differ
diff --git a/ui/yellow_sliderLeft.png b/ui/yellow_sliderLeft.png
deleted file mode 100644
index 9ec9498..0000000
Binary files a/ui/yellow_sliderLeft.png and /dev/null differ
diff --git a/ui/yellow_sliderRight.png b/ui/yellow_sliderRight.png
deleted file mode 100644
index 452ae60..0000000
Binary files a/ui/yellow_sliderRight.png and /dev/null differ
diff --git a/ui/yellow_sliderUp.png b/ui/yellow_sliderUp.png
deleted file mode 100644
index 951d291..0000000
Binary files a/ui/yellow_sliderUp.png and /dev/null differ
diff --git a/ui/yellow_tick.png b/ui/yellow_tick.png
deleted file mode 100644
index 6589596..0000000
Binary files a/ui/yellow_tick.png and /dev/null differ
diff --git a/uv.lock b/uv.lock
new file mode 100644
index 0000000..4641f15
--- /dev/null
+++ b/uv.lock
@@ -0,0 +1,564 @@
+version = 1
+revision = 3
+requires-python = ">=3.12"
+resolution-markers = [
+ "python_full_version >= '3.15'",
+ "python_full_version < '3.15'",
+]
+
+[[package]]
+name = "ast-serialize"
+version = "0.5.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/81/9d/09e27731bd5864a9ce04e3244074e674bb8936bf62b45e0357248717adac/ast_serialize-0.5.0.tar.gz", hash = "sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6", size = 61157, upload-time = "2026-05-17T17:48:29.429Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/c0/9a/13dde51ba9e15f8b97957ab7cb0120d0e381524d651c6bd630b9c359227f/ast_serialize-0.5.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a", size = 1183520, upload-time = "2026-05-17T17:47:30.831Z" },
+ { url = "https://files.pythonhosted.org/packages/37/de/5a7f0a9fe68944f536632a5af84676739c7d2582be42deb082634bf3a754/ast_serialize-0.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b", size = 1175779, upload-time = "2026-05-17T17:47:32.551Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/81/0bb853e76e4f6e9a1855d569003c59e19ffac45f7079d91505d1bb212f92/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1", size = 1233750, upload-time = "2026-05-17T17:47:34.731Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/d3/4cf705beeccc08754d0bbda99aefff26110e209b9a07ac8a6b60eec48531/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6", size = 1235942, upload-time = "2026-05-17T17:47:36.287Z" },
+ { url = "https://files.pythonhosted.org/packages/26/c8/ee097e437ea27dd2b8b227865c875492b585650a5802a22d82b304c8201b/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2", size = 1442517, upload-time = "2026-05-17T17:47:38.17Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/bd/68063442838f1ba68ec72b5436430bc75b3bb17a1a3c3063f09b0c05ae2b/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903", size = 1254081, upload-time = "2026-05-17T17:47:39.826Z" },
+ { url = "https://files.pythonhosted.org/packages/50/e2/1e520793bc6a4e4524a6ab022391e827825eaa0c3811828bfdc6852eca26/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261", size = 1259910, upload-time = "2026-05-17T17:47:41.369Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/e1/49b60f467979979cfe6913b43948ff25bca971ad0591d181812f163a988e/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027", size = 1250678, upload-time = "2026-05-17T17:47:43.702Z" },
+ { url = "https://files.pythonhosted.org/packages/74/ba/66ab9555de6275677566f6574e5ef6c29cb185ea866f643bc06f8280a8ee/ast_serialize-0.5.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937", size = 1301603, upload-time = "2026-05-17T17:47:46.256Z" },
+ { url = "https://files.pythonhosted.org/packages/66/42/6aca9b9abc710014b2be9059689e5dd1679339e78f567ffb4d255a9e2050/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c", size = 1410332, upload-time = "2026-05-17T17:47:47.899Z" },
+ { url = "https://files.pythonhosted.org/packages/47/68/2f76594432a22581ecf878b5e75a9b8601c24b2241cf0bbeb1e21fcf370c/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b", size = 1509979, upload-time = "2026-05-17T17:47:50.942Z" },
+ { url = "https://files.pythonhosted.org/packages/40/ac/a93c9b58292653f6c595752f677a08e608f903b710594909e9231a389b3b/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab", size = 1505002, upload-time = "2026-05-17T17:47:54.093Z" },
+ { url = "https://files.pythonhosted.org/packages/14/2e/b278f68c497ee2f1d1576cbbef8db5281cd4a5f2db040537592ac9c8862e/ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3", size = 1456231, upload-time = "2026-05-17T17:47:56.311Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/43/419be1c566a4c504cd8fd60ce2f84e790f295495c0f327cfaeadf3d51012/ast_serialize-0.5.0-cp314-cp314t-win32.whl", hash = "sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38", size = 1058668, upload-time = "2026-05-17T17:47:58.305Z" },
+ { url = "https://files.pythonhosted.org/packages/03/6f/c9d4d549295ed05111aeb8853232d1afd9d0a179fddb01eeffbb3a4a6842/ast_serialize-0.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c", size = 1101075, upload-time = "2026-05-17T17:48:00.35Z" },
+ { url = "https://files.pythonhosted.org/packages/d0/8e/d00c5ab30c58222e07d62956fca86c59d91b9ad32997e633c38b526623a3/ast_serialize-0.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb", size = 1075347, upload-time = "2026-05-17T17:48:01.753Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/9e/dc2530acb3a60dc6e46d65abf27d1d9f86721694757906a148d90a6860de/ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101", size = 1191380, upload-time = "2026-05-17T17:48:03.738Z" },
+ { url = "https://files.pythonhosted.org/packages/26/0a/bd3d18a582f273d6c843d16bb9e22e9e16365ff7991e92f18f798e9f1224/ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a", size = 1183879, upload-time = "2026-05-17T17:48:05.463Z" },
+ { url = "https://files.pythonhosted.org/packages/40/ae/1f919100f8620887af58fcc381c61a1f218cdf89c6e155f87b213e61010a/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211", size = 1244529, upload-time = "2026-05-17T17:48:07.008Z" },
+ { url = "https://files.pythonhosted.org/packages/c6/ca/6376559dcce707cdbc1d0d9a13c8d3baaaa501e949ce0ebdc4230cd881aa/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf", size = 1240560, upload-time = "2026-05-17T17:48:08.46Z" },
+ { url = "https://files.pythonhosted.org/packages/35/b2/a620e206b5aeb7efbf2710336df57d457cffbb3991076bbcc1147ef9abd4/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9", size = 1451172, upload-time = "2026-05-17T17:48:09.922Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/e0/4ad5c04c24a40481b2935ce9a0ccdb6023dc8b667167d06ae530cc3512f2/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee", size = 1265072, upload-time = "2026-05-17T17:48:11.469Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/71/4d1d479aa56d0101c40e17720c3d6ac2af7269ea0487a80b18e7bfd1a5b7/ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809", size = 1270488, upload-time = "2026-05-17T17:48:13.575Z" },
+ { url = "https://files.pythonhosted.org/packages/6d/4f/0de1bbe06f6edef9fde4ed12ca8e7b3ec7e6e2bd4e672c5af487f7957665/ast_serialize-0.5.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43", size = 1260702, upload-time = "2026-05-17T17:48:15.141Z" },
+ { url = "https://files.pythonhosted.org/packages/75/61/e00872439cfdddcc3c1b6cdaa6e5d904ba8e26a18807c67c4e14409d0ca8/ast_serialize-0.5.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934", size = 1311182, upload-time = "2026-05-17T17:48:16.779Z" },
+ { url = "https://files.pythonhosted.org/packages/76/8e/699a5b955f7926956c95e9e1d74132acad73c2fe7a426f94da89123c20aa/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759", size = 1421410, upload-time = "2026-05-17T17:48:18.527Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/ae/d5b7626874478997adc7a29ab28accf21e596fb590c944290401dfd0b29e/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887", size = 1516587, upload-time = "2026-05-17T17:48:20.133Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/ce/b59e02a82d9c4244d64cde502e0b00e83e38816abe19155ceb5437402c7f/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27", size = 1515171, upload-time = "2026-05-17T17:48:21.921Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/38/d8d90042747d05aa08d4efcf1c99035a5f670a6bf4c214d31644392afbca/ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d", size = 1464668, upload-time = "2026-05-17T17:48:23.544Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/51/5b840c4df7334104cecffa28f23904fe81ca89ca223d2450e288de39fd3c/ast_serialize-0.5.0-cp39-abi3-win32.whl", hash = "sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a", size = 1068311, upload-time = "2026-05-17T17:48:25.027Z" },
+ { url = "https://files.pythonhosted.org/packages/41/11/ca5672c7d491825bc4cd6702dea106a6b60d928707712ec257c7833ae476/ast_serialize-0.5.0-cp39-abi3-win_amd64.whl", hash = "sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590", size = 1108931, upload-time = "2026-05-17T17:48:26.591Z" },
+ { url = "https://files.pythonhosted.org/packages/45/19/cc8bd127d28a43da249aa955cfd164cf8fd534e79e42cea96c4854d72fd0/ast_serialize-0.5.0-cp39-abi3-win_arm64.whl", hash = "sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642", size = 1081181, upload-time = "2026-05-17T17:48:28.122Z" },
+]
+
+[[package]]
+name = "cfgv"
+version = "3.5.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/4e/b5/721b8799b04bf9afe054a3899c6cf4e880fcf8563cc71c15610242490a0c/cfgv-3.5.0.tar.gz", hash = "sha256:d5b1034354820651caa73ede66a6294d6e95c1b00acc5e9b098e917404669132", size = 7334, upload-time = "2025-11-19T20:55:51.612Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/db/3c/33bac158f8ab7f89b2e59426d5fe2e4f63f7ed25df84c036890172b412b5/cfgv-3.5.0-py2.py3-none-any.whl", hash = "sha256:a8dc6b26ad22ff227d2634a65cb388215ce6cc96bbcc5cfde7641ae87e8dacc0", size = 7445, upload-time = "2025-11-19T20:55:50.744Z" },
+]
+
+[[package]]
+name = "colorama"
+version = "0.4.6"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
+]
+
+[[package]]
+name = "coverage"
+version = "7.14.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/54/fd/0ab2772530e946e1be1abd0bc09e647ec9b02e88f0867857601fefca8953/coverage-7.14.1.tar.gz", hash = "sha256:30c08f7d90415aa98b3c990385dea2939b0da55f38515e5b369b83655f8523be", size = 920132, upload-time = "2026-05-26T20:41:36.783Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/3d/b7/bdbb725ba02c5b42825b200c940f38b7a54fcad24627b7192f78f8110d76/coverage-7.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a06c76364a9360e33d6d23769aefdf7f66f38e2ffb60ceb1baaa4989d83b695c", size = 220022, upload-time = "2026-05-26T20:39:03.702Z" },
+ { url = "https://files.pythonhosted.org/packages/72/81/fdc0898a55c6219223291ec1a1fe89966ef212ce82276aa0899df84b5de0/coverage-7.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fad54e871165f6ec2f536063ac74c3104508a12963e64072ba44bd822de52b0c", size = 220379, upload-time = "2026-05-26T20:39:05.381Z" },
+ { url = "https://files.pythonhosted.org/packages/de/72/de048c4a25e13bce59ac6a339351c10bdf2515e07459afcdaf04dc3143a2/coverage-7.14.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:84b535f00655ecafe1d929d1fb00ed5d6fa3051ea643ab2c161a3887b86f294b", size = 251888, upload-time = "2026-05-26T20:39:07.367Z" },
+ { url = "https://files.pythonhosted.org/packages/28/30/300c343f68beb9d4cbb64ec81e58c5b6b80b56927f72d2b38654ac26e013/coverage-7.14.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:6b6b0853b895fe0e98cbfc580d1ec3393d9302b4b1e96a77b3f5c91fdab899e6", size = 254624, upload-time = "2026-05-26T20:39:09.037Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/ed/7b25642496e8170b6bac14adce00537c6e5fa2d586159401a4de3e8b49e6/coverage-7.14.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:442cc9c952b2df400cda54bb04ab87330cf2cd08a8692cbbea36773531eb6f37", size = 255739, upload-time = "2026-05-26T20:39:10.889Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/a2/abd210b8c4e29c24e4624916db97bb519097a91034aaeb767f937e7da794/coverage-7.14.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8270544c361ed405a27a060dbc9ed2c124b084d96dfdc2d9a2510482aef981ad", size = 257998, upload-time = "2026-05-26T20:39:12.722Z" },
+ { url = "https://files.pythonhosted.org/packages/7f/24/7c50beed3792fe62f6ce0545c6686ce83379719e2c0276179333d97eae92/coverage-7.14.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:48b283b1dd6372e8de2a7a9a4c4d5dc06f4d4fd209b876f3c88a7a205a0c8f84", size = 252296, upload-time = "2026-05-26T20:39:14.259Z" },
+ { url = "https://files.pythonhosted.org/packages/15/05/0f874628ebcbfc77ead559ff210281ef06a97db08481832e7dd39274a135/coverage-7.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5b0c99ba93a07d56f6df340bb79be53202a082b2fdb81bfe6190b741a3470d54", size = 253658, upload-time = "2026-05-26T20:39:15.923Z" },
+ { url = "https://files.pythonhosted.org/packages/99/6f/ca6ad067364b337ef997802115e7ecad2abd2248b05471464b0dea02b4d4/coverage-7.14.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e471bc5769ff073b058cfadb0d736b56ce067c8560eabeb0da88462df98c23e7", size = 251803, upload-time = "2026-05-26T20:39:17.537Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/30/b9b4d377cd9f40baf228068f5a81faf8450c6228503011bd499708483a50/coverage-7.14.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f497a1ea81d4cd7c10ddcaa685135b9aabd291af3d55775a9ddf3cb7a364cdd9", size = 255873, upload-time = "2026-05-26T20:39:19.414Z" },
+ { url = "https://files.pythonhosted.org/packages/3c/21/7c721a9e5e6bb88547d30a787aefb97512d3f54c1324c7488d9b3743f7f9/coverage-7.14.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:2222be86d0b54f5dd5a38f45f17f315f737245e857bf0bdedc70734f84a13c02", size = 251372, upload-time = "2026-05-26T20:39:21.169Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/8c/f8ae5a2200130e1503cd7661a6cd3b2b7bacef98277fbf3571fb13f8b766/coverage-7.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:85e85586565842f6932abebd4c18bcb1074223dc0b3576e7d173ca710622813a", size = 253245, upload-time = "2026-05-26T20:39:23.097Z" },
+ { url = "https://files.pythonhosted.org/packages/34/62/70a9024672a5f6910517d9628c52c9afbdd3cf8f46426af52bb148a56fff/coverage-7.14.1-cp312-cp312-win32.whl", hash = "sha256:4a28fd227808366b196a75476dced2eb35b351d6766ba9c858dc93319e87f4f1", size = 222567, upload-time = "2026-05-26T20:39:24.868Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/81/8b7cd386839b039ebe1855733b9f9449a8dec5d79564018234f185a7fa70/coverage-7.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:54acdb6674a4661768d7bf7db32dfb9f46ab1d764f8aba6df75ce1a6a088724e", size = 223372, upload-time = "2026-05-26T20:39:26.603Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/ba/b44d472022f620d289d95fa830143235c0c36461c6f2437ea8d51e5481ed/coverage-7.14.1-cp312-cp312-win_arm64.whl", hash = "sha256:99cd41ff91afd94896fea3bc002706b6ae4ce95727d06e4a0f39c0a8d8bd8b1a", size = 221989, upload-time = "2026-05-26T20:39:28.242Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/9e/5f6d56327c62b185225d145191c607e07515294a0aa6338e58805cd4a5ac/coverage-7.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:be9f2c802dcfce3f71298303aa5dad0dce440a76c52f2f60dacd8656dab78793", size = 220044, upload-time = "2026-05-26T20:39:29.902Z" },
+ { url = "https://files.pythonhosted.org/packages/75/92/e82aca356744cbbc0f77a0b623e38918c1872361963413a3bab5d0340393/coverage-7.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6223a72fd0e4c7156353ec0f08a5f93623e1d3034d0e2683b9bb8ea674131b1d", size = 220412, upload-time = "2026-05-26T20:39:31.561Z" },
+ { url = "https://files.pythonhosted.org/packages/27/c9/385bde0bf7ed0f4bf3a7ee5367060a86b5d218718cfd6fb943c0f836b34f/coverage-7.14.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7279d2110a28cebc738b6459ecda2771735a4c18465fbbd36b3288fe5ed92247", size = 251412, upload-time = "2026-05-26T20:39:33.337Z" },
+ { url = "https://files.pythonhosted.org/packages/51/8c/23faf6a2343a0d17f960a4bd56c43bc7eb4cf312f774dd6ceebd82c7d8fc/coverage-7.14.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9eeb3fcbc13ba40dfbdb22d01d196a28e9cef9ed4c29b60061a1e0e823a9929d", size = 254008, upload-time = "2026-05-26T20:39:35.009Z" },
+ { url = "https://files.pythonhosted.org/packages/42/06/36f4aa9ca8a815e6036156e80706a67828bb97bd826948244f6996dda957/coverage-7.14.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f0cfc27c539f07cf5c0a4cfe211d0b6cae039f8f40526dbaa71944e64b50a7b", size = 255241, upload-time = "2026-05-26T20:39:36.71Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/79/95266316352f90f6b1c6736bb413302edfde2453fb32422d3911642691b3/coverage-7.14.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:221c70f316241a78e77e607c227cefc8808d4e08f28d99c04f35694690e940be", size = 257373, upload-time = "2026-05-26T20:39:38.412Z" },
+ { url = "https://files.pythonhosted.org/packages/e3/9c/58316d1f66c488b5fca8a0eb3e98348807813efa8a0d0833b9021be27488/coverage-7.14.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:da028256b04ec30e5e0114b6f76172938c313991f0a2d3d894271315cf5d5e43", size = 251635, upload-time = "2026-05-26T20:39:40.268Z" },
+ { url = "https://files.pythonhosted.org/packages/ef/5a/ca2398a568e16fed7bb713e84ba3603a7164fb65779abe645c565ec890d5/coverage-7.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76a085d7005236a767e3426148b2c407e53ad61695c562f8a81da2d373324901", size = 253373, upload-time = "2026-05-26T20:39:42.145Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/2c/0396562c32deaebe7be51d865b3a41e9a87d7561acafe1a28f53b07e019a/coverage-7.14.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b553d04b5e778a8e56d57eb134aff42a92718ecba45e79c4764ecfa40efd92ff", size = 251341, upload-time = "2026-05-26T20:39:43.907Z" },
+ { url = "https://files.pythonhosted.org/packages/fd/8f/a94f9221184c9cae1ee115820e3798e48b6b17777a9f19e46fb9a0c8dc74/coverage-7.14.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:46f714d2fb8ae2f4f29f23ada7f1e79b759fff5a70f94a1dac23af204c3ec9e4", size = 255497, upload-time = "2026-05-26T20:39:46.166Z" },
+ { url = "https://files.pythonhosted.org/packages/71/69/505d70e47db1eaebcd002c39759707621ef184cd6b1ae084d9f41293f323/coverage-7.14.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1896f5e19ff3f0431c7ce2172adc54890fd97f86b59ced8ca1649145d9ffe35d", size = 251159, upload-time = "2026-05-26T20:39:48.03Z" },
+ { url = "https://files.pythonhosted.org/packages/e0/aa/58681c383aa33a9d2ed40a02d7a22fbf780d1fa4d575396365777828198c/coverage-7.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:62fd185ef9df3c33d1c8178c5af105f762afbad96038de9a4ae100aa6297ca33", size = 252934, upload-time = "2026-05-26T20:39:49.872Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/fd/11c928cd6bdffc7074bb5965c173d9ebf517fb00205e1da524b98d29ef92/coverage-7.14.1-cp313-cp313-win32.whl", hash = "sha256:ab4af6352741a604c431c6072fce5bee33bf0f20dc7a56618d6bf6bb89e9810c", size = 222584, upload-time = "2026-05-26T20:39:51.68Z" },
+ { url = "https://files.pythonhosted.org/packages/6f/92/fb416fc26d340dcba19518c418d6048e913186e17243982c5e435e41fa7a/coverage-7.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:7af486dabe8954d03b087f0021540897afe084f04e16ff5579e08cc46f871416", size = 223394, upload-time = "2026-05-26T20:39:53.472Z" },
+ { url = "https://files.pythonhosted.org/packages/73/c6/02d56e3867972f77d5036de924643f26c056e848f00452cafb4dbc3c29b4/coverage-7.14.1-cp313-cp313-win_arm64.whl", hash = "sha256:2224f89ffd0c5605ccce1ed7a584da162bc7c55f601ab1c946bc9de31a486b42", size = 222015, upload-time = "2026-05-26T20:39:55.374Z" },
+ { url = "https://files.pythonhosted.org/packages/4d/9e/fcc77914050df73f7662fa1f00902774c79c075a8388ab334074574bf77e/coverage-7.14.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de286598cc65d2b489411174b1faec2f5a7775fb3201fd925db2a76b4030f37d", size = 220733, upload-time = "2026-05-26T20:39:57.189Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/67/2963cbdaf5cbadec44efa3a1e39eaa1f02df4079585f05387607a221e126/coverage-7.14.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:042c46ded7c288aeb07cf14a28b6c1e10b78fcba40171c3fa1e939377eeef0b5", size = 221086, upload-time = "2026-05-26T20:39:59.019Z" },
+ { url = "https://files.pythonhosted.org/packages/c8/c5/8701645574e11881f2f47d8930f98bc48b5d43b25eb5b4430dfc4a2f9f48/coverage-7.14.1-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f4ddbe407477f04c45115d1a4e5bc480f753553b534d338d4c3358b1cdd0ea52", size = 262381, upload-time = "2026-05-26T20:40:00.822Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/28/7a64d73598263e0c5abd5084211a8474488d31b3c552ff531c719dfcff62/coverage-7.14.1-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d13e6725992e2d2fd7d81d4f5241952d13740121dfd501da09201be39b2c003a", size = 264458, upload-time = "2026-05-26T20:40:02.506Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/d8/4969179db9f7eb4df218e69540adf829d1c835f59452513d065d15446802/coverage-7.14.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f747dc8edcfe740130f28f32f3995e955494285717e86ee25af51db2219df08a", size = 266884, upload-time = "2026-05-26T20:40:04.421Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/78/a45d5794dbc9bafd97afc96a4377c86c7820d78b6cf51b89bc1d4e919275/coverage-7.14.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ced2f09ef276fd58611a1ef502164ad266d2b75174e5a40cabbdb4033f9f6cf2", size = 268022, upload-time = "2026-05-26T20:40:06.298Z" },
+ { url = "https://files.pythonhosted.org/packages/21/cb/4f5e354e9e3e67af96bd4e57113e6db6b22298c7168b13eec408a549903d/coverage-7.14.1-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b84800013769a78ccb9ef4659402e26d06867e337b61ec365f77ad008adea80e", size = 261631, upload-time = "2026-05-26T20:40:08.226Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/49/eced49af4cb996d5d8b7e94e736175c513e4facd3398507b89892b4326d8/coverage-7.14.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ea8cd6ca0ee9f616aaef3afc6882e32c2cbf18b00d96313ffd76af650574034d", size = 264443, upload-time = "2026-05-26T20:40:10.137Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/d8/5603a88a7c5913a6b54f6cb1a8c46f7b39cbb30f27cd3f492908da09b2d7/coverage-7.14.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:aa5e304a873fabddc11e484e9b6b738bd38bd7bed17b09aa84eecf5332e8b8bb", size = 262069, upload-time = "2026-05-26T20:40:11.999Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/59/2ae3cb79da554a06c8619d6c88ea19dd1e4aed4b834b6a83bb1fa243bdc5/coverage-7.14.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5a1c5215be81035e629d5bc756650634d0bf31991038db7a0eccb90f025ce16d", size = 265780, upload-time = "2026-05-26T20:40:13.858Z" },
+ { url = "https://files.pythonhosted.org/packages/af/5f/b130c1dc999031f2648bd25317fbce505ad8d5562079b4ed81e736a84967/coverage-7.14.1-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:79058c47dae6788504b5effb319961bcd72d7240551464b91d474bc0ed186d69", size = 260970, upload-time = "2026-05-26T20:40:16.142Z" },
+ { url = "https://files.pythonhosted.org/packages/87/d1/ec13ccddeb48ec963bdfa72a11224bac2584bd045ba13beca82f8113e9c7/coverage-7.14.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:370c5afae3fa0658e11694a32b24c2778f6bc2d17718121f94ee185e69f26b54", size = 263157, upload-time = "2026-05-26T20:40:18.382Z" },
+ { url = "https://files.pythonhosted.org/packages/cf/c2/cd91ead503045161092d3845f7bb95ea2f25131ce96d3e314dd835d91b9c/coverage-7.14.1-cp313-cp313t-win32.whl", hash = "sha256:3758dd0a7f1fa57365ef2e781df0f0731d38b6e3772259d13dae4bd8a958d4b1", size = 223259, upload-time = "2026-05-26T20:40:20.381Z" },
+ { url = "https://files.pythonhosted.org/packages/71/9f/1e28d97e6bd2c76b07f38b7c02870f1371255ff6717f54eca578fcbbdd0e/coverage-7.14.1-cp313-cp313t-win_amd64.whl", hash = "sha256:6ff665fb023a77386fe11685190cee1f60a7d635994a30d9b0a061533d470fce", size = 224320, upload-time = "2026-05-26T20:40:22.316Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/e0/d936e908f0e1efa55e52b91e01b52f1055cef5e1ab2718493390ed8e2fb8/coverage-7.14.1-cp313-cp313t-win_arm64.whl", hash = "sha256:17a5a241e5997621a956a7f402a7433ef4221e5152809b785bec79e2323799f1", size = 222577, upload-time = "2026-05-26T20:40:24.894Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/34/fc2f101b151af3799a101f0550b0454aa008afdc0add677394ec4aa8ea10/coverage-7.14.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:d5ed429d0b8edaac649e889b4ffcedb6c80b06629a3f93050e3dddfb99235bee", size = 220091, upload-time = "2026-05-26T20:40:27.249Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/a7/1ebae2ab5b961b5c79bb09fe7b3ac99edb190d8be4a8c510b2cf66f46468/coverage-7.14.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8011224a62280e50dab346960c03cf47aca1a1e09e608c0fb33fd6e0cc8e9500", size = 220421, upload-time = "2026-05-26T20:40:30.084Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/90/92aca9cf0acc95123c96cd1eb1f08917897a7f5dee01e15738922971ec31/coverage-7.14.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:12c42ec1e14f553c4f817e989365982e646e27211f10a0f717855b94a79c8906", size = 251466, upload-time = "2026-05-26T20:40:32.542Z" },
+ { url = "https://files.pythonhosted.org/packages/26/2b/78048cbe3b999f6cbf9cc0d90abba6a88a3e0863a8c1c6cbc762f3f8802f/coverage-7.14.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:06144cd511cf2624873a035c5069cf297144f6e77a73ee3d7a55b605ec5efb42", size = 253973, upload-time = "2026-05-26T20:40:34.473Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/21/c2e33b29d1cfde484a19d437afc343c6cd30b08d78cbbf9f5aff14e57b2b/coverage-7.14.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a311d8e1da24be5c1ccf85cbfb06315dbaa1703d5a1eab3f6432c72b837917c8", size = 255318, upload-time = "2026-05-26T20:40:38.154Z" },
+ { url = "https://files.pythonhosted.org/packages/8e/ee/aad2f108d63b769121005302f16bf66db8625c88ceaba466942e09a2607e/coverage-7.14.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c79cead5b5bc584d9c71451cb984d0e3a84e0c0937379c8efcbf27c8d661b851", size = 257633, upload-time = "2026-05-26T20:40:40.164Z" },
+ { url = "https://files.pythonhosted.org/packages/c2/f8/11a2c29b4fd76d9849f81d0bb812ec0017a9396df3217214e38934a8c837/coverage-7.14.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dcbf65f1f66a26cdd88c35cf68fb4729c5d1cd2e88added72420541dfb212034", size = 251488, upload-time = "2026-05-26T20:40:42.631Z" },
+ { url = "https://files.pythonhosted.org/packages/c9/b8/9a5820de4b8ac2b71d85e3b5fb49108d7469c665f0e2ad0dd7569023e305/coverage-7.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fd86572566fb40189a8260446158235159bc7a82dfbc87a3b39cf4fb57fcec1c", size = 253329, upload-time = "2026-05-26T20:40:45.208Z" },
+ { url = "https://files.pythonhosted.org/packages/6b/ff/f33e4823667e27548e8fd8df44217515303f9808d0ff29817db56f87d990/coverage-7.14.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:7771b601718fdde84832c3a434ca9bbf4ae9adbc49d84198b4110700c3c77c36", size = 251291, upload-time = "2026-05-26T20:40:47.502Z" },
+ { url = "https://files.pythonhosted.org/packages/68/9b/489db0ebb209054766b90a9014a45f6d26eb724c02ec21311c3733b5a644/coverage-7.14.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:39b21e212c55af06fa375e3dbf90a8a8e38792f3a910c580066d23563830ddd5", size = 255564, upload-time = "2026-05-26T20:40:49.372Z" },
+ { url = "https://files.pythonhosted.org/packages/27/b5/16bc2d4c2409b23c7737edb68c83bc89e345f378050549fe1d75ac7d34d5/coverage-7.14.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:f2302660e32562a532b442480121aef8aa61a5bdb20b30bf0adab29f10a5a4b4", size = 251107, upload-time = "2026-05-26T20:40:51.677Z" },
+ { url = "https://files.pythonhosted.org/packages/7d/0c/2629997469a00cd069d588a41c9dc887610f2775ae89d250c4791e65272a/coverage-7.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:03a6f93c1ec3b7f2e77b5dbcc5573a2c21f12529a5c6bbe0f16f72303cc2fa4d", size = 252764, upload-time = "2026-05-26T20:40:54.267Z" },
+ { url = "https://files.pythonhosted.org/packages/d2/ee/f78d63c8f079e0d7211c7e2401fa17e311514534ba61bae03e4b287ce4ab/coverage-7.14.1-cp314-cp314-win32.whl", hash = "sha256:8a3ce026d73290f42f08dafecbd82c193a74df280461fbf97300fec51fd133ee", size = 222837, upload-time = "2026-05-26T20:40:56.496Z" },
+ { url = "https://files.pythonhosted.org/packages/dc/b9/be539854f93a70dfbeec69117f33ec70dc42ff0b65b5b07ab8d40d04228e/coverage-7.14.1-cp314-cp314-win_amd64.whl", hash = "sha256:114c95ef29302423b87d159075805f4ab973254a2638a5d7d046c94887cc87d7", size = 223650, upload-time = "2026-05-26T20:40:58.351Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/9e/24e2842fef40f35ac82ba3a7719c8023d011bf3bf652d0675316a9d088a1/coverage-7.14.1-cp314-cp314-win_arm64.whl", hash = "sha256:a07891c3f4805442b31b71e84ba3cf29ed1aa9a428284e06deeb4b23e5b46343", size = 222218, upload-time = "2026-05-26T20:41:00.321Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/1d/ac0a9df5fe31c1e8bdd658074905fc12844a05c1a7e3fdb8417e97c31e23/coverage-7.14.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:1101a5ebb083aecb625ebb6209d4105b58f647b093cb2dc8122d7b33f743cfe1", size = 220822, upload-time = "2026-05-26T20:41:02.281Z" },
+ { url = "https://files.pythonhosted.org/packages/32/cf/f964fd9aff20323f9f1a726c97135f8a76bcd87b92dad141a456a43f3c64/coverage-7.14.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:851b9e1e4e8a4608e77c79714b2e77c0970d2ed7202a05e92ae407817481887b", size = 221084, upload-time = "2026-05-26T20:41:04.593Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/5e/7e5ef2aba844de2b80d678619fcf0841b42e3f37f16411226f3fe4c1016f/coverage-7.14.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d5b89cdfb2ee051b71e8c3c70bd81a9eff81100f736a269136fe1a68efe00474", size = 262454, upload-time = "2026-05-26T20:41:06.641Z" },
+ { url = "https://files.pythonhosted.org/packages/64/62/75809bded87015cc4935524218a2a8ed8dd1a8498bfed30a2f4f7a4b4d34/coverage-7.14.1-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0177614a0370f227888b4e436a7c55686d6a9f90eb1ade2b624ba685a1686e86", size = 264578, upload-time = "2026-05-26T20:41:08.556Z" },
+ { url = "https://files.pythonhosted.org/packages/f3/42/d33392dc14633525012d2d504fa1a33b05538bf535f5c1d64675e5754b78/coverage-7.14.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2d69af5dea2de76fc485a83032a630523f985198b7e25be901ec60181587b01e", size = 266981, upload-time = "2026-05-26T20:41:10.824Z" },
+ { url = "https://files.pythonhosted.org/packages/2a/49/0157c4428c2aca7f1e09d5565930586fd5ae36f1655f08b0daa7cf1fcae1/coverage-7.14.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:35ab22d91de736e8966b980dc355cbcdd2c6dbbcfe275f9a2991bc8a91b3df65", size = 268112, upload-time = "2026-05-26T20:41:12.966Z" },
+ { url = "https://files.pythonhosted.org/packages/96/26/86b9ce71f4092b1ed325ce1421698081df1286b833400b6836912834d6e0/coverage-7.14.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:357d4e32935c36588aaba057d734fa32428c360c9fc2e4442afbf1b646beee6e", size = 261558, upload-time = "2026-05-26T20:41:15Z" },
+ { url = "https://files.pythonhosted.org/packages/20/4c/c311210c5472cf5401d8422b0d7812cdd520f24417673afabda6c323faca/coverage-7.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:51bd64741cc6fa065abd300ede1afe5a5291ece9c31da8b24884deda48bcc3f8", size = 264447, upload-time = "2026-05-26T20:41:17.369Z" },
+ { url = "https://files.pythonhosted.org/packages/fb/71/59513f8710ed3e6b0ac0a050a5b7e977bb9c9e880354863b5d00d8809256/coverage-7.14.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:9132cd363a68a4c3daa7c8704a654b1e39d3360f6f5b8ddd470608a945236c07", size = 262048, upload-time = "2026-05-26T20:41:19.309Z" },
+ { url = "https://files.pythonhosted.org/packages/84/8d/bceed32dc494f5bbf50f775cd2e78ca814953942b5ea28d3c1c3ac316f14/coverage-7.14.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07c6290b1697b862c0478eab545eec949a0d0e4d6d03497f446d706da3b4f2de", size = 265781, upload-time = "2026-05-26T20:41:21.559Z" },
+ { url = "https://files.pythonhosted.org/packages/e7/c5/9348fe40dbfd4991aaf78df2c6c3098bfb2cc834d1fd362a64b4efef855a/coverage-7.14.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5ea0c297e27133853b4d8a3eb799bff5a2dbd9f2f41537a240d337ac9b4df890", size = 260896, upload-time = "2026-05-26T20:41:23.428Z" },
+ { url = "https://files.pythonhosted.org/packages/ca/92/1ea0f03929da7cf87206b1fa24f4c8e9c158be0455481af29ec0a1f3503f/coverage-7.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:01b7733daad0237daa01ef80fe2dfceffc911e6a17fa7b55d14aa8214eaaaecd", size = 263214, upload-time = "2026-05-26T20:41:25.419Z" },
+ { url = "https://files.pythonhosted.org/packages/f6/a9/b2493c054c0e01a643266742ab45e15744e60743f9260cd930c7142b1124/coverage-7.14.1-cp314-cp314t-win32.whl", hash = "sha256:6adc5a36984624a70bf11d7184e20fa0a49aa7c47ffab43804106a1a695ea22e", size = 223624, upload-time = "2026-05-26T20:41:27.795Z" },
+ { url = "https://files.pythonhosted.org/packages/fc/bd/3e1e6a57fccd2d7c83fcdf338e93ba98eb85c6e877dd34731ac585375490/coverage-7.14.1-cp314-cp314t-win_amd64.whl", hash = "sha256:ddf799247318f34dbcd2efa8c95a8d0642674e926bb1774cf9b63dfd2a389d1c", size = 224728, upload-time = "2026-05-26T20:41:30.098Z" },
+ { url = "https://files.pythonhosted.org/packages/bb/d7/31066cf1d2f0c6c797fce911bcfa01dd35642dc6da992a950256097c5860/coverage-7.14.1-cp314-cp314t-win_arm64.whl", hash = "sha256:145986fe66647eb489f18d9a997567a3fd358584c4b5a808769113abc07466af", size = 222752, upload-time = "2026-05-26T20:41:32.123Z" },
+ { url = "https://files.pythonhosted.org/packages/8a/3c/1a983b9a745d7f83d53f057bcc5bf79ba6a2bbc08266b3f0c7d6fe630c9b/coverage-7.14.1-py3-none-any.whl", hash = "sha256:a252f21c27e38347e60111a3266b03827422a7d5525951aceee313aa68bab1d2", size = 211815, upload-time = "2026-05-26T20:41:34.078Z" },
+]
+
+[[package]]
+name = "distlib"
+version = "0.4.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/c9/02/bd72be9134d25ed783ecbbc38a539ffaefbf90c78418c7fb7229600dbac7/distlib-0.4.3.tar.gz", hash = "sha256:f152097224a0ae24be5a0f6bae1b9359af82133bce63f98a95f86cae1aede9ed", size = 615141, upload-time = "2026-06-12T08:04:52.847Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/02/08/9c41fb51ab5b43eb21674aff13df270e8ba6c4b29c8624e328dc7a9482af/distlib-0.4.3-py2.py3-none-any.whl", hash = "sha256:4b0ce306c966eb73bc3a7b6abad017c556dadd92c44701562cd528ac7fde4d5b", size = 470628, upload-time = "2026-06-12T08:04:50.506Z" },
+]
+
+[[package]]
+name = "exit-dash-hyperion"
+version = "2.0.0"
+source = { editable = "." }
+dependencies = [
+ { name = "platformdirs" },
+ { name = "pygame-ce" },
+]
+
+[package.optional-dependencies]
+dev = [
+ { name = "mypy" },
+ { name = "pre-commit" },
+ { name = "pytest" },
+ { name = "pytest-cov" },
+ { name = "ruff" },
+]
+
+[package.metadata]
+requires-dist = [
+ { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.11" },
+ { name = "platformdirs", specifier = ">=4.0" },
+ { name = "pre-commit", marker = "extra == 'dev'" },
+ { name = "pygame-ce", specifier = ">=2.5.7" },
+ { name = "pytest", marker = "extra == 'dev'", specifier = ">=8" },
+ { name = "pytest-cov", marker = "extra == 'dev'" },
+ { name = "ruff", marker = "extra == 'dev'", specifier = ">=0.6" },
+]
+provides-extras = ["dev"]
+
+[[package]]
+name = "filelock"
+version = "3.29.4"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e6/dc/be6cbe99670cd6e4ad387123647cb08e0c32975e223f82551e914c5568a6/filelock-3.29.4.tar.gz", hash = "sha256:10cdb3656fc44541cdf30652a93fb10ec6b05325620eb316bd26893e4201538a", size = 63028, upload-time = "2026-06-13T16:12:00.744Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/13/37/a065dc3bd6e49423a6532c642ca7378d3f467b1ef44c2800c937af7f9739/filelock-3.29.4-py3-none-any.whl", hash = "sha256:dac1648087d5115554850d113e7dd8c83ab2d38e3435dde2d4f163847e57b767", size = 42757, upload-time = "2026-06-13T16:11:59.582Z" },
+]
+
+[[package]]
+name = "identify"
+version = "2.6.19"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/52/63/51723b5f116cc04b061cb6f5a561790abf249d25931d515cd375e063e0f4/identify-2.6.19.tar.gz", hash = "sha256:6be5020c38fcb07da56c53733538a3081ea5aa70d36a156f83044bfbf9173842", size = 99567, upload-time = "2026-04-17T18:39:50.265Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/94/84/d9273cd09688070a6523c4aee4663a8538721b2b755c4962aafae0011e72/identify-2.6.19-py2.py3-none-any.whl", hash = "sha256:20e6a87f786f768c092a721ad107fc9df0eb89347be9396cadf3f4abbd1fb78a", size = 99397, upload-time = "2026-04-17T18:39:49.221Z" },
+]
+
+[[package]]
+name = "iniconfig"
+version = "2.3.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" },
+]
+
+[[package]]
+name = "librt"
+version = "0.11.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/40/08/9e7f6b5d2b5bed6ad055cdd5925f192bb403a51280f86b56554d9d0699a2/librt-0.11.0.tar.gz", hash = "sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1", size = 200139, upload-time = "2026-05-10T18:17:25.138Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8b/d0/07c77e067f0838949b43bd89232c29d72efebb9d2801a9750184eb706b71/librt-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46", size = 144147, upload-time = "2026-05-10T18:15:53.227Z" },
+ { url = "https://files.pythonhosted.org/packages/7a/24/8493538fa4f62f982686398a5b8f68008138a75086abdea19ade64bf4255/librt-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3", size = 143614, upload-time = "2026-05-10T18:15:54.657Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/1e/f8bad050810d9171f34a1648ed910e56814c2ba61639f2bd53c6377ae24b/librt-0.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67", size = 485538, upload-time = "2026-05-10T18:15:56.117Z" },
+ { url = "https://files.pythonhosted.org/packages/c0/fe/3594ebfbaf03084ba4b120c9ba5c3183fd938a48725e9bbe6ff0a5159ad8/librt-0.11.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a", size = 479623, upload-time = "2026-05-10T18:15:57.544Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/da/5d1876984b3746c85dbd219dbfcb73c85f54ee263fd32e5b2a632ec14571/librt-0.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a", size = 513082, upload-time = "2026-05-10T18:15:58.805Z" },
+ { url = "https://files.pythonhosted.org/packages/19/6e/55bdf5d5ca00c3e18430690bf2c953d8d3ffd3c337418173d33dec985dc9/librt-0.11.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f", size = 508105, upload-time = "2026-05-10T18:16:00.2Z" },
+ { url = "https://files.pythonhosted.org/packages/07/10/f1f23a7c595ee90ece4d35c851e5d104b1311a887ed1b4ac4c35bbd13da8/librt-0.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b", size = 522268, upload-time = "2026-05-10T18:16:01.708Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/02/5720f5697a7f54b78b3aefbe20df3a48cedcff1276618c4aa481177942ed/librt-0.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766", size = 527348, upload-time = "2026-05-10T18:16:03.496Z" },
+ { url = "https://files.pythonhosted.org/packages/50/db/b4a47c6f91db4ff76348a0b3dd0cc65e090a078b765a810a62ff9434c3d3/librt-0.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d", size = 516294, upload-time = "2026-05-10T18:16:05.173Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/58/9384b2f4eb1ed1d273d40948a7c5c4b2360213b402ef3be4641c06299f9c/librt-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8", size = 553608, upload-time = "2026-05-10T18:16:06.839Z" },
+ { url = "https://files.pythonhosted.org/packages/21/7b/5aa8848a7c6a9278c79375146da1812e695754ceec5f005e6043461a7315/librt-0.11.0-cp312-cp312-win32.whl", hash = "sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a", size = 101879, upload-time = "2026-05-10T18:16:08.103Z" },
+ { url = "https://files.pythonhosted.org/packages/37/33/8a745436944947575b584231750a41417de1a38cf6a2e9251d1065651c09/librt-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9", size = 119831, upload-time = "2026-05-10T18:16:09.174Z" },
+ { url = "https://files.pythonhosted.org/packages/59/67/a6739ac96e28b7855808bdb0370e250606104a859750d209e5a0716fe7ab/librt-0.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c", size = 103470, upload-time = "2026-05-10T18:16:10.369Z" },
+ { url = "https://files.pythonhosted.org/packages/82/61/e59168d4d0bf2bf90f4f0caf7a001bfc60254c3af4586013b04dc3ef517b/librt-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894", size = 144119, upload-time = "2026-05-10T18:16:11.771Z" },
+ { url = "https://files.pythonhosted.org/packages/61/fd/caa1d60b12f7dd79ccea23054e06eeaebe266a5f52c40a6b651069200ce5/librt-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c", size = 143565, upload-time = "2026-05-10T18:16:13.334Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/a9/dc744f5c2b4978d48db970be29f22716d3413d28b14ad99740817315cf2c/librt-0.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea", size = 485395, upload-time = "2026-05-10T18:16:14.729Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/21/7f8e97a1e4dae952a5a95948f6f8507a173bc1e669f54340bba6ca1ca31b/librt-0.11.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230", size = 479383, upload-time = "2026-05-10T18:16:16.321Z" },
+ { url = "https://files.pythonhosted.org/packages/a6/6d/d8ee9c114bebf2c50e29ec2aa940826fccb62a645c3e4c18760987d0e16d/librt-0.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2", size = 513010, upload-time = "2026-05-10T18:16:17.647Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/43/0b5708af2bd30a46400e72ba6bdaa8f066f15fb9a688527e34220e8d6c06/librt-0.11.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3", size = 508433, upload-time = "2026-05-10T18:16:19.309Z" },
+ { url = "https://files.pythonhosted.org/packages/4a/50/356187247d09013490481033183b3532b58acf8028bcb34b2b56a375c9b2/librt-0.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21", size = 522595, upload-time = "2026-05-10T18:16:20.642Z" },
+ { url = "https://files.pythonhosted.org/packages/40/e7/c6ac4240899c7f3248079d5a9900debe0dadb3fdeaf856684c987105ba47/librt-0.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930", size = 527255, upload-time = "2026-05-10T18:16:22.352Z" },
+ { url = "https://files.pythonhosted.org/packages/eb/b5/a81322dbeedeeaf9c1ee6f001734d28a09d8383ac9e6779bc24bbd0743c6/librt-0.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be", size = 516847, upload-time = "2026-05-10T18:16:23.627Z" },
+ { url = "https://files.pythonhosted.org/packages/ae/66/6e6323787d592b55204a42595ff1102da5115601b53a7e9ddebc889a6da5/librt-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e", size = 553920, upload-time = "2026-05-10T18:16:25.025Z" },
+ { url = "https://files.pythonhosted.org/packages/9c/21/623f8ca230857102066d9ca8c6c1734995908c4d0d1bee7bb2ef0021cb33/librt-0.11.0-cp313-cp313-win32.whl", hash = "sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e", size = 101898, upload-time = "2026-05-10T18:16:26.649Z" },
+ { url = "https://files.pythonhosted.org/packages/b3/1d/b4ebd44dd723f768469007515cb92251e0ae286c94c140f374801140fa74/librt-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47", size = 119812, upload-time = "2026-05-10T18:16:27.859Z" },
+ { url = "https://files.pythonhosted.org/packages/3b/e4/b2f4ca7965ca373b491cdb4bc25cdb30c1649ca81a8782056a83850292a9/librt-0.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44", size = 103448, upload-time = "2026-05-10T18:16:29.066Z" },
+ { url = "https://files.pythonhosted.org/packages/29/eb/dbce197da4e227779e56b5735f2decc3eb36e55a1cdbf1bd65d6639d76c1/librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd", size = 143345, upload-time = "2026-05-10T18:16:30.674Z" },
+ { url = "https://files.pythonhosted.org/packages/76/a3/254bebd0c11c8ba684018efb8006ff22e466abce445215cca6c778e7d9de/librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4", size = 143131, upload-time = "2026-05-10T18:16:32.037Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/3f/f77d6122d21ac7bf6ae8a7dfced1bd2a7ac545d3273ebdcaf8042f6d619f/librt-0.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8", size = 477024, upload-time = "2026-05-10T18:16:33.493Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/0a/2c996dadebaa7d9bbbd43ef2d4f3e66b6da545f838a41694ef6172cebec8/librt-0.11.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b", size = 474221, upload-time = "2026-05-10T18:16:34.864Z" },
+ { url = "https://files.pythonhosted.org/packages/0a/7e/f5d92af8486b8272c23b3e686b46ff72d89c8169585eb61eef01a2ac7147/librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175", size = 505174, upload-time = "2026-05-10T18:16:36.705Z" },
+ { url = "https://files.pythonhosted.org/packages/af/1a/cb0734fe86398eb33193ab753b7326255c74cac5eb09e76b9b16536e7adb/librt-0.11.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03", size = 497216, upload-time = "2026-05-10T18:16:38.418Z" },
+ { url = "https://files.pythonhosted.org/packages/18/06/094820f91558b66e29943c0ec41c9914f460f48dd51fc503c3101e10842d/librt-0.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c", size = 513921, upload-time = "2026-05-10T18:16:39.848Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/c2/00de9018871a282f530cacb457d5ec0428f6ac7e6fedde9aff7468d9fb04/librt-0.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3", size = 520850, upload-time = "2026-05-10T18:16:41.471Z" },
+ { url = "https://files.pythonhosted.org/packages/51/9d/64631832348fd1834fb3a61b996434edddaaf25a31d03b0a76273159d2cf/librt-0.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96", size = 504237, upload-time = "2026-05-10T18:16:43.15Z" },
+ { url = "https://files.pythonhosted.org/packages/a5/ec/ae5525eb16edc827a044e7bb8777a455ff95d4bca9379e7e6bddd7383647/librt-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe", size = 546261, upload-time = "2026-05-10T18:16:44.408Z" },
+ { url = "https://files.pythonhosted.org/packages/5a/09/adce371f27ca039411da9659f7430fcc2ba6cd0c7b3e4467a0f091be7fa9/librt-0.11.0-cp314-cp314-win32.whl", hash = "sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f", size = 96965, upload-time = "2026-05-10T18:16:46.039Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/ee/8ac720d98548f173c7ce2e632a7ca94673f74cacd5c8162a84af5b35958a/librt-0.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7", size = 115151, upload-time = "2026-05-10T18:16:47.133Z" },
+ { url = "https://files.pythonhosted.org/packages/94/20/c900cf14efeb09b6bef2b2dff20779f73464b97fd58d1c6bccc379588ae3/librt-0.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1", size = 98850, upload-time = "2026-05-10T18:16:48.597Z" },
+ { url = "https://files.pythonhosted.org/packages/0c/71/944bfe4b64e12abffcd3c15e1cce07f72f3d55655083786285f4dedeb532/librt-0.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72", size = 151138, upload-time = "2026-05-10T18:16:49.839Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/10/99e64a5c86989357fda078c8143c533389585f6473b7439172dd8f3b3b2d/librt-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa", size = 151976, upload-time = "2026-05-10T18:16:51.062Z" },
+ { url = "https://files.pythonhosted.org/packages/21/31/5072ad880946d83e5ea4147d6d018c78eefce85b77819b19bdd0ee229435/librt-0.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548", size = 557927, upload-time = "2026-05-10T18:16:52.632Z" },
+ { url = "https://files.pythonhosted.org/packages/5e/8d/70b5fb7cfbab60edbe7381614ab985da58e144fbf465c86d44c95f43cdca/librt-0.11.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2", size = 539698, upload-time = "2026-05-10T18:16:53.934Z" },
+ { url = "https://files.pythonhosted.org/packages/fa/a3/ba3495a0b3edbd24a4cae0d1d3c64f39a9fc45d06e812101289b50c1a619/librt-0.11.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f", size = 577162, upload-time = "2026-05-10T18:16:55.589Z" },
+ { url = "https://files.pythonhosted.org/packages/f7/db/36e25fb81f99937ff1b96612a1dc9fd66f039cb9cc3aee12c01fac31aab9/librt-0.11.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51", size = 566494, upload-time = "2026-05-10T18:16:56.975Z" },
+ { url = "https://files.pythonhosted.org/packages/33/0d/3f622b47f0b013eeb9cf4cc07ae9bfe378d832a4eec998b2b209fe84244d/librt-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2", size = 596858, upload-time = "2026-05-10T18:16:58.374Z" },
+ { url = "https://files.pythonhosted.org/packages/a9/02/71b90bc93039c46a2000651f6ad60122b114c8f54c4ad306e0e96f5b75ad/librt-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085", size = 590318, upload-time = "2026-05-10T18:16:59.676Z" },
+ { url = "https://files.pythonhosted.org/packages/04/04/418cb3f75621e2b761fb1ab0f017f4d70a1a72a6e7c74ee4f7e8d198c2f3/librt-0.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3", size = 575115, upload-time = "2026-05-10T18:17:01.007Z" },
+ { url = "https://files.pythonhosted.org/packages/cc/2c/5a2183ac58dd911f26b5d7e7d7d8f1d87fcecdddd99d6c12169a258ff62c/librt-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd", size = 617918, upload-time = "2026-05-10T18:17:02.682Z" },
+ { url = "https://files.pythonhosted.org/packages/15/1f/dc6771a52592a4451be6effa200cbfc9cec61e4393d3033d81a9d307961d/librt-0.11.0-cp314-cp314t-win32.whl", hash = "sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8", size = 103562, upload-time = "2026-05-10T18:17:03.99Z" },
+ { url = "https://files.pythonhosted.org/packages/62/4a/7d1415567027286a75ba1093ec4aca11f073e0f559c530cf3e0a757ad55c/librt-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c", size = 124327, upload-time = "2026-05-10T18:17:05.465Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/62/b40b382fa0c66fee1478073eb8db352a4a6beda4a1adccf1df911d8c289c/librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253", size = 102572, upload-time = "2026-05-10T18:17:06.809Z" },
+]
+
+[[package]]
+name = "mypy"
+version = "2.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "ast-serialize" },
+ { name = "librt", marker = "platform_python_implementation != 'PyPy'" },
+ { name = "mypy-extensions" },
+ { name = "pathspec" },
+ { name = "typing-extensions" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/82/15/cca9d88503549ed6fedeaa1d448cdddd542ee8a490232d732e278036fbf2/mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633", size = 3898359, upload-time = "2026-05-11T18:37:36.237Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/95/b1/55861beb5c339b44f9a2ba92df9e2cb1eeb4ae1eee674cdf7772c797778b/mypy-2.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af", size = 14874381, upload-time = "2026-05-11T18:37:31.784Z" },
+ { url = "https://files.pythonhosted.org/packages/0b/b3/b7f770114b7d0ac92d0f76e8d93c2780844a70488a90e91821927850da86/mypy-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6", size = 13665501, upload-time = "2026-05-11T18:34:23.063Z" },
+ { url = "https://files.pythonhosted.org/packages/b6/f3/8ae2037967e2126689a0c11d99e2b707134a565191e92c60ca2572aec60a/mypy-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211", size = 14045750, upload-time = "2026-05-11T18:31:48.151Z" },
+ { url = "https://files.pythonhosted.org/packages/a0/32/615eb5911859e43d054941b0d0a7d06cfa2870eba86529cf385b052b111c/mypy-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b", size = 15061630, upload-time = "2026-05-11T18:37:06.898Z" },
+ { url = "https://files.pythonhosted.org/packages/d4/03/4eafbfff8bfab1b87082741eae6e6a624028c984e6708b73bce2a8570c9d/mypy-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22", size = 15288831, upload-time = "2026-05-11T18:31:18.07Z" },
+ { url = "https://files.pythonhosted.org/packages/99/ee/919661478e5891a3c96e549c036e467e64563ab85995b10c53c8358e16a3/mypy-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b", size = 11135228, upload-time = "2026-05-11T18:34:31.23Z" },
+ { url = "https://files.pythonhosted.org/packages/24/0a/6a12b9782ca0831a553192f351679f4548abc9d19a7cc93bb7feb02084c7/mypy-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8", size = 10040684, upload-time = "2026-05-11T18:36:48.199Z" },
+ { url = "https://files.pythonhosted.org/packages/6e/dd/c7191469c777f07689c032a8f7326e393ea34c92d6d76eb7ce5ba57ea66d/mypy-2.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5", size = 14852174, upload-time = "2026-05-11T18:31:38.929Z" },
+ { url = "https://files.pythonhosted.org/packages/55/8c/aed55408879043d72bb9135f4d0d19a02b886dd569631e113e3d2706cb8d/mypy-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e", size = 13651542, upload-time = "2026-05-11T18:36:04.636Z" },
+ { url = "https://files.pythonhosted.org/packages/3a/8e/f371a824b1f1fa8ea6e3dbb8703d232977d572be2329554a3bc4d960302f/mypy-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e", size = 14033929, upload-time = "2026-05-11T18:35:55.742Z" },
+ { url = "https://files.pythonhosted.org/packages/94/21/f54be870d6dd53a82c674407e0f8eed7174b05ec78d42e5abd7b42e84fd5/mypy-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285", size = 15039200, upload-time = "2026-05-11T18:33:10.281Z" },
+ { url = "https://files.pythonhosted.org/packages/17/99/bf21748626a40ce59fd29a39386ab46afec88b7bd2f0fa6c3a97c995523f/mypy-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5", size = 15272690, upload-time = "2026-05-11T18:32:07.205Z" },
+ { url = "https://files.pythonhosted.org/packages/d6/d7/9e90d2cf47100bea550ed2bc7b0d4de3a62181d84d5e37da0003e8462637/mypy-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65", size = 11147435, upload-time = "2026-05-11T18:33:56.477Z" },
+ { url = "https://files.pythonhosted.org/packages/ec/46/e5c449e858798e35ffc90946282a27c62a77be743fe17480e4977374eb91/mypy-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d", size = 10035052, upload-time = "2026-05-11T18:32:30.049Z" },
+ { url = "https://files.pythonhosted.org/packages/b0/ca/b279a672e874aedd5498ae25f722dacc8aa86bbffb939b3f97cbb1cf6686/mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2", size = 14848422, upload-time = "2026-05-11T18:35:45.984Z" },
+ { url = "https://files.pythonhosted.org/packages/27/e6/3efe56c631d959b9b4454e208b0ac4b7f4f58b404c89f8bec7b49efdfc21/mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f", size = 13677374, upload-time = "2026-05-11T18:36:57.188Z" },
+ { url = "https://files.pythonhosted.org/packages/84/7f/8107ea87a44fd1f1b59882442f033c9c3488c127201b1d1d15f1cbd6022e/mypy-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4", size = 14055743, upload-time = "2026-05-11T18:35:18.361Z" },
+ { url = "https://files.pythonhosted.org/packages/51/4d/b6d34db183133b83761b9199a82d31557cdbb70a380d8c3b3438e11882a3/mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef", size = 15020937, upload-time = "2026-05-11T18:34:59.618Z" },
+ { url = "https://files.pythonhosted.org/packages/ff/d7/f08360c691d758acb02f45022c34d98b92892f4ea756644e1000d4b9f3d8/mypy-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135", size = 15253371, upload-time = "2026-05-11T18:36:41.081Z" },
+ { url = "https://files.pythonhosted.org/packages/67/1b/09460a13719530a19bce27bd3bc8449e83569dd2ba7faf51c9c3c30c0b61/mypy-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21", size = 11326429, upload-time = "2026-05-11T18:34:13.526Z" },
+ { url = "https://files.pythonhosted.org/packages/40/62/75dbf0f82f7b6680340efc614af29dd0b3c17b8a4f1cd09b8bd2fd6bc814/mypy-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57", size = 10218799, upload-time = "2026-05-11T18:32:23.491Z" },
+ { url = "https://files.pythonhosted.org/packages/b2/66/caca04ed7d972fb6eb6dd1ccd6df1de5c38fae8c5b3dc1c4e8e0d85ee6b9/mypy-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e", size = 15923458, upload-time = "2026-05-11T18:35:28.64Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/52/2d90cbe49d014b13ed7ff337930c30bad35893fe38a1e4641e756bb62191/mypy-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780", size = 14757697, upload-time = "2026-05-11T18:36:14.208Z" },
+ { url = "https://files.pythonhosted.org/packages/ac/37/d98f4a14e081b238992d0ed96b6d39c7cc0148c9699eb71eaa68629665ea/mypy-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd", size = 15405638, upload-time = "2026-05-11T18:33:48.249Z" },
+ { url = "https://files.pythonhosted.org/packages/a3/c2/15c46613b24a84fad2aea1248bf9619b99c2767ae9071fe224c179a0b7d4/mypy-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08", size = 16215852, upload-time = "2026-05-11T18:32:50.296Z" },
+ { url = "https://files.pythonhosted.org/packages/5c/90/9c16a57f482c76d25f6379762b56bbf65c711d8158cf271fb2802cfb0640/mypy-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081", size = 16452695, upload-time = "2026-05-11T18:33:38.182Z" },
+ { url = "https://files.pythonhosted.org/packages/0f/4c/215a4eeb63cacc5f17f516691ea7285d11e249802b942476bff15922a314/mypy-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7", size = 12866622, upload-time = "2026-05-11T18:34:39.945Z" },
+ { url = "https://files.pythonhosted.org/packages/4b/50/1043e1db5f455ffe4c9ab22747cd8ca2bc492b1e4f4e21b130a44ee2b217/mypy-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6", size = 10610798, upload-time = "2026-05-11T18:36:31.444Z" },
+ { url = "https://files.pythonhosted.org/packages/0d/2a/13ca1f292f6db1b98ff495ef3467736b331621c5917cad984b7043e7348d/mypy-2.1.0-py3-none-any.whl", hash = "sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289", size = 2693302, upload-time = "2026-05-11T18:31:29.246Z" },
+]
+
+[[package]]
+name = "mypy-extensions"
+version = "1.1.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" },
+]
+
+[[package]]
+name = "nodeenv"
+version = "1.10.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/24/bf/d1bda4f6168e0b2e9e5958945e01910052158313224ada5ce1fb2e1113b8/nodeenv-1.10.0.tar.gz", hash = "sha256:996c191ad80897d076bdfba80a41994c2b47c68e224c542b48feba42ba00f8bb", size = 55611, upload-time = "2025-12-20T14:08:54.006Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/88/b2/d0896bdcdc8d28a7fc5717c305f1a861c26e18c05047949fb371034d98bd/nodeenv-1.10.0-py2.py3-none-any.whl", hash = "sha256:5bb13e3eed2923615535339b3c620e76779af4cb4c6a90deccc9e36b274d3827", size = 23438, upload-time = "2025-12-20T14:08:52.782Z" },
+]
+
+[[package]]
+name = "packaging"
+version = "26.2"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" },
+]
+
+[[package]]
+name = "pathspec"
+version = "1.1.1"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" },
+]
+
+[[package]]
+name = "platformdirs"
+version = "4.10.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/d7/47/e4501f49c178ae1d9f4a75073fda4204f52647993f075a9db4d14930e0c5/platformdirs-4.10.0.tar.gz", hash = "sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7", size = 31224, upload-time = "2026-05-28T03:32:53.587Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl", hash = "sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a", size = 22743, upload-time = "2026-05-28T03:32:52.175Z" },
+]
+
+[[package]]
+name = "pluggy"
+version = "1.6.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" },
+]
+
+[[package]]
+name = "pre-commit"
+version = "4.6.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "cfgv" },
+ { name = "identify" },
+ { name = "nodeenv" },
+ { name = "pyyaml" },
+ { name = "virtualenv" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/8e/22/2de9408ac81acbb8a7d05d4cc064a152ccf33b3d480ebe0cd292153db239/pre_commit-4.6.0.tar.gz", hash = "sha256:718d2208cef53fdc38206e40524a6d4d9576d103eb16f0fec11c875e7716e9d9", size = 198525, upload-time = "2026-04-21T20:31:41.613Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/80/6e/4b28b62ecb6aae56769c34a8ff1d661473ec1e9519e2d5f8b2c150086b26/pre_commit-4.6.0-py2.py3-none-any.whl", hash = "sha256:e2cf246f7299edcabcf15f9b0571fdce06058527f0a06535068a86d38089f29b", size = 226472, upload-time = "2026-04-21T20:31:40.092Z" },
+]
+
+[[package]]
+name = "pygame-ce"
+version = "2.5.7"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/e9/0d/bb6a6fdf1b227c0bb9a44437a70962a3854bcc541533c261e5021a5ee691/pygame_ce-2.5.7.tar.gz", hash = "sha256:86beb797cd73c141299a29b56f7df2b0543fbdc81d428022458329ff694aaa51", size = 5935870, upload-time = "2026-03-02T09:26:59.005Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/57/a7/cd305034f505bfa1a1acdafd3d86af54da14b29151a0d99f348306272773/pygame_ce-2.5.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:dca2f8ba56bf3b4b8c73c4863d0603773403f4f66bc2fe25784ea74aee3fffc3", size = 17210332, upload-time = "2026-03-02T09:25:52.18Z" },
+ { url = "https://files.pythonhosted.org/packages/e5/94/7f6304a31ccc7d11d4443e590cbfa6fce2bd34077575a7790d4f0a14f440/pygame_ce-2.5.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4dc989462faf2c5947881f708fa406d7ac13c1bc987c1588d630ca62ad369989", size = 12709001, upload-time = "2026-03-02T09:25:54.806Z" },
+ { url = "https://files.pythonhosted.org/packages/09/8b/a7886b7bfe874fa381201ee538928af3c1cab2fe3e36927ed08f3f1d0b61/pygame_ce-2.5.7-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:538689d77c44f5dbefc0abeab5b9806d6c90ebc6d64078736c8a4c731f08b37e", size = 13236706, upload-time = "2026-03-02T09:25:57.524Z" },
+ { url = "https://files.pythonhosted.org/packages/db/17/70ada4cef84eca48a995cc9e0f2f087e6190b3e4111e9c8ec3c7a8f689bd/pygame_ce-2.5.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0d8fa8822c0f4b5ae6b44ada7be9f2193fd512da1381c37fa3c5bda8971d64cb", size = 12812909, upload-time = "2026-03-02T09:25:59.971Z" },
+ { url = "https://files.pythonhosted.org/packages/40/db/1cfcfb7813ce6d2202919ad87c7e1b278a4f820902ba826df43dc8906e34/pygame_ce-2.5.7-cp312-cp312-win32.whl", hash = "sha256:604207c8813a594919bb7e6d3ed3834f79aa099d2d648e8a8fc3d786ad3fa1c8", size = 9837595, upload-time = "2026-03-02T09:26:02.573Z" },
+ { url = "https://files.pythonhosted.org/packages/1f/d4/43b006affa13e2f4572aa28a0d1f64c91c330d289c30a022b5416245714c/pygame_ce-2.5.7-cp312-cp312-win_amd64.whl", hash = "sha256:b6b7eec2779fac11ed265a18ab926b3829654120a5c9a07c36eeedeb012b8c3c", size = 10414958, upload-time = "2026-03-02T09:26:05.25Z" },
+ { url = "https://files.pythonhosted.org/packages/18/1b/971a432d8bab8c52031ddbd0e681750a57348213ec0f8a0e0d6713e8df46/pygame_ce-2.5.7-cp312-cp312-win_arm64.whl", hash = "sha256:eb99a8a7185057064163610b3ca3e1d3307f0eb3dfff6e19556fa5132c6bca87", size = 10859829, upload-time = "2026-03-02T09:26:08.06Z" },
+ { url = "https://files.pythonhosted.org/packages/21/96/d28381210ec2ed5d7a04f77cd8f6949a7734f75a7a7d9a95fe8ed60fe3ba/pygame_ce-2.5.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8766985d802017e150fcfb9adc659967d8548a961d491b8974f0748412cc0427", size = 17203240, upload-time = "2026-03-02T09:26:10.975Z" },
+ { url = "https://files.pythonhosted.org/packages/b8/f0/a3e4d0ad2519d106d178652ae7ec692e8acadf3d2260493840c27f8eabb8/pygame_ce-2.5.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:58eabfc184dd28c682e5e6ccfce01224bb12653c6648babcd0bb9d9bd662d938", size = 12705532, upload-time = "2026-03-02T09:26:13.795Z" },
+ { url = "https://files.pythonhosted.org/packages/13/0d/6d6c29aa5ecf63a66983bdf04066dc019290e7412f64b0ae5133c5e53d47/pygame_ce-2.5.7-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:92d5732cd512c8ec0b47e9a3e6c683fb811bdf2090362580778ce698222a64ab", size = 13233559, upload-time = "2026-03-02T09:26:16.202Z" },
+ { url = "https://files.pythonhosted.org/packages/fe/96/e400d3a2c6456e3a334d9fae1f8704d964027b60064935278028dd79293f/pygame_ce-2.5.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:48e9a4ece43b08adc8ffb0bbbe0fe183eef4bb501a7d31552ae7398592ec0a82", size = 12811409, upload-time = "2026-03-02T09:26:19.148Z" },
+ { url = "https://files.pythonhosted.org/packages/8f/ed/8e3c6f5d4ac763f6766c2043f842b2c52028b30a4ce2ce2f5dced5961354/pygame_ce-2.5.7-cp313-cp313-win32.whl", hash = "sha256:f6439100bdee81da96f5acffb280f20511c93dd67178d8a8cf29d6cfd1aa46dd", size = 9835553, upload-time = "2026-03-02T09:26:22.123Z" },
+ { url = "https://files.pythonhosted.org/packages/06/a0/7acd164b3a206327bf53df5e5399227a5baf858ae2944cba562a0ae77e0a/pygame_ce-2.5.7-cp313-cp313-win_amd64.whl", hash = "sha256:25047c97760fc640a6a8bbfdf3398c5825adfd55986a7523a65c95a1fb61d759", size = 10413012, upload-time = "2026-03-02T09:26:24.747Z" },
+ { url = "https://files.pythonhosted.org/packages/47/d5/e4419a340ae24bd0dde5a6861406c24114f59a543aad44f1d2f2ae4752d5/pygame_ce-2.5.7-cp313-cp313-win_arm64.whl", hash = "sha256:f5a7197096ef82d588539f13b0f7ade767f800c7b0b015a94e386f488e1039f6", size = 10856939, upload-time = "2026-03-02T09:26:27.107Z" },
+ { url = "https://files.pythonhosted.org/packages/26/08/9fe0003d69077ff8faff242a85260b8a192d3b7111c02332b8b2f515d40c/pygame_ce-2.5.7-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:addfbf7d119647eec157d611f463e5d572836fa74d0d222c59210294ed618b9d", size = 17211017, upload-time = "2026-03-02T09:26:30.243Z" },
+ { url = "https://files.pythonhosted.org/packages/40/c7/217c5430c8c612879162beb2d18cb10ad8b1b4db6ce03245289a3de6bc1b/pygame_ce-2.5.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1c92feb289e34ac323a7b62b91d230a4e32b44059c4d7fb95631e504b1d9b365", size = 12710845, upload-time = "2026-03-02T09:26:33.165Z" },
+ { url = "https://files.pythonhosted.org/packages/00/a4/6fb0054bfb2522c4ad3ff82ecbc9c1a3c6694c50d24f2451717121636a1d/pygame_ce-2.5.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5c1ed4100311015cc67d24fe4e4d7c2f4cb25c34e043545061271c1d018c02d4", size = 12812020, upload-time = "2026-03-02T09:26:35.953Z" },
+ { url = "https://files.pythonhosted.org/packages/a2/9b/0e0996573a9dd4bb34874c10643224a72372818242e07486c9eb4a22eebb/pygame_ce-2.5.7-cp314-cp314-win32.whl", hash = "sha256:1b7e641af3aeac92bb7e4df1402d6802271f4bd09c747d2665f154ef9b07a4e6", size = 9968590, upload-time = "2026-03-02T09:26:38.517Z" },
+ { url = "https://files.pythonhosted.org/packages/96/96/c94d0e508954093e37a77b03101a3cf51a242e02cc0ec726edcb117f8885/pygame_ce-2.5.7-cp314-cp314-win_amd64.whl", hash = "sha256:595f4257c15fed11cd816ae0bfabad3d99f8f04a000d7d164a22c0f9afd6cb65", size = 10581240, upload-time = "2026-03-02T09:26:41.139Z" },
+ { url = "https://files.pythonhosted.org/packages/81/bb/93c5dadb66ac9733ca52952e063cce117a9312d6f97facd5dc4932f3d777/pygame_ce-2.5.7-cp314-cp314-win_arm64.whl", hash = "sha256:3e6ce74fd5a5f146f1bcf0224ae3e880c733917a9edbb53f790329d235520433", size = 11057480, upload-time = "2026-03-02T09:26:43.871Z" },
+]
+
+[[package]]
+name = "pygments"
+version = "2.20.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" },
+]
+
+[[package]]
+name = "pytest"
+version = "9.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "colorama", marker = "sys_platform == 'win32'" },
+ { name = "iniconfig" },
+ { name = "packaging" },
+ { name = "pluggy" },
+ { name = "pygments" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/84/0e/b5858858d74958632c49b72cb25a3976ff9f632397626715be71c89d3971/pytest-9.1.0.tar.gz", hash = "sha256:41dd9148c08072446394cefd3d79701701335a9f4cae69ba92e39f6c7f5c061c", size = 1634181, upload-time = "2026-06-13T18:52:45.983Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/8b/5a/ba30a81239b909821b3153e303e7def45178bf353da4f72380e6c5e8793b/pytest-9.1.0-py3-none-any.whl", hash = "sha256:8ebb0e7888bdf2bdfc602ec51f8f62d50200af37356c74e503c79a94f5c81f32", size = 386453, upload-time = "2026-06-13T18:52:44.045Z" },
+]
+
+[[package]]
+name = "pytest-cov"
+version = "7.1.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "coverage" },
+ { name = "pluggy" },
+ { name = "pytest" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" },
+]
+
+[[package]]
+name = "python-discovery"
+version = "1.4.2"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "filelock" },
+ { name = "platformdirs" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/0b/1a/cbbaf13b730abb0a16b964d984e19f2fe520c21a4dc664051359a3f5a9e7/python_discovery-1.4.2.tar.gz", hash = "sha256:8f3746c4b4968d22afbb97d36e1a0e5b66e6c0f297290f2e95f05b9b8bf18690", size = 70277, upload-time = "2026-06-11T16:10:42.383Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/1a/82/a70006589557f267f15bd384c0642ad49f0d97b690c3a05b166b9dcbad3b/python_discovery-1.4.2-py3-none-any.whl", hash = "sha256:475803f53b7b2ed6e490e27373f9d8340f7d2eebf9acdaf645d7d714c97bb500", size = 33886, upload-time = "2026-06-11T16:10:41.192Z" },
+]
+
+[[package]]
+name = "pyyaml"
+version = "6.0.3"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" },
+ { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" },
+ { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" },
+ { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" },
+ { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" },
+ { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" },
+ { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" },
+ { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" },
+ { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" },
+ { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" },
+ { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" },
+ { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" },
+ { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" },
+ { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" },
+ { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" },
+ { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" },
+ { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" },
+ { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" },
+ { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" },
+ { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" },
+ { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" },
+ { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" },
+ { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" },
+ { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" },
+ { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" },
+ { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" },
+ { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" },
+ { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" },
+ { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" },
+ { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" },
+ { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" },
+ { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
+ { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
+ { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
+]
+
+[[package]]
+name = "ruff"
+version = "0.15.17"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/8c/a9/3abdf488f1bf3d24c699415e454ed554a6350d5d89ce183be1ee0a3361ac/ruff-0.15.17.tar.gz", hash = "sha256:2ec446937fd16c8c4de2674a209cc5af64d9c6f17d21fbf1151054fa0bcf5219", size = 4743346, upload-time = "2026-06-11T17:54:47.663Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/db/4d/e11259f5da07cb6afb2d074c31bf09da9671993f7329d4f15d2fdc458301/ruff-0.15.17-py3-none-linux_armv6l.whl", hash = "sha256:d9feddb927fc68bd295f5eebc587a7e42cfaf9b65f60ca4a2386febff575da8f", size = 10856677, upload-time = "2026-06-11T17:54:49.533Z" },
+ { url = "https://files.pythonhosted.org/packages/29/3e/772d679e1a0dc058e58875bd2c0cb713a0530877b4a76fee3c7966df0d49/ruff-0.15.17-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:25805a226d741c47d274a35ad5c10a7dde175fcddfa511d7cf3da0a21eb3eab7", size = 11223443, upload-time = "2026-06-11T17:55:00.573Z" },
+ { url = "https://files.pythonhosted.org/packages/68/58/bd41f7688b2fd5623012605130ed70e60aa7f2244baa3d5066bdd61530c8/ruff-0.15.17-py3-none-macosx_11_0_arm64.whl", hash = "sha256:f6ad73b14c2d18a3bf8ad7cb6974294d7f613a7898604826058e6ac64918ef4d", size = 10566458, upload-time = "2026-06-11T17:55:07.52Z" },
+ { url = "https://files.pythonhosted.org/packages/d8/5b/733371013fcf1ec339e477ece6ab42bfe10bdd9bba8ee88a9516aa56bfc0/ruff-0.15.17-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ba0c1e4f95bcb3869d0d30cbd5917071ef2e28665abfec970cdab0492c713ed", size = 10914483, upload-time = "2026-06-11T17:55:05.501Z" },
+ { url = "https://files.pythonhosted.org/packages/bd/cc/6f24251cc0252f7239391ccb85833f320efad14ebe5b443943f37ced6332/ruff-0.15.17-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:81647960f10bff57d2e51cadd0c3950fe598400c852863a038720ef5b8cca91e", size = 10647497, upload-time = "2026-06-11T17:54:57.733Z" },
+ { url = "https://files.pythonhosted.org/packages/68/dd/0d10c17ce1a1624d6fc3156309c3f834fdb5dfaad026ec90c85684f3990e/ruff-0.15.17-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e01a84ddbc8c16c23055ba3924476850f1bbc1917cebbb9376665a63e74260d", size = 11416967, upload-time = "2026-06-11T17:54:51.461Z" },
+ { url = "https://files.pythonhosted.org/packages/2f/91/556bfb156f6144f355e831c23db00b2fc4120f86b3ce81cc5f7fd2df51f3/ruff-0.15.17-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fe9f653152f8f294f9f7e03bf3a453d8b4a27f7a59c78c8666167f2b17b96c", size = 12335770, upload-time = "2026-06-11T17:54:45.793Z" },
+ { url = "https://files.pythonhosted.org/packages/88/82/8b5999aa13355e926f06d9f42a32dcca862f623bf0363785ff89d607dffd/ruff-0.15.17-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c0fe88a7676e7a05b73174d4d4a59cb2ac21ff8263583f87a81a6018475a978", size = 11575441, upload-time = "2026-06-11T17:54:32.661Z" },
+ { url = "https://files.pythonhosted.org/packages/11/93/f10377bb04109ca0e8cbc483ff1982c54b6d418210041776f93e8cdc7fa9/ruff-0.15.17-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecfc3c7878fff94633ab0348524e093f9ce3243080416dd7d14f8ba400174719", size = 11557614, upload-time = "2026-06-11T17:54:34.698Z" },
+ { url = "https://files.pythonhosted.org/packages/c7/a6/eeeae7f7d5493df41649ab3db92f086b2d0a30199e4efdf8e3dd7a033f24/ruff-0.15.17-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:b8461180b22420b1bdc289909410930761629fddf2a5aaf60fae1ab26cedc4c4", size = 11544450, upload-time = "2026-06-11T17:54:39.042Z" },
+ { url = "https://files.pythonhosted.org/packages/32/88/5991ce565129a24dd4a00db1254b3b5db2e53018cbe4018ea5a89738e727/ruff-0.15.17-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6eccbe50a038b503e7140b441aa9c7fc8c1f36edf23ebef9f4165c2f28f568b7", size = 10892524, upload-time = "2026-06-11T17:55:09.432Z" },
+ { url = "https://files.pythonhosted.org/packages/f5/1d/0fdd248313425f55223968af04b0a42125466a8d88d21c1d99c6af0a51e8/ruff-0.15.17-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:382fc0521025f5a8ad447d8bdd523545d0d7646adb718eb1c2dac5065ec27c0f", size = 10659573, upload-time = "2026-06-11T17:54:36.824Z" },
+ { url = "https://files.pythonhosted.org/packages/9e/0e/072e8260deb9461062ce9311ced27a8e541229a6ffd483013dd37661e43e/ruff-0.15.17-py3-none-musllinux_1_2_i686.whl", hash = "sha256:456d41fcd1b2777ad63f09a6e7121d43f7b688bbc76a800c10f7f8fb1f912c3f", size = 11127818, upload-time = "2026-06-11T17:55:03.124Z" },
+ { url = "https://files.pythonhosted.org/packages/ab/b4/55060a34163121498014696b5f656db5b8c6963768f227dbf0d76b311073/ruff-0.15.17-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b1a04bcc94ae6194e9db05d16ad31f298a7194bfbcb08258bbe589cee1d587b8", size = 11655901, upload-time = "2026-06-11T17:54:53.562Z" },
+ { url = "https://files.pythonhosted.org/packages/49/71/9b29d6b87cef468d697f43c6a91e3fae4a80185779d7d5a4ef27d173439f/ruff-0.15.17-py3-none-win32.whl", hash = "sha256:596065960ab1ff593f744220c9fe6580eda00a95003cffa9f4048bb5b1bf0392", size = 10925574, upload-time = "2026-06-11T17:54:55.723Z" },
+ { url = "https://files.pythonhosted.org/packages/3d/b2/8fc77f3723228836fa5d12497eb71c808f83782e10d058d2b15cfa14640b/ruff-0.15.17-py3-none-win_amd64.whl", hash = "sha256:6769e5fa1710b179b92e0bfa5a51735b35baea9013dadb06d5f44cbcf9547084", size = 12058788, upload-time = "2026-06-11T17:54:41.042Z" },
+ { url = "https://files.pythonhosted.org/packages/2d/c7/c53e8dbff9c9dc4b7928773421ae294a5d28fcb8dcda1a089579d3a7e510/ruff-0.15.17-py3-none-win_arm64.whl", hash = "sha256:f3be1fbb34bcdfd146240d8fb92a709d4c2c8191348580a3c044ec60fa0b4456", size = 11355275, upload-time = "2026-06-11T17:54:43.635Z" },
+]
+
+[[package]]
+name = "typing-extensions"
+version = "4.15.0"
+source = { registry = "https://pypi.org/simple" }
+sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" },
+]
+
+[[package]]
+name = "virtualenv"
+version = "21.5.0"
+source = { registry = "https://pypi.org/simple" }
+dependencies = [
+ { name = "distlib" },
+ { name = "filelock" },
+ { name = "platformdirs" },
+ { name = "python-discovery" },
+]
+sdist = { url = "https://files.pythonhosted.org/packages/cd/0e/933bacb37b57ae7928b0030eef205a3dbb3e37afdbdde5be2e113318958f/virtualenv-21.5.0.tar.gz", hash = "sha256:98847aadf5e2037e0e4d2e19528eb3aca6f23906422e59a510bff231a6d32fce", size = 4577424, upload-time = "2026-06-13T20:36:45.066Z" }
+wheels = [
+ { url = "https://files.pythonhosted.org/packages/e9/87/b0667ede418386ab631e48924b845d326f366d61e6bd08fe68a748fae4d4/virtualenv-21.5.0-py3-none-any.whl", hash = "sha256:8f7c38605023688c89789f566959006af6d61c99eeeb9e58342eb780c5761e5e", size = 4557937, upload-time = "2026-06-13T20:36:42.967Z" },
+]