This commit is contained in:
2025-12-12 00:13:55 +01:00
parent 158beec572
commit e15b429e75
17 changed files with 482 additions and 202 deletions

View File

@@ -26,7 +26,7 @@ class OceanSystem {
}
update(time, delta) {
if (!this.scene.player) return;
if (!this.scene.player || !this.scene.terrainSystem) return;
const playerPos = this.scene.player.getPosition();
const tile = this.scene.terrainSystem.getTile(playerPos.x, playerPos.y);
@@ -83,6 +83,8 @@ class OceanSystem {
return;
}
if (!this.scene.terrainSystem) return;
// Check if on water or near water?
// Actually, let's allow "deploying" boat anywhere, but only moving fast on water?
// OR: Only allow deploying on water tile.

View File

@@ -1,29 +1,34 @@
// ========================================================
// NOVE GLOBALNE KONSTANTE ZA LOKACIJE
// STARDEW VALLEY STYLE FOREST MAP - 100x100
// ========================================================
const MAP_SIZE = 100; // 100x100 velika mapa!
const FARM_SIZE = 8; // 8x8 MICRO FARM - Začetek igre!
const FARM_CENTER_X = 50; // Center mape (50,50)
const FARM_CENTER_Y = 50; // Center mape (50,50)
const CITY_SIZE = 15;
const CITY_START_X = 65; // Desni del mape (npr. med 65 in 80)
const CITY_START_Y = 65;
// Zapuščene hiše lokacije - ODSTRANJENO ZA TESTIRANJE!
const ABANDONED_HOUSES = [
// { x: 25, y: 25, size: 5 },
// { x: 75, y: 30, size: 6 },
// { x: 40, y: 75, size: 4 }
]; // PRAZNO - brez hiš!
// ========================================================
// NOVE KONSTANTE ZA RUDNIK IN RUDE
// GOZD KONSTANTE - STARDEW VALLEY STYLE (OPTIMIZIRANO)
// ========================================================
const TILE_STONE_ORE = 82; // ID za navadni kamen (Ore Tile)
const TILE_IRON_ORE = 83; // ID za železovo rudo
const TILE_PAVEMENT = 16; // ID za prehodno ploščico (tla rudnika)
const TILE_MINE_WALL = 81; // ID za zid rudnika (Solid/Kolizija)
// ID-ji Virov
const ITEM_STONE = 20; // ID za kamen, ki ga igralec dobi
const ITEM_IRON = 21; // ID za železo
const TREE_DENSITY_THRESHOLD = 0.45; // Višja vrednost = manj gosto (manj gozda)
const TREE_DENSITY = 0.01; // 1% chance za drevo (zelo nizka gostota)
const PURPLE_TREE_CHANCE = 0.30; // 30% vijolčnih dreves
const FRUIT_TREE_CHANCE = 0.20; // 20% sadnih dreves
const ROCK_DENSITY_THRESHOLD = 0.60; // Prag za skupine skal
// ========================================================
// RUDNIK KONSTANTE (za terrainTypes)
// ========================================================
const TILE_PAVEMENT = 16; // ID za prehodno ploščico
const TILE_MINE_WALL = 81; // ID za zid rudnika
const TILE_STONE_ORE = 82; // ID za navadni kamen
const TILE_IRON_ORE = 83; // ID za železovo rudo
// Terrain Generator System
class TerrainSystem {
constructor(scene, width = 100, height = 100) {
@@ -127,10 +132,35 @@ class TerrainSystem {
this.generatedChunks = new Set();
this.chunkSize = 10;
// FOREST GENERATION: Tracking postavljenih dreves za preverjanje razdalje
this.placedTrees = []; // Seznam vseh postavljenih dreves { x, y }
this.MIN_TREE_DISTANCE_SQUARED = 2 * 2; // Minimalna razdalja med drevesi (2 tiles)
// Init tiles array with NULLs
this.tiles = Array.from({ length: this.height }, () => Array(this.width).fill(null));
}
/**
* Preveri, ali je nova lokacija (newX, newY) dovolj oddaljena od vseh
* že postavljenih dreves. Uporablja kvadrat razdalje za hitrejšo optimizacijo.
*/
isTreeLocationFarEnough(newX, newY) {
for (let i = 0; i < this.placedTrees.length; i++) {
const existingTree = this.placedTrees[i];
// Izračunaj kvadrat razdalje
const dx = newX - existingTree.x;
const dy = newY - existingTree.y;
const distanceSq = (dx * dx) + (dy * dy);
// Če je razdalja manjša od zahtevane minimalne razdalje, zavrni lokacijo
if (distanceSq < this.MIN_TREE_DISTANCE_SQUARED) {
return false;
}
}
return true; // Lokacija je dovolj oddaljena
}
createTileTextures() {
const tileWidth = 48;
const tileHeight = 60;
@@ -373,186 +403,87 @@ class TerrainSystem {
for (let y = startY; y < endY; y++) {
for (let x = startX; x < endX; x++) {
// --- PER TILE GENERATION LOGIC (Moved from old loop) ---
const nx = x * 0.1;
const ny = y * 0.1;
const elevation = this.noise.noise(nx, ny);
// SIMPLE TERRAIN - samo grass (brez elevation/stone/hills)
let terrainType = this.terrainTypes.GRASS_FULL;
// Edges of WORLD -也 grass
// (removed elevation-based terrain - user wants clean platform)
// --- STARDEW VALLEY FOREST GENERATION ---
let terrainType = this.terrainTypes.GRASS_FULL; // Vsa mapa je trava!
// Farm Override - ZELENA PLATFORMA!
if (Math.abs(x - FARM_CENTER_X) <= FARM_SIZE / 2 && Math.abs(y - FARM_CENTER_Y) <= FARM_SIZE / 2) {
terrainType = this.terrainTypes.GRASS_FULL; // ZELENA TRAVA!
terrainType = this.terrainTypes.GRASS_FULL;
}
// RIVER Override - VIJUGAST POTOK!
// River gre diagonalno skozi mapo z sinusnim vijuganjem
const riverCenterY = 50; // Center Y pozicija za river
const riverWidth = 3; // Širina potoka (3 tiles)
const waveAmplitude = 8; // Amplituda vijuganja
const waveFrequency = 0.1; // Frekvenca vijuganja
// Izračun vijugaste poti
const riverOffset = Math.sin(x * waveFrequency) * waveAmplitude;
const riverY = riverCenterY + riverOffset;
// Če je tile znotraj river area
if (Math.abs(y - riverY) <= riverWidth / 2) {
terrainType = this.terrainTypes.WATER; // VODA!
}
// City Override - DISABLED (User request: no walls)
// if (x >= CITY_START_X && x < CITY_START_X + CITY_SIZE &&
// y >= CITY_START_Y && y < CITY_START_Y + CITY_SIZE) {
// const isEdge = (x === CITY_START_X ||
// x === CITY_START_X + CITY_SIZE - 1 ||
// y === CITY_START_Y ||
// y === CITY_START_Y + CITY_SIZE - 1);
// if (isEdge) {
// terrainType = { name: 'WALL_EDGE', color: 0x505050, solid: true };
// } else {
// terrainType = this.terrainTypes.PAVEMENT;
// if (Math.random() < 0.15) {
// terrainType = this.terrainTypes.RUINS;
// }
// }
// }
// Zapuščene hiše - DIRT tiles
let isHouse = false;
ABANDONED_HOUSES.forEach(house => {
if (x >= house.x && x < house.x + house.size &&
y >= house.y && y < house.y + house.size) {
terrainType = this.terrainTypes.DIRT; // Hiša na DIRT
isHouse = true;
}
});
// Create Tile Data
this.tiles[y][x] = {
type: terrainType.name,
texture: terrainType.name === 'water' ? 'water_frame_0' : terrainType.name, // Water tiles get animated frame!
texture: terrainType.name,
hasDecoration: false,
hasCrop: false,
solid: terrainType.solid || false
solid: terrainType.solid || false,
isHouse: isHouse
};
// Track water tiles za animacijo
if (terrainType.name === 'water') {
this.waterTiles.push(this.tiles[y][x]);
}
// Track valid positions for decorations
if (terrainType.name !== 'water' && terrainType.name !== 'sand' && terrainType.name !== 'stone' && !terrainType.solid) {
// Exclude Farm/City from random decor logic
// Track valid positions for decorations (TREES!)
if (terrainType.name === 'grass_full' && !isHouse) {
const isFarm = Math.abs(x - FARM_CENTER_X) <= (FARM_SIZE / 2 + 2) && Math.abs(y - FARM_CENTER_Y) <= (FARM_SIZE / 2 + 2);
const isCity = x >= CITY_START_X - 2 && x < CITY_START_X + CITY_SIZE + 2 && y >= CITY_START_Y - 2 && y < CITY_START_Y + CITY_SIZE + 2;
if (!isFarm && !isCity) {
if (!isFarm) {
validPositions.push({ x, y });
}
}
// Direct Placement Calls (Trees/Rocks) - legacy method support
// this.placeTree(x, y, terrainType.name); // Optional: keep this if preferred over random batch
}
}
// --- CHUNK DECORATION PASS ---
// DISABLED - User wants clean platform (no trees, rocks, flowers)
// 1. Random Decorations - DISABLED
// validPositions.forEach(pos => {
// // Trees
// if (Math.random() < 0.05) {
// this.placeTree(pos.x, pos.y, 'grass');
// }
// // Rocks
// if (Math.random() < 0.02) {
// this.placeRock(pos.x, pos.y, 'grass');
// }
// // Flowers
// if (Math.random() < 0.05) {
// const flowers = ['flower_red', 'flower_yellow', 'flower_blue'];
// const flowerType = flowers[Math.floor(Math.random() * flowers.length)];
// this.addDecoration(pos.x, pos.y, flowerType);
// }
// // Path Stones
// if (Math.random() < 0.02) {
// this.addDecoration(pos.x, pos.y, 'path_stone');
// }
// });
// MICRO FARM FENCE (8x8 starting area) - DISABLED FOR NOW
// Will be added properly later
// --- STARDEW VALLEY FOREST DECORATION PASS ---
const farmMinX = FARM_CENTER_X - FARM_SIZE / 2;
const farmMaxX = FARM_CENTER_X + FARM_SIZE / 2;
const farmMinY = FARM_CENTER_Y - FARM_SIZE / 2;
const farmMaxY = FARM_CENTER_Y + FARM_SIZE / 2;
// DECORATIONS: Flowers & Bushes on grass tiles (random)
for (let y = startY; y < endY; y++) {
for (let x = startX; x < endX; x++) {
const tile = this.tiles[y][x]; // Corrected access to this.tiles
// DREVESA - 3% gostota z preverjanjem razdalje!
validPositions.forEach(pos => {
const rand = Math.random();
// Only on grass tiles, outside farm area
if (tile && tile.type === 'GRASS_FULL' && // Changed 'grass' to 'GRASS_FULL' to match terrainType.name
(x < farmMinX || x > farmMaxX || y < farmMinY || y > farmMaxY)) {
const rand = Math.random();
// 10% chance for flowers
if (rand < 0.10) {
const flowerTypes = ['flowers_new', 'flowers_pink_isometric'];
const randomType = flowerTypes[Math.floor(Math.random() * flowerTypes.length)];
this.addDecoration(x, y, randomType);
}
// 8% chance for grass patches (visual variety)
else if (rand >= 0.10 && rand < 0.18) {
this.addDecoration(x, y, 'grass_sprite');
}
// 5% chance for bushes
else if (rand >= 0.18 && rand < 0.23) {
this.addDecoration(x, y, 'bush_small');
}
// 3% chance for small rocks
else if (rand >= 0.23 && rand < 0.26) {
const rockTypes = ['rock_small', 'rock_2'];
const randomRock = rockTypes[Math.floor(Math.random() * rockTypes.length)];
this.addDecoration(x, y, randomRock);
}
// 3% chance za drevo
if (rand < TREE_DENSITY) {
// PREVERJANJE RAZDALJE: Ali je ta lokacija dovolj oddaljena?
if (!this.isTreeLocationFarEnough(pos.x, pos.y)) {
return; // Preskoči to lokacijo - preblizu drugim drevesom!
}
}
}
// Check if this chunk contains farm border
if (cx * this.chunkSize <= farmMaxX && (cx + 1) * this.chunkSize >= farmMinX &&
cy * this.chunkSize <= farmMaxY && (cy + 1) * this.chunkSize >= farmMinY) {
const treeRand = Math.random();
let treeType;
// Top border (y = farmMinY)
if (startY <= farmMinY && endY > farmMinY) {
for (let x = Math.max(startX, farmMinX); x <= Math.min(endX - 1, farmMaxX); x++) {
this.addDecoration(x, farmMinY, 'fence_isometric');
// 30% VIJOLČNA DREVESA
if (treeRand < PURPLE_TREE_CHANCE) {
treeType = 'tree_purple';
}
}
// Bottom border (y = farmMaxY)
if (startY <= farmMaxY && endY > farmMaxY) {
for (let x = Math.max(startX, farmMinX); x <= Math.min(endX - 1, farmMaxX); x++) {
this.addDecoration(x, farmMaxY, 'fence_isometric');
// 20% SADNA DREVESA
else if (treeRand < PURPLE_TREE_CHANCE + FRUIT_TREE_CHANCE) {
const fruitTypes = ['tree_apple', 'tree_pear', 'tree_cherry'];
treeType = fruitTypes[Math.floor(Math.random() * fruitTypes.length)];
}
}
// Left border (x = farmMinX)
if (startX <= farmMinX && endX > farmMinX) {
for (let y = Math.max(startY, farmMinY); y <= Math.min(endY - 1, farmMaxY); y++) {
this.addDecoration(farmMinX, y, 'fence_isometric');
// 50% NAVADNA DREVESA
else {
const normalTrees = ['tree_green_final', 'tree_blue_final', 'tree_sapling'];
treeType = normalTrees[Math.floor(Math.random() * normalTrees.length)];
}
}
// Right border (x = farmMaxX)
if (startX <= farmMaxX && endX > farmMaxX) {
for (let y = Math.max(startY, farmMinY); y <= Math.min(endY - 1, farmMaxY); y++) {
this.addDecoration(farmMaxX, y, 'fence_isometric');
}
// DODAJ DREVO
this.addDecoration(pos.x, pos.y, treeType);
this.placedTrees.push({ x: pos.x, y: pos.y });
}
}
});
// KONEC generateChunk
}
updateChunks(camera) {
@@ -777,18 +708,22 @@ class TerrainSystem {
let scale = 1.0;
if (type === 'rock_1' || type === 'rock_2') scale = 1.5; // Povečano (bilo 0.5)
// POMANJŠANA DREVESA - Stardew Valley stil
if (type === 'rock_1' || type === 'rock_2') scale = 1.0; // Zmanjšano
else if (type === 'tree_green_new' || type === 'tree_blue_new' || type === 'tree_dead_new') scale = 0.04;
else if (type === 'flowers_new') scale = 0.02;
else if (type === 'fence') scale = 0.025;
else if (type === 'gravestone') scale = 0.03;
else if (type === 'hill_sprite') scale = 0.025;
else if (type.includes('_final')) scale = 1.0; // New Final Trees
else if (type.includes('_final')) scale = 0.7; // POMANJŠANO - final trees
else if (type.includes('purple') || type.includes('apple') || type.includes('pear') || type.includes('cherry')) {
scale = 0.6; // POMANJŠANO - novi sadni in vijolčni
}
else {
// Old Assets (Low Res)
if (type.includes('tree')) scale = 1.2 + Math.random() * 0.4;
else if (type.includes('rock')) scale = 0.8;
else scale = 1.0;
if (type.includes('tree')) scale = 0.7 + Math.random() * 0.2; // POMANJŠANO (bilo 1.2-1.6)
else if (type.includes('rock')) scale = 0.6; // POMANJŠANO
else scale = 0.8; // POMANJŠANO
}
// Calculate Plant Day for Saplings (Growth System)