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] = '.'; } } // Helper to draw a building const drawBuilding = (x, y, w, h, doorSide) => { // 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] = '.'; } } } // Door if (doorSide === 'bottom') { this.tiles[y + h - 1][Math.floor(x + w / 2)] = '.'; } else if (doorSide === 'top') { this.tiles[y][Math.floor(x + w / 2)] = '.'; } else if (doorSide === 'left') { this.tiles[Math.floor(y + h / 2)][x] = '.'; } else if (doorSide === 'right') { this.tiles[Math.floor(y + h / 2)][x + w - 1] = '.'; } // Add to rooms for reference this.rooms.push({ x, y, w, h }); }; // 1. Temple (North Center) drawBuilding(20, 5, 10, 8, 'bottom'); // 2. General Store (West) drawBuilding(5, 15, 8, 6, 'right'); // 3. Weapon Shop (East) drawBuilding(37, 15, 8, 6, 'left'); // 4. Dungeon Entrance (North East) drawBuilding(40, 5, 6, 6, 'bottom'); // 5. Houses (South) drawBuilding(10, 30, 6, 5, 'top'); drawBuilding(22, 30, 6, 5, 'top'); drawBuilding(34, 30, 6, 5, 'top'); } 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] === '>' || this.tiles[y][x] === '<'; } }