Multidirectional map generation
This commit is contained in:
@@ -177,6 +177,7 @@ export type Inventory = {
|
|||||||
export type RunState = {
|
export type RunState = {
|
||||||
stats: Stats;
|
stats: Stats;
|
||||||
inventory: Inventory;
|
inventory: Inventory;
|
||||||
|
seed: number;
|
||||||
lastReloadableWeaponId?: string | null;
|
lastReloadableWeaponId?: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,13 +38,13 @@ export function generateWorld(floor: number, runState: RunState): { world: World
|
|||||||
const height = GAME_CONFIG.map.height;
|
const height = GAME_CONFIG.map.height;
|
||||||
const tiles: Tile[] = new Array(width * height).fill(TileType.WALL);
|
const tiles: Tile[] = new Array(width * height).fill(TileType.WALL);
|
||||||
|
|
||||||
const random = seededRandom(floor * 12345);
|
const random = seededRandom(runState.seed + floor * 12345);
|
||||||
|
|
||||||
// Create ECS World first
|
// Create ECS World first
|
||||||
const ecsWorld = new ECSWorld(); // Starts at ID 1 by default
|
const ecsWorld = new ECSWorld(); // Starts at ID 1 by default
|
||||||
|
|
||||||
// Set ROT's RNG seed for consistent dungeon generation
|
// Set ROT's RNG seed for consistent dungeon generation
|
||||||
ROT.RNG.setSeed(floor * 12345);
|
ROT.RNG.setSeed(runState.seed + floor * 12345);
|
||||||
|
|
||||||
// Replace generateRooms call with track-first logic for mine cart mechanic
|
// Replace generateRooms call with track-first logic for mine cart mechanic
|
||||||
const { rooms, trackPath } = generateTrackLevel(width, height, tiles, floor, random);
|
const { rooms, trackPath } = generateTrackLevel(width, height, tiles, floor, random);
|
||||||
@@ -156,19 +156,52 @@ function generateTrackLevel(width: number, height: number, tiles: Tile[], _floor
|
|||||||
|
|
||||||
// 1. Generate a winding path of "Anchor Points" for rooms
|
// 1. Generate a winding path of "Anchor Points" for rooms
|
||||||
const anchors: Vec2[] = [];
|
const anchors: Vec2[] = [];
|
||||||
let currA = { x: 10, y: Math.floor(height / 2) };
|
const startDir = Math.floor(random() * 4); // 0: East, 1: West, 2: South, 3: North
|
||||||
anchors.push({ ...currA });
|
|
||||||
|
|
||||||
const targetX = width - 10;
|
let currA: Vec2;
|
||||||
|
const margin = 10;
|
||||||
const stepSize = 12;
|
const stepSize = 12;
|
||||||
|
|
||||||
while (currA.x < targetX) {
|
if (startDir === 0) { // East (Left to Right)
|
||||||
const nextX = currA.x + Math.floor(stepSize * (0.8 + random() * 0.4));
|
currA = { x: margin, y: margin + Math.floor(random() * (height - margin * 2)) };
|
||||||
const nextY = currA.y + Math.floor((random() - 0.5) * height * 0.6);
|
} else if (startDir === 1) { // West (Right to Left)
|
||||||
|
currA = { x: width - margin, y: margin + Math.floor(random() * (height - margin * 2)) };
|
||||||
|
} else if (startDir === 2) { // South (Top to Bottom)
|
||||||
|
currA = { x: margin + Math.floor(random() * (width - margin * 2)), y: margin };
|
||||||
|
} else { // North (Bottom to Top)
|
||||||
|
currA = { x: margin + Math.floor(random() * (width - margin * 2)), y: height - margin };
|
||||||
|
}
|
||||||
|
|
||||||
|
anchors.push({ ...currA });
|
||||||
|
|
||||||
|
const isFinished = () => {
|
||||||
|
if (startDir === 0) return currA.x >= width - margin;
|
||||||
|
if (startDir === 1) return currA.x <= margin;
|
||||||
|
if (startDir === 2) return currA.y >= height - margin;
|
||||||
|
return currA.y <= margin;
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!isFinished()) {
|
||||||
|
let nextX = currA.x;
|
||||||
|
let nextY = currA.y;
|
||||||
|
|
||||||
|
if (startDir === 0) { // East
|
||||||
|
nextX += Math.floor(stepSize * (0.8 + random() * 0.4));
|
||||||
|
nextY += Math.floor((random() - 0.5) * height * 0.4);
|
||||||
|
} else if (startDir === 1) { // West
|
||||||
|
nextX -= Math.floor(stepSize * (0.8 + random() * 0.4));
|
||||||
|
nextY += Math.floor((random() - 0.5) * height * 0.4);
|
||||||
|
} else if (startDir === 2) { // South
|
||||||
|
nextY += Math.floor(stepSize * (0.8 + random() * 0.4));
|
||||||
|
nextX += Math.floor((random() - 0.5) * width * 0.4);
|
||||||
|
} else { // North
|
||||||
|
nextY -= Math.floor(stepSize * (0.8 + random() * 0.4));
|
||||||
|
nextX += Math.floor((random() - 0.5) * width * 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
currA = {
|
currA = {
|
||||||
x: Math.min(width - 5, nextX),
|
x: Math.max(margin / 2, Math.min(width - margin / 2, nextX)),
|
||||||
y: Math.max(5, Math.min(height - 5, nextY))
|
y: Math.max(margin / 2, Math.min(height - margin / 2, nextY))
|
||||||
};
|
};
|
||||||
anchors.push({ ...currA });
|
anchors.push({ ...currA });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
public runState: RunState = {
|
public runState: RunState = {
|
||||||
stats: { ...GAME_CONFIG.player.initialStats },
|
stats: { ...GAME_CONFIG.player.initialStats },
|
||||||
inventory: { gold: 0, items: [] },
|
inventory: { gold: 0, items: [] },
|
||||||
|
seed: Math.floor(Math.random() * 1000000),
|
||||||
lastReloadableWeaponId: null
|
lastReloadableWeaponId: null
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -478,6 +479,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
this.runState = {
|
this.runState = {
|
||||||
stats: { ...p.stats },
|
stats: { ...p.stats },
|
||||||
inventory: { gold: p.inventory.gold, items: [...p.inventory.items] },
|
inventory: { gold: p.inventory.gold, items: [...p.inventory.items] },
|
||||||
|
seed: this.runState.seed,
|
||||||
lastReloadableWeaponId: this.runState.lastReloadableWeaponId
|
lastReloadableWeaponId: this.runState.lastReloadableWeaponId
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -486,6 +488,7 @@ export class GameScene extends Phaser.Scene {
|
|||||||
this.runState = {
|
this.runState = {
|
||||||
stats: { ...GAME_CONFIG.player.initialStats },
|
stats: { ...GAME_CONFIG.player.initialStats },
|
||||||
inventory: { gold: 0, items: [] },
|
inventory: { gold: 0, items: [] },
|
||||||
|
seed: Math.floor(Math.random() * 1000000),
|
||||||
lastReloadableWeaponId: null
|
lastReloadableWeaponId: null
|
||||||
};
|
};
|
||||||
this.floorIndex = 1;
|
this.floorIndex = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user