build a space shooter game with vanilla JavaScript and canvas. no libraries. no frameworks. multi-file project structure.
PROJECT STRUCTURE: space-shooter/ index.html -- entry point, canvas setup, script imports in dependency order (config > audio > particles > background > enemies > player > ui > game) README.md -- what it is, how to run, controls, screenshot placeholder css/styles.css -- fullscreen canvas, cursor hidden during gameplay, no-select, overflow hidden js/ config.js -- color palette, speeds, enemy stats, sizes, all tuning constants game.js -- main game loop, state machine (menu/playing/paused/gameover), collision detection, damage numbers, screen shake player.js -- ship rendering, mouse tracking with lerp, weapons, upgrade tiers, health, engine trail spawning enemies.js -- pixelated octopus enemy types (grid-based fillRect rendering, NOT smooth arcs), wave spawning, boss logic particles.js -- explosion system, ink splatter, engine trails, bullet trails, spark impacts, powerup sparkles background.js -- 4-layer parallax (stars, nebula, planets, comets), all scrolling DOWNWARD (vertical shooter), mouse-reactive depth ui.js -- HUD (20px font, y=40 baseline, proper spacing), start/gameover screens, score display, health bar, combo counter audio.js -- Web Audio API procedural sounds (laser, explosions, boss music, powerup, hit sound, unleash drone)
CRITICAL IMPLEMENTATION DETAILS (do not skip these):
CANVAS SETUP:
- in game.js init(), explicitly set canvas.width = window.innerWidth, canvas.height = window.innerHeight
- set ctx.imageSmoothingEnabled = false (pixel art style requires this)
- add window resize listener to update canvas dimensions
ENEMY SIZES (must be large enough for collision):
- small octopus: size 36
- medium octopus: size 48
- baby octopus: size 20
- boss octopus: size 150
BULLET SPEEDS (must be slow enough to not phase through enemies):
- tier 1: speed 8
- tier 2: speed 10
- tier 3: speed 12
- tier 4: speed 14
SHIP MOUSE TRACKING:
- use lerp with factor 0.35 (not lower, feels sluggish below 0.2)
- ship.x += (mouseX - ship.x) * 0.35 per frame
COLLISION DETECTION:
- use circle-to-circle distance check: dxdx + dydy < (r1+r2)*(r1+r2)
- bullet collision radius = bullet width
- enemy collision radius = enemy size / 2
- do NOT use bounding box point-in-rect. fast bullets tunnel through enemies with point checks
- player-enemy contact: use ship radius + 30px buffer, apply screen shake on contact damage
OCTOPUS RENDERING (pixel art style):
- render ALL octopus types using grid-based fillRect patterns, NOT ctx.arc() or smooth shapes
- define pixel grids (e.g. 8x8 or 10x10 arrays of 0s and 1s) for each octopus type
- calculate cell size from enemy size / grid dimensions
- draw each filled cell with ctx.fillRect(x + colcellW, y + rowcellH, cellW, cellH)
- tentacles animate by toggling bottom row cells between frames
- this gives authentic pixelated look. smooth arcs look wrong for this art style
BACKGROUND SCROLLING:
- this is a VERTICAL top-down shooter. everything scrolls DOWNWARD (positive y direction)
- stars: small dots moving down slowly, wrap when off bottom
- nebula: transparent cloud shapes drifting down
- planets: mix of far (small 20-40px, dim 0.4 opacity, slow 0.1-0.2 speed) and near (large 60-100px, full opacity, faster 0.5-0.8 speed) for depth variation
- comets: streak across diagonally, moving downward
- parallax reacts to mouse position for depth feel
- do NOT scroll sideways or upward
PARTICLE SYSTEM:
- particles.draw(ctx) MUST be called in the game's main draw loop. if you forget this, no particles render
- engine trails: spawn in player.update() every frame, small orange-yellow particles behind thrusters
- bullet trails: spawn in game.js bullet update loop, tiny particles along bullet path matching bullet color
- spark particles: spawn at hit point when bullet hits enemy (white/yellow, short lived)
- ink splatter: spawn on enemy death, color matches enemy type
- explosions: green core burst + scattered colored particles
HIT FEEDBACK (critical for game feel):
- when bullet hits enemy: enemy flashes white for 3 frames (hitFlash property, render white overlay)
- spawn 3-5 spark particles at impact point
- spawn floating damage number that rises and fades ("-10" text, yellow, floats up 60px over 1 second)
- play hit sound (short noise burst)
HUD LAYOUT:
- font size 20px monospace
- SCORE at x=20, y=40
- LEVEL at canvas center, y=40
- COMBO at right edge minus padding, y=40
- health bar at bottom center
- do NOT stack labels or let them overlap
GAMEPLAY:
- top-down vertical infinite scrolling. ship follows mouse cursor smoothly
- hold left click for continuous rapid fire. bullet spread improves per level
- enemies are PIXELATED OCTOPUS ALIENS that spawn from top in wave patterns
- infinite flying, levels increase enemy count, speed, and bullet patterns
- boss octopus every 5 levels with health bar and tentacle attack patterns
- score counter, combo multiplier for consecutive kills without getting hit
ENEMY TYPES (all pixel art octopus variants):
- small octopus (2 tentacles waving animation, neon pink) - basic grunt, moves in sine wave patterns
- medium octopus (4 tentacles, electric blue) - shoots ink blobs back at player, splits into 2 baby octopi on death
- baby octopus (tiny, cyan) - spawns from medium death, fast but fragile
- BOSS octopus (8 tentacles, glowing purple, large) - every 5 levels, tentacles visually reach toward player, multi-phase health bar, ink barrage attack
POWER-UP SYSTEM:
- killing a big/boss octopus drops a glowing orb pickup
- collecting orb = UNLEASH MODE for 5 seconds
- during unleash: bullets become massive spread beams, ship glows white-hot, chain reaction explosions on everything touched, score multiplier goes 3x
- subtle chromatic aberration screen effect during unleash
- countdown ring around ship showing remaining unleash time (green ring that shrinks)
- right before each boss wave, a mini-swarm of small octopi rushes in (perfect unleash timing opportunity)
SHIP DESIGN (pixel art, all canvas-drawn):
- angular stealth fighter shape (F-117 style but pixelated)
- main body: dark gunmetal gray with cyan edge glow (#4ECDC4)
- 2 rear thrusters with orange-yellow flame particles trailing behind (spawned every frame in player.update)
- ship banks slightly left/right when moving (2-3 frame tilt animation)
- UPGRADE TIERS (every 3 levels):
- tier 1: basic ship, single cannon, cyan glow
- tier 2: wider wings, dual cannons, green glow
- tier 3: full delta wing, triple spread shot, gold glow
- tier 4: final form, homing missiles + spread, white glow with rainbow edge shimmer
VISUALS:
- neon cyberpunk color palette on dark space background
- 4-layer parallax background: distant stars (slow), colorful nebula clouds (medium), planets with depth variation (far=dim+small, near=bright+large), occasional comet streaks
- parallax reacts slightly to mouse movement for depth feel
- explosions: green core burst + rainbow colored dust particles that scatter and fade
- ink splatter effect on octopus death (color matches enemy type: pink/blue/cyan/purple)
- bullets leave short neon color trails (spawned as particles in bullet update loop)
- enemies flash WHITE when hit (3-frame hitFlash, not just glow)
- screen shake on explosions, scales with enemy size
- screen flash on player hit
EFFECTS:
- full particle system for: explosions, ink splatter, engine trails, bullet trails, hit sparks, dust clouds, powerup sparkles
- smooth 60fps target with requestAnimationFrame
- dark space background (#0D1117) with vibrant neon everything else
AUDIO (Web Audio API, procedural, no external files):
- laser pew sound on shoot (short oscillator sweep)
- explosion sounds (noise burst + low rumble, varies by enemy size)
- powerup collect chime (ascending tone)
- unleash mode bass drone
- boss warning alarm
- ambient space hum (very subtle background)
- hit sound (short noise burst when bullet hits enemy)
UI:
- start screen: game title "OCTOPUS INVADERS" with pulsing glow, all 4 octopus types displayed as pixel art preview, "CLICK TO START" text
- HUD: score (top left), level (top center), combo counter (top right) -- all at y=40 with 20px font, health bar (bottom), unleash meter if active
- game over screen: final score, level reached, enemies killed, screen shake effect, "CLICK TO RESTART"
- pause with ESC key
- all UI text in monospace font
DOCUMENTATION:
- README.md with: game description, how to run (python3 -m http.server 3001), controls list, project structure explanation
- brief JSDoc comments at top of each JS module explaining its responsibility
- config.js should have clear sections with comments for easy tuning
serve with python3 -m http.server 3001 when done. make sure all imports work and game runs immediately on first load.