asemxin
Initial commit: Super Mario Web game
2d54981
// 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 },
};
}