Add README and polish entry point

- Created comprehensive `README.md` with game overview, controls, tech stack, project structure, setup instructions, and architecture notes.
- Updated `index.html` title to “AIsteroids 2026” and reformatted CSS for readability.
- Refactored imports in `js/main.js` for consistent spacing and added a Phaser `scale` configuration (FIT mode, auto‑center, optional parent) to improve responsive display.
This commit is contained in:
Brian Fertig 2026-02-21 14:46:20 -07:00
parent 26a80b6b89
commit 59ab58b0a7
3 changed files with 134 additions and 9 deletions

102
README.md Normal file
View File

@ -0,0 +1,102 @@
# AIsteroids 2026
A top-down space shooter built with Phaser 3, inspired by the classic Asteroids arcade game. Survive escalating waves of asteroids and alien attackers across multiple levels — no installation required.
---
## Gameplay
- **Asteroids** spawn at the start of each level. Shoot them to break them apart:
- Large → 13 medium or small fragments
- Medium → 2 small fragments
- Small → destroyed completely
- **Alien ships** periodically warp in and hunt the player. Three variants appear as levels progress:
- **Basic** (cyan saucer) — moves toward the player and fires single shots
- **Spread** (orange saucer) — fires a 5-bullet fan, appears at level 3+
- **Missile** (purple diamond) — fires homing missiles, appears at level 5+
- A level ends when all asteroids and alien ships are destroyed. The player always respawns at screen center on a new level.
- Asteroid speed increases each level (capped at 2× the base speed).
## Controls
| Input | Action |
|---|---|
| Mouse movement | Rotate ship toward cursor (360° turn takes 2 seconds) |
| Left mouse button | Thrust / accelerate |
| `A` or `Space` | Fire weapon |
The ship uses zero-gravity physics — it builds speed over ~2 seconds at full thrust and gradually decelerates when thrust is released.
---
## Tech Stack
| Tool | Purpose |
|---|---|
| [Phaser 3.60](https://phaser.io/) | HTML5 game framework (WebGL renderer) |
| JavaScript ES6 Modules | Game logic, entity classes |
| Phaser Arcade Physics | Collision detection, zero-gravity movement |
| WebGL PostFX Pipeline | Custom CRT scanline/barrel-distortion shader |
| Python 3 HTTP server | Local development server (no build step) |
There is no bundler, package manager, or build step. Modules are loaded natively by the browser over HTTP using ES6 `import`/`export`.
---
## Project Structure
```
oc-test/
├── index.html # Entry point — loads Phaser via CDN and bootstraps main.js
├── start_web.sh # Helper script: starts python3 -m http.server 8000
├── Software.md # Authoritative game design specification
└── js/
├── main.js # Phaser config, scene list, pipeline registration
├── scenes/
│ ├── BootScene.js # Procedural texture generation, hands off to MenuScene
│ ├── MenuScene.js # Title screen with decorative entities and CRT effect
│ └── GameScene.js # Core game loop — owns all entities and collision logic
├── entities/
│ ├── Player.js # Player ship: mouse-driven rotation, thrust, firing
│ ├── Asteroid.js # Asteroid: size variants, rotation, fragmentation data
│ ├── AlienShip.js # Alien ship: type variants, AI movement, attack patterns
│ └── Bullet.js # Bullets and homing missiles (player, alien, missile types)
└── pipelines/
└── CRTPipeline.js # WebGL PostFXPipeline: scanlines, barrel distortion, vignette
```
All game graphics are **procedurally generated** at startup in `BootScene` — no external image assets are required for the core game.
---
## Running Locally
Requires Python 3 (for the dev server) and a modern browser with WebGL support.
```bash
# Clone the repo
git clone <repo-url>
cd oc-test
# Start the development server
./start_web.sh
# or equivalently:
python3 -m http.server 8000
```
Then open [http://localhost:8000](http://localhost:8000) in your browser.
> **Note:** The game must be served over HTTP (not opened as a `file://` URL) because ES6 modules require a server context.
---
## Architecture Notes
- **Scene flow:** `BootScene``MenuScene``GameScene`
- **Entity pattern:** Each entity class holds an `alive` flag and attaches itself to its sprite via `sprite.gameEntity = this`, enabling collision callbacks to look up the owning object.
- **Collision detection:** Uses Phaser physics groups for overlap detection, backed by plain JS arrays for per-frame update loops.
- **CRT effect:** Applied as a `PostFXPipeline` in both `MenuScene` and `GameScene` (WebGL only). Features barrel distortion (strength 0.18), alternating scanlines, and a vignette.

View File

@ -1,16 +1,34 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Space Shooter</title>
<title>AIsteroids 2026</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; overflow: hidden; }
canvas { display: block; }
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
overflow: hidden;
}
canvas {
display: block;
}
</style>
</head>
<body>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.60.0/dist/phaser.min.js"></script>
<script type="module" src="js/main.js"></script>
</body>
</html>
</html>

View File

@ -1,12 +1,17 @@
import BootScene from './scenes/BootScene.js';
import MenuScene from './scenes/MenuScene.js';
import GameScene from './scenes/GameScene.js';
import CRTPipeline from './pipelines/CRTPipeline.js';
import BootScene from './scenes/BootScene.js';
import MenuScene from './scenes/MenuScene.js';
import GameScene from './scenes/GameScene.js';
import CRTPipeline from './pipelines/CRTPipeline.js';
const config = {
type: Phaser.WEBGL, // Required for PostFXPipeline (CRT shader)
width: 1600,
height: 900,
scale: {
mode: Phaser.Scale.FIT, // This will scale to fit the screen
autoCenter: Phaser.Scale.CENTER_BOTH, // Center both horizontally and vertically
parent: 'game-container' // Optional: specify parent container
},
backgroundColor: '#000011',
pipeline: { CRTPipeline }, // Registers the pipeline by class name
physics: {