export class Map { constructor(width, height) { this.width = width; this.height = height; this.tiles = []; this.rooms = []; } generate() { this.rooms = []; // Initialize with walls for (let y = 0; y < this.height; y++) { this.tiles[y] = []; for (let x = 0; x < this.width; x++) { this.tiles[y][x] = '#'; } } const MAX_ROOMS = 10; const MIN_SIZE = 6; const MAX_SIZE = 12; for (let i = 0; i < MAX_ROOMS; i++) { const w = Math.floor(Math.random() * (MAX_SIZE - MIN_SIZE + 1)) + MIN_SIZE; const h = Math.floor(Math.random() * (MAX_SIZE - MIN_SIZE + 1)) + MIN_SIZE; const x = Math.floor(Math.random() * (this.width - w - 1)) + 1; const y = Math.floor(Math.random() * (this.height - h - 1)) + 1; const newRoom = { x, y, w, h }; // Check overlap let failed = false; for (const other of this.rooms) { if (newRoom.x <= other.x + other.w && newRoom.x + newRoom.w >= other.x && newRoom.y <= other.y + other.h && newRoom.y + newRoom.h >= other.y) { failed = true; break; } } if (!failed) { this.createRoom(newRoom); if (this.rooms.length > 0) { const prev = this.rooms[this.rooms.length - 1]; const newCenter = { x: Math.floor(newRoom.x + newRoom.w / 2), y: Math.floor(newRoom.y + newRoom.h / 2) }; const prevCenter = { x: Math.floor(prev.x + prev.w / 2), y: Math.floor(prev.y + prev.h / 2) }; if (Math.random() < 0.5) { this.createHKorridor(prevCenter.x, newCenter.x, prevCenter.y); this.createVKorridor(prevCenter.y, newCenter.y, newCenter.x); } else { this.createVKorridor(prevCenter.y, newCenter.y, prevCenter.x); this.createHKorridor(prevCenter.x, newCenter.x, newCenter.y); } } this.rooms.push(newRoom); } } } generateTown() { this.rooms = []; // Fill with grass/floor for (let y = 0; y < this.height; y++) { this.tiles[y] = []; for (let x = 0; x < this.width; x++) { this.tiles[y][x] = '.'; } } // Create buildings const numBuildings = 5; for (let i = 0; i < numBuildings; i++) { const w = Math.floor(Math.random() * 6) + 5; const h = Math.floor(Math.random() * 6) + 5; const x = Math.floor(Math.random() * (this.width - w - 2)) + 1; const y = Math.floor(Math.random() * (this.height - h - 2)) + 1; // Check overlap (simple check against other buildings) // For now, just place them. If they overlap, they merge. // Draw Walls for (let by = y; by < y + h; by++) { for (let bx = x; bx < x + w; bx++) { if (by === y || by === y + h - 1 || bx === x || bx === x + w - 1) { this.tiles[by][bx] = '#'; } else { this.tiles[by][bx] = '.'; } } } // Add Door (randomly on one side) if (Math.random() < 0.5) { // Horizontal wall door const doorX = Math.floor(Math.random() * (w - 2)) + x + 1; const doorY = Math.random() < 0.5 ? y : y + h - 1; this.tiles[doorY][doorX] = '.'; } else { // Vertical wall door const doorY = Math.floor(Math.random() * (h - 2)) + y + 1; const doorX = Math.random() < 0.5 ? x : x + w - 1; this.tiles[doorY][doorX] = '.'; } // Add to rooms list so we can spawn things inside if we want this.rooms.push({ x, y, w, h }); } } createRoom(room) { for (let y = room.y; y < room.y + room.h; y++) { for (let x = room.x; x < room.x + room.w; x++) { this.tiles[y][x] = '.'; } } } createHKorridor(x1, x2, y) { for (let x = Math.min(x1, x2); x <= Math.max(x1, x2); x++) { this.tiles[y][x] = '.'; } } createVKorridor(y1, y2, x) { for (let y = Math.min(y1, y2); y <= Math.max(y1, y2); y++) { this.tiles[y][x] = '.'; } } isWalkable(x, y) { if (x < 0 || x >= this.width || y < 0 || y >= this.height) return false; return this.tiles[y][x] === '.' || this.tiles[y][x] === '>'; } }