Spaces:
Sleeping
Sleeping
| // Level data and generation | |
| import { Level, Block, Enemy } from './types'; | |
| import { GAME_CONFIG } from '../constants'; | |
| const { TILE_SIZE, LEVEL_WIDTH, LEVEL_HEIGHT, COLORS } = GAME_CONFIG; | |
| export function createLevel1(): Level { | |
| const blocks: Block[] = []; | |
| const enemies: Enemy[] = []; | |
| // Ground blocks | |
| for (let x = 0; x < LEVEL_WIDTH; x += TILE_SIZE) { | |
| // Skip gaps | |
| const gapStart = 1200; | |
| const gapEnd = 1300; | |
| const gapStart2 = 2200; | |
| const gapEnd2 = 2350; | |
| if ((x >= gapStart && x < gapEnd) || (x >= gapStart2 && x < gapEnd2)) { | |
| 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', | |
| }); | |
| } | |
| // Brick and question block platforms | |
| const platforms = [ | |
| // First platform section | |
| { x: 400, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 500, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 532, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 564, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 596, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 628, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Second platform section | |
| { x: 800, y: LEVEL_HEIGHT - TILE_SIZE * 8, type: 'brick' as const }, | |
| { x: 832, y: LEVEL_HEIGHT - TILE_SIZE * 8, type: 'brick' as const }, | |
| { x: 864, y: LEVEL_HEIGHT - TILE_SIZE * 8, type: 'brick' as const }, | |
| // Third section | |
| { x: 1400, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 1500, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 1532, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| // Stairs section | |
| { x: 1600, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 1632, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 1632, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 1664, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 1664, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 1664, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 1696, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 1696, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 1696, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 1696, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'ground' as const }, | |
| // After second gap | |
| { x: 2400, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| { x: 2500, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'brick' as const }, | |
| { x: 2532, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'question' as const, hasCoin: true }, | |
| // Final stairs to flag | |
| { x: 2800, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 2832, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 2832, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 2864, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 2864, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 2864, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 2896, y: LEVEL_HEIGHT - TILE_SIZE * 3, type: 'ground' as const }, | |
| { x: 2896, y: LEVEL_HEIGHT - TILE_SIZE * 4, type: 'ground' as const }, | |
| { x: 2896, y: LEVEL_HEIGHT - TILE_SIZE * 5, type: 'ground' as const }, | |
| { x: 2896, y: LEVEL_HEIGHT - TILE_SIZE * 6, type: 'ground' as const }, | |
| { x: 2896, 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, | |
| }); | |
| }); | |
| // Pipes | |
| const pipes = [ | |
| { x: 700, height: 2 }, | |
| { x: 1000, height: 3 }, | |
| { x: 1900, height: 2 }, | |
| { x: 2600, 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: 300, y: LEVEL_HEIGHT - TILE_SIZE * 4 }, | |
| { x: 332, y: LEVEL_HEIGHT - TILE_SIZE * 4 }, | |
| { x: 850, y: LEVEL_HEIGHT - TILE_SIZE * 10 }, | |
| { x: 2450, y: LEVEL_HEIGHT - TILE_SIZE * 7 }, | |
| { x: 2482, y: LEVEL_HEIGHT - TILE_SIZE * 7 }, | |
| ]; | |
| coinPositions.forEach(pos => { | |
| blocks.push({ | |
| x: pos.x, | |
| y: pos.y, | |
| width: 24, | |
| height: 24, | |
| type: 'coin', | |
| }); | |
| }); | |
| // Enemies (Goombas) | |
| const goombaPositions = [ | |
| { x: 600, y: LEVEL_HEIGHT - TILE_SIZE * 3 }, | |
| { x: 900, y: LEVEL_HEIGHT - TILE_SIZE * 3 }, | |
| { x: 1100, y: LEVEL_HEIGHT - TILE_SIZE * 3 }, | |
| { x: 1450, y: LEVEL_HEIGHT - TILE_SIZE * 3 }, | |
| { x: 1800, y: LEVEL_HEIGHT - TILE_SIZE * 3 }, | |
| { x: 2450, y: LEVEL_HEIGHT - TILE_SIZE * 3 }, | |
| { x: 2700, y: LEVEL_HEIGHT - TILE_SIZE * 3 }, | |
| ]; | |
| goombaPositions.forEach(pos => { | |
| enemies.push({ | |
| x: pos.x, | |
| y: pos.y, | |
| vx: -1, | |
| vy: 0, | |
| width: 32, | |
| height: 32, | |
| type: 'goomba', | |
| isAlive: true, | |
| direction: -1, | |
| }); | |
| }); | |
| return { | |
| width: LEVEL_WIDTH, | |
| height: LEVEL_HEIGHT, | |
| blocks, | |
| enemies, | |
| startPosition: { x: 64, y: LEVEL_HEIGHT - TILE_SIZE * 4 }, | |
| flagPosition: { x: 3000, y: LEVEL_HEIGHT - TILE_SIZE * 10 }, | |
| }; | |
| } | |