FAZA 1: Terrain generation with Perlin noise and isometric view - Ready for testing

This commit is contained in:
2025-12-06 17:54:45 +01:00
parent 7e20dff962
commit d61df381cb
7 changed files with 630 additions and 20 deletions

View File

@@ -0,0 +1,126 @@
// Terrain Generator System
// Generira proceduralni isometrični teren
class TerrainSystem {
constructor(scene, width = 100, height = 100) {
this.scene = scene;
this.width = width;
this.height = height;
this.iso = new IsometricUtils(48, 24);
this.noise = new PerlinNoise(Date.now());
this.tiles = [];
this.tileSprites = [];
// Tipi terena z threshold vrednostmi
this.terrainTypes = {
WATER: { threshold: 0.3, color: 0x2166aa, name: 'water' },
SAND: { threshold: 0.4, color: 0xf4e7c6, name: 'sand' },
GRASS: { threshold: 0.65, color: 0x5cb85c, name: 'grass' },
DIRT: { threshold: 0.75, color: 0x8b6f47, name: 'dirt' },
STONE: { threshold: 1.0, color: 0x7d7d7d, name: 'stone' }
};
}
// Generiraj teren
generate() {
console.log(`🌍 Generating terrain: ${this.width}x${this.height}...`);
// Generiraj tile podatke
for (let y = 0; y < this.height; y++) {
this.tiles[y] = [];
for (let x = 0; x < this.width; x++) {
const noiseValue = this.noise.getNormalized(x, y, 0.05, 4);
const terrainType = this.getTerrainType(noiseValue);
this.tiles[y][x] = {
gridX: x,
gridY: y,
type: terrainType.name,
color: terrainType.color,
height: noiseValue
};
}
}
console.log('✅ Terrain data generated!');
}
// Določi tip terena glede na noise vrednost
getTerrainType(value) {
for (const type of Object.values(this.terrainTypes)) {
if (value < type.threshold) {
return type;
}
}
return this.terrainTypes.STONE;
}
// Renderaj teren (visual sprites)
render(offsetX = 0, offsetY = 300) {
console.log('🎨 Rendering terrain sprites...');
const container = this.scene.add.container(offsetX, offsetY);
// Renderaj vse tile-e
for (let y = 0; y < this.height; y++) {
for (let x = 0; x < this.width; x++) {
const tile = this.tiles[y][x];
const screenPos = this.iso.toScreen(x, y);
// Kreira diamond (romb) obliko za isometric tile
const graphics = this.scene.add.graphics();
// Osnovna barva
const baseColor = tile.color;
graphics.fillStyle(baseColor, 1);
// Nariši isometric tile (diamond shape)
const tileWidth = this.iso.tileWidth;
const tileHeight = this.iso.tileHeight;
graphics.beginPath();
graphics.moveTo(screenPos.x, screenPos.y); // Top
graphics.lineTo(screenPos.x + tileWidth / 2, screenPos.y + tileHeight / 2); // Right
graphics.lineTo(screenPos.x, screenPos.y + tileHeight); // Bottom
graphics.lineTo(screenPos.x - tileWidth / 2, screenPos.y + tileHeight / 2); // Left
graphics.closePath();
graphics.fillPath();
// Outline za boljšo vidljivost
graphics.lineStyle(1, 0x000000, 0.2);
graphics.strokePath();
// Dodaj v container
container.add(graphics);
// Shrani referenco
this.tileSprites.push({
graphics: graphics,
tile: tile,
depth: this.iso.getDepth(x, y)
});
}
}
// Sortiraj po depth
container.setDepth(0);
console.log(`✅ Rendered ${this.tileSprites.length} tiles!`);
return container;
}
// Pridobi tile na določenih grid koordinatah
getTile(gridX, gridY) {
if (gridX >= 0 && gridX < this.width && gridY >= 0 && gridY < this.height) {
return this.tiles[gridY][gridX];
}
return null;
}
// Screen koordinate -> tile
getTileAtScreen(screenX, screenY) {
const grid = this.iso.toGrid(screenX, screenY);
return this.getTile(grid.x, grid.y);
}
}