Spaces:
Sleeping
Sleeping
| // Level 3 - Castle Theme | |
| import { Level, Block, Enemy } from './types'; | |
| import { GAME_CONFIG } from '../constants'; | |
| const { TILE_SIZE, LEVEL_HEIGHT } = GAME_CONFIG; | |
| const LEVEL_3_WIDTH = 4000; | |
| export function createLevel3(): Level { | |
| const blocks: Block[] = []; | |
| const enemies: Enemy[] = []; | |
| // Ground blocks with lava pits | |
| for (let x = 0; x < LEVEL_3_WIDTH; x += TILE_SIZE) { | |
| // Lava pit positions (deadly gaps) | |
| const lavaPits = [ | |
| { start: 600, end: 750 }, | |
| { start: 1200, end: 1400 }, | |
| { start: 1800, end: 1950 }, | |
| { start: 2400, end: 2600 }, | |
| { start: 3000, end: 3150 }, | |
| ]; | |
| const inLava = lavaPits.some(pit => x >= pit.start && x < pit.end); | |
| if (inLava) continue; | |
| // Castle floor (darker ground) | |
| blocks.push({ | |
| x, | |
| y: LEVEL_HEIGHT - TILE_SIZE, | |
| width: TILE_SIZE, | |
| height: TILE_SIZE, | |
| type: 'ground', | |
| }); | |
| blocks.push({ | |
| x, | |
| y: LEVEL_HEIGHT - TILE_SIZE * 2, | |
| width: TILE_SIZE, | |
| height: TILE_SIZE, | |
| type: 'ground', | |
| }); | |
| } | |
| // Castle walls and platforms | |
| const platforms = [ | |
| // Early section - stepping platforms | |
| { x: 200, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 300, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 400, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'question' as const, hasCoin: true }, | |
| { x: 500, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Over first lava pit | |
| { x: 620, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 680, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| { x: 740, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Mid section | |
| { x: 850, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 950, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 1050, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| { x: 1100, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| // Over second lava pit - tricky jumps | |
| { x: 1220, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 1280, y: LEVEL_HEIGHT - TILE_SIZE * 7, type: 'brick' as const }, | |
| { x: 1340, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Question block cluster | |
| { x: 1500, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 1532, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 1564, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| // High platform section | |
| { x: 1650, y: LEVEL_HEIGHT - TILE_SIZE * 8, type: 'brick' as const }, | |
| { x: 1682, y: LEVEL_HEIGHT - TILE_SIZE * 8, type: 'brick' as const }, | |
| { x: 1714, y: LEVEL_HEIGHT - TILE_SIZE * 8, type: 'brick' as const }, | |
| // Over third lava pit | |
| { x: 1820, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 1880, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| { x: 1940, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Long platform run | |
| { x: 2050, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2082, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2114, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2146, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2178, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2210, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2242, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2274, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| // Over fourth lava pit | |
| { x: 2420, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 2480, y: LEVEL_HEIGHT - TILE_SIZE * 7, type: 'question' as const, hasCoin: true }, | |
| { x: 2540, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Pre-boss section | |
| { x: 2700, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2800, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 2900, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| // Over fifth lava pit | |
| { x: 3020, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 3080, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| { x: 3140, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Final staircase to flag | |
| { x: 3300, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3332, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3332, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 3364, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3364, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 3364, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 3396, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3396, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 3396, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 3396, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'ground' as const }, | |
| { x: 3428, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3428, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 3428, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 3428, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'ground' as const }, | |
| { x: 3428, y: LEVEL_HEIGHT - TILE_SIZE * 7, type: 'ground' as const }, | |
| ]; | |
| platforms.forEach(p => { | |
| blocks.push({ | |
| x: p.x, | |
| y: p.y, | |
| width: TILE_SIZE, | |
| height: TILE_SIZE, | |
| type: p.type, | |
| hasCoin: p.hasCoin, | |
| }); | |
| }); | |
| // Fewer pipes in castle | |
| const pipes = [ | |
| { x: 800, height: 2 }, | |
| { x: 2000, height: 2 }, | |
| { x: 2650, height: 3 }, | |
| ]; | |
| pipes.forEach(pipe => { | |
| for (let h = 0; h < pipe.height; h++) { | |
| blocks.push({ | |
| x: pipe.x, | |
| y: LEVEL_HEIGHT - TILE_SIZE * 2 - (h * TILE_SIZE), | |
| width: TILE_SIZE * 2, | |
| height: TILE_SIZE, | |
| type: 'pipe', | |
| }); | |
| } | |
| }); | |
| // Floating coins - harder to get | |
| const coinPositions = [ | |
| { x: 680, y: LEVEL_HEIGHT - TILE_SIZE * 8 }, | |
| { x: 1280, y: LEVEL_HEIGHT - TILE_SIZE * 9 }, | |
| { x: 1880, y: LEVEL_HEIGHT - TILE_SIZE * 8 }, | |
| { x: 2480, y: LEVEL_HEIGHT - TILE_SIZE * 9 }, | |
| { x: 3080, y: LEVEL_HEIGHT - TILE_SIZE * 8 }, | |
| ]; | |
| coinPositions.forEach(pos => { | |
| blocks.push({ | |
| x: pos.x, | |
| y: pos.y, | |
| width: 24, | |
| height: 24, | |
| type: 'coin', | |
| }); | |
| }); | |
| // Many enemies - challenging! | |
| const enemyPositions = [ | |
| { x: 250, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 450, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'koopa' as const }, | |
| { x: 900, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 1000, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 1450, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'koopa' as const }, | |
| { x: 1700, y: LEVEL_HEIGHT - TILE_SIZE * 10, type: 'goomba' as const }, | |
| { x: 2100, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'goomba' as const }, | |
| { x: 2200, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'koopa' as const }, | |
| { x: 2750, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 2850, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 3200, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'koopa' as const }, | |
| ]; | |
| enemyPositions.forEach(pos => { | |
| enemies.push({ | |
| x: pos.x, | |
| y: pos.y, | |
| vx: -1, | |
| vy: 0, | |
| width: 32, | |
| height: pos.type === 'koopa' ? 40 : 32, | |
| type: pos.type, | |
| isAlive: true, | |
| direction: -1, | |
| }); | |
| }); | |
| return { | |
| width: LEVEL_3_WIDTH, | |
| height: LEVEL_HEIGHT, | |
| blocks, | |
| enemies, | |
| startPosition: { x: 64, y: LEVEL_HEIGHT - TILE_SIZE * 4 }, | |
| flagPosition: { x: 3550, y: LEVEL_HEIGHT - TILE_SIZE * 10 }, | |
| }; | |
| } | |