Last Updated: 3/6/2026
API Reference
Complete TypeScript API documentation for the Snake Game.
SnakeGame Class
The main game class that manages all game logic, rendering, and state.
Constructor
constructor()Initializes the game:
- Gets canvas element and 2D context
- Updates canvas size based on viewport
- Loads high score from localStorage
- Sets up event listeners
- Adds window resize handler
Types
Position
type Position = { x: number; y: number }Represents a grid coordinate.
Direction
type Direction = 'UP' | 'DOWN' | 'LEFT' | 'RIGHT'Four possible movement directions.
Constants
const ISO_MIN_WIDTH = 300 // Minimum isometric view width (px)
const ISO_MAX_WIDTH = 1200 // Maximum isometric view width (px)Private Properties
Canvas & Context
private canvas: HTMLCanvasElement
private ctx: CanvasRenderingContext2DCanvas element and 2D rendering context.
Game State
private snake: Position[] = []
private food: Position = { x: 0, y: 0 }
private direction: Direction = 'RIGHT'
private nextDirection: Direction = 'RIGHT'
private score: number = 0
private level: number = 1
private gridSize: number = 10
private initialGridSize: number = 10snake: Array of body segments (head at index 0)food: Current food positiondirection: Current movement directionnextDirection: Queued direction (applied next update)score: Current score (food eaten)level: Current level (starts at 1, increments on grid expansion)gridSize: Current grid dimensions (doubles on level up)initialGridSize: Starting grid size (adjustable with +/- keys)
Game Loop
private gameSpeed: number = 200
private baseSpeed: number = 200
private gameLoop: number | null = null
private isPaused: boolean = false
private isGameOver: boolean = false
private gameStarted: boolean = falsegameSpeed: Current update interval in millisecondsbaseSpeed: Initial speed (200ms = 5 updates/second)gameLoop: setInterval ID for the game loopisPaused: Whether game is pausedisGameOver: Whether game has endedgameStarted: Whether game has begun (first input received)
Isometric Rendering
private isoAngle: number = Math.PI / 3 // 60° rotation
private perspectiveRatio: number = 0.5 // Vertical squash
private perspectiveStrength: number = 0.4 // Depth effect intensity
private focalLength: number = InfinityisoAngle: Z-axis rotation angle (adjustable with Q/E)perspectiveRatio: Y-axis compression for top-down viewperspectiveStrength: How much perspective affects size (0-0.8)focalLength: Computed focal length for perspective projection
private basisXx: number = 0
private basisXy: number = 0
private basisYx: number = 0
private basisYy: number = 0Basis vectors for grid-to-screen transformation.
private baseBlockHeight: number = 0
private rawMaxY: number = 0
private rawCenterX: number = 0
private isoOriginX: number = 0
private isoOriginY: number = 0baseBlockHeight: 3D block height in pixelsrawMaxY: Maximum Y coordinate before perspectiverawCenterX: Center X coordinate before perspectiveisoOriginX,isoOriginY: Canvas offset to center grid
private isoCache: { x: number; y: number }[][] = []Pre-computed screen coordinates for grid intersections.
Public Methods
startNewGame()
startNewGame(): voidResets and starts a new game:
- Resets grid to initial size
- Places snake at center
- Resets score and level
- Spawns food
- Shows game screen
- Clears any existing game loop
- Draws initial state
The game loop doesn’t start until the player presses a direction key.
Private Methods
Viewport & Sizing
getIsoWidth()
private getIsoWidth(): numberCalculates the isometric view width based on viewport:
- Accounts for page padding (64px) and canvas border (6px)
- Returns a value between
ISO_MIN_WIDTHandISO_MAX_WIDTH
updateCanvasSize()
private updateCanvasSize(): voidRecalculates all rendering parameters:
- Computes basis vectors from rotation angle
- Calculates scale to fit grid in viewport
- Computes perspective focal length
- Sets canvas dimensions
- Centers grid in canvas
- Builds isometric coordinate cache
Called on initialization, window resize, and grid size changes.
Coordinate Transformation
toIso()
private toIso(gridX: number, gridY: number): { x: number; y: number }Transforms grid coordinates to screen coordinates:
- Applies basis vector transformation
- Applies perspective scaling based on depth
- Adds origin offset
Parameters:
gridX: Grid X coordinategridY: Grid Y coordinate
Returns: Screen coordinates { x, y }
Rendering
draw()
private draw(): voidMain rendering function:
- Clears canvas
- Draws ground plane (checkerboard)
- Draws grid lines
- Draws ground border
- Collects all objects (snake segments + food)
- Sorts objects back-to-front
- Draws shadows
- Draws 3D blocks
drawGroundPlane()
private drawGroundPlane(): voidDraws the checkerboard ground using Path2D batching.
drawGridLines()
private drawGridLines(): voidDraws grid lines (skipped if tiles are too small).
drawGroundBorder()
private drawGroundBorder(): voidDraws a border around the grid perimeter.
getBlockHeight()
private getBlockHeight(gx: number, gy: number): numberCalculates the perspective-adjusted height for a block at grid position (gx, gy).
drawBlockShadow()
private drawBlockShadow(gx: number, gy: number): voidDraws a shadow quad on the ground at grid position (gx, gy).
drawBlock()
private drawBlock(
gx: number,
gy: number,
topColor: string,
rightColor: string,
leftColor: string
): voidDraws a 3D block with shaded faces:
- Culls back faces
- Draws front faces with appropriate shading
- Draws top face
Parameters:
gx,gy: Grid positiontopColor: Color for top facerightColor: Color for right-facing sidesleftColor: Color for left-facing sides
Input Handling
setupEventListeners()
private setupEventListeners(): voidAttaches keyboard and button event listeners.
handleKeyPress()
private handleKeyPress(e: KeyboardEvent): voidHandles all keyboard input:
| Key(s) | Action |
|---|---|
| Enter | Start new game |
| R | Restart game |
| P | Toggle pause |
| +/= | Increase grid size (pre-game) |
| -/_ | Decrease grid size (pre-game) |
| Q | Rotate view clockwise |
| E | Rotate view counter-clockwise |
| [ | Decrease perspective |
| ] | Increase perspective |
| Arrow keys, WASD | Move snake |
isValidDirection()
private isValidDirection(newDirection: Direction): booleanChecks if a direction change is valid (not opposite to current direction).
togglePause()
private togglePause(): voidToggles pause state and shows/hides pause screen.
Game Logic
update()
private update(): voidMain game loop update:
- Apply queued direction
- Move snake head
- Check for collision
- Check if food was eaten
- Spawn new food if needed
- Check for grid expansion
- Update display
Called by setInterval at gameSpeed interval.
checkCollision()
private checkCollision(head: Position): booleanChecks if a position collides with walls or snake body.
Parameters:
head: Position to check
Returns: true if collision detected
checkGridExpansion()
private checkGridExpansion(): voidChecks if snake fills 25% of grid; if so, calls expandGrid().
expandGrid()
private expandGrid(): voidDoubles grid size and advances level:
- Doubles
gridSize - Increments
level - Halves
gameSpeed(increases difficulty) - Updates canvas size
- Restarts game loop with new speed
- Spawns new food
spawnFood()
private spawnFood(): voidSpawns food at a random empty grid position.
endGame()
private endGame(): voidEnds the game:
- Stops game loop
- Updates high score if beaten
- Shows game over screen with final score
UI Management
updateUI()
private updateUI(): voidUpdates score, level, and grid size displays.
showScreen()
private showScreen(screenId: string): voidShows a screen by ID, hiding all others.
Parameters:
screenId: Element ID of screen to show ('game','game-over', etc.)
Persistence
getHighScore()
private getHighScore(): numberRetrieves high score from localStorage.
Returns: High score (0 if not set)
saveHighScore()
private saveHighScore(score: number): voidSaves high score to localStorage and updates UI.
loadHighScore()
private loadHighScore(): voidLoads high score from localStorage and updates UI.
Usage Example
import './style.css'
// Game automatically initializes and attaches to #canvas
new SnakeGame()The game is instantiated once at module load. All interaction is through keyboard input.
HTML Requirements
The game expects the following HTML structure:
<canvas id="canvas"></canvas>
<div id="game" class="screen">
<div id="score">0</div>
<div id="level">1</div>
<div id="grid-size">10x10</div>
<div id="high-score">0</div>
<button id="new-game">New Game</button>
</div>
<div id="game-over" class="screen hidden">
<div id="final-score">0</div>
<div id="game-over-high-score">0</div>
<button id="play-again">Play Again</button>
</div>
<div id="pause" class="screen overlay hidden">
<!-- Pause overlay -->
</div>localStorage Keys
snake-high-score: Stores the high score as a string (e.g.,"42")