LyssaGame/src/Map.js

145 lines
4.7 KiB
JavaScript

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] === '<';
}
}