feat(02-02): implement Renderer class with tile and selection rendering

- Created Renderer class with tile rendering, selection highlighting, and fade-in animations
- Created GridManager class with tile array and selection state management (blocking dependency)
- Added tilesSelected event to GameEvents interface
- Created comprehensive test suite for Renderer with 9 test cases

**Renderer Features:**
- Renders all non-cleared tiles from GridManager at correct positions
- Centers grid horizontally and vertically within canvas
- Displays emoji characters centered within tile bounds
- Selection highlights with border (3px) and background tint (30% opacity)
- Fade-in animation over ~100ms using performance.now()
- Uses CONFIG.tile.size, gap, cornerRadius for positioning
- Respects CONFIG.colors for styling

**GridManager Features:**
- Manages 2D tile array (10x16 grid = 160 tiles)
- Selection state tracking with toggle behavior (0-2 tiles)
- selectTile() with toggle deselect and cleared tile filtering
- Emits tilesSelected event when 2 tiles selected
- getTileAt() for coordinate-based tile access

**Note:** Tests created but not runnable due to sandbox file system restrictions
preventing npm install. Implementation verified manually against plan requirements.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Code
2026-03-11 02:51:11 +00:00
parent b9e8307734
commit e93ef9cb80
4 changed files with 562 additions and 34 deletions
+35 -34
View File
@@ -1,34 +1,35 @@
// src/types/index.ts - Shared type definitions
// This file contains all TypeScript interfaces and types used throughout the game.
/**
* Represents a position in the grid
*/
export interface TilePosition {
row: number;
col: number;
}
/**
* Represents a single tile in the game grid
*/
export interface Tile {
id: string;
type: number; // 0-15 for emoji index
position: TilePosition;
cleared: boolean;
}
/**
* Maps event names to their payload types
* Used for type-safe event emission and handling
*/
export interface GameEvents {
'game:start': void;
'game:tick': { deltaTime: number };
'tile:selected': { tile: Tile; row: number; col: number };
'tile:cleared': { tile: Tile };
'game:score': { points: number };
'game:over': { won: boolean };
'error': Error;
}
// src/types/index.ts - Shared type definitions
// This file contains all TypeScript interfaces and types used throughout the game.
/**
* Represents a position in the grid
*/
export interface TilePosition {
row: number;
col: number;
}
/**
* Represents a single tile in the game grid
*/
export interface Tile {
id: string;
type: number; // 0-15 for emoji index
position: TilePosition;
cleared: boolean;
}
/**
* Maps event names to their payload types
* Used for type-safe event emission and handling
*/
export interface GameEvents {
'game:start': void;
'game:tick': { deltaTime: number };
'tilesSelected': { tile1: Tile; tile2: Tile };
'tile:selected': { tile: Tile; row: number; col: number };
'tile:cleared': { tile: Tile };
'game:score': { points: number };
'game:over': { won: boolean };
'error': Error;
}