Spaces:
Sleeping
Sleeping
| // Level 2 - Underground Cave Theme | |
| import { Level, Block, Enemy } from './types'; | |
| import { GAME_CONFIG } from '../constants'; | |
| const { TILE_SIZE, LEVEL_HEIGHT } = GAME_CONFIG; | |
| const LEVEL_2_WIDTH = 3600; | |
| export function createLevel2(): Level { | |
| const blocks: Block[] = []; | |
| const enemies: Enemy[] = []; | |
| // Ground blocks with more gaps | |
| for (let x = 0; x < LEVEL_2_WIDTH; x += TILE_SIZE) { | |
| // Multiple gaps for underground feel | |
| const gaps = [ | |
| { start: 800, end: 900 }, | |
| { start: 1400, end: 1550 }, | |
| { start: 2200, end: 2350 }, | |
| { start: 2800, end: 2900 }, | |
| ]; | |
| const inGap = gaps.some(gap => x >= gap.start && x < gap.end); | |
| if (inGap) continue; | |
| // Ground layer (2 blocks high) | |
| 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', | |
| }); | |
| } | |
| // Ceiling blocks for underground feel | |
| for (let x = 0; x < LEVEL_2_WIDTH; x += TILE_SIZE) { | |
| blocks.push({ | |
| x, | |
| y: 0, | |
| width: TILE_SIZE, | |
| height: TILE_SIZE, | |
| type: 'ground', | |
| }); | |
| blocks.push({ | |
| x, | |
| y: TILE_SIZE, | |
| width: TILE_SIZE, | |
| height: TILE_SIZE, | |
| type: 'ground', | |
| }); | |
| } | |
| // Underground platforms - brick style | |
| const platforms = [ | |
| // First section - stepping stones | |
| { x: 200, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 280, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 360, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| // Question blocks with coins | |
| { x: 500, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 600, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| // Long platform section | |
| { x: 700, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 732, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 764, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| // After first gap | |
| { x: 950, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 1000, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'question' as const, hasCoin: true }, | |
| { x: 1050, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Mid-level platforms | |
| { x: 1200, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 1232, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 1264, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 1296, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| // High platform section | |
| { x: 1600, y: LEVEL_HEIGHT - TILE_SIZE * 7, type: 'brick' as const }, | |
| { x: 1632, y: LEVEL_HEIGHT - TILE_SIZE * 7, type: 'brick' as const }, | |
| { x: 1664, y: LEVEL_HEIGHT - TILE_SIZE * 7, type: 'question' as const, hasCoin: true }, | |
| { x: 1696, y: LEVEL_HEIGHT - TILE_SIZE * 7, type: 'brick' as const }, | |
| // Low platforms | |
| { x: 1800, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 1900, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 2000, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| // After gaps section | |
| { x: 2400, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'brick' as const }, | |
| { x: 2500, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 2600, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'brick' as const }, | |
| // Final staircase | |
| { x: 3000, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3032, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3032, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 3064, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3064, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 3064, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 3096, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 3096, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 3096, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 3096, y: LEVEL_HEIGHT - TILE_SIZE * 6, 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, | |
| }); | |
| }); | |
| // More pipes in underground | |
| const pipes = [ | |
| { x: 400, height: 2 }, | |
| { x: 1100, height: 3 }, | |
| { x: 1750, height: 2 }, | |
| { x: 2100, height: 4 }, | |
| { x: 2700, height: 2 }, | |
| ]; | |
| 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 | |
| const coinPositions = [ | |
| { x: 250, y: LEVEL_HEIGHT - TILE_SIZE * 7 }, | |
| { x: 282, y: LEVEL_HEIGHT - TILE_SIZE * 8 }, | |
| { x: 314, y: LEVEL_HEIGHT - TILE_SIZE * 7 }, | |
| { x: 1650, y: LEVEL_HEIGHT - TILE_SIZE * 9 }, | |
| { x: 2550, y: LEVEL_HEIGHT - TILE_SIZE * 8 }, | |
| ]; | |
| coinPositions.forEach(pos => { | |
| blocks.push({ | |
| x: pos.x, | |
| y: pos.y, | |
| width: 24, | |
| height: 24, | |
| type: 'coin', | |
| }); | |
| }); | |
| // More enemies - including Koopas | |
| const enemyPositions = [ | |
| { x: 350, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 650, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 750, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'goomba' as const }, | |
| { x: 1050, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'koopa' as const }, | |
| { x: 1350, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 1650, y: LEVEL_HEIGHT - TILE_SIZE * 9, type: 'goomba' as const }, | |
| { x: 1950, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'koopa' as const }, | |
| { x: 2450, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' as const }, | |
| { x: 2650, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'goomba' 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_2_WIDTH, | |
| height: LEVEL_HEIGHT, | |
| blocks, | |
| enemies, | |
| startPosition: { x: 64, y: LEVEL_HEIGHT - TILE_SIZE * 4 }, | |
| flagPosition: { x: 3200, y: LEVEL_HEIGHT - TILE_SIZE * 10 }, | |
| }; | |
| } | |