farma updejt
This commit is contained in:
@@ -43,6 +43,84 @@ window.Antigravity = {
|
||||
}
|
||||
},
|
||||
|
||||
Camera: {
|
||||
/**
|
||||
* Nastavi kamero, da sledi tarči
|
||||
* @param {Phaser.Scene} scene
|
||||
* @param {Phaser.GameObjects.GameObject} target
|
||||
*/
|
||||
follow: function (scene, target) {
|
||||
if (scene.cameras && scene.cameras.main && target) {
|
||||
// Uporabimo lerp za gladko sledenje (0.1, 0.1)
|
||||
scene.cameras.main.startFollow(target, true, 0.1, 0.1);
|
||||
console.log('📷 Antigravity Camera: Following target');
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Nastavi zoom stopnjo kamere
|
||||
* @param {Phaser.Scene} scene
|
||||
* @param {number} zoomLevel
|
||||
*/
|
||||
setZoom: function (scene, zoomLevel) {
|
||||
if (scene.cameras && scene.cameras.main) {
|
||||
scene.cameras.main.setZoom(zoomLevel);
|
||||
console.log(`🔍 Antigravity Camera: Zoom set to ${zoomLevel}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
UI: {
|
||||
showMessage: function (scene, message, color = '#ffffff') {
|
||||
if (scene.events && scene.player) {
|
||||
scene.events.emit('show-floating-text', {
|
||||
x: scene.player.x,
|
||||
y: scene.player.y - 60,
|
||||
text: message,
|
||||
color: color
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
setText: function (scene, elementId, text) {
|
||||
const ui = scene.scene.get('UIScene');
|
||||
if (ui && ui[elementId]) {
|
||||
ui[elementId].setText(text);
|
||||
}
|
||||
},
|
||||
|
||||
setBarValue: function (scene, elementId, percent) {
|
||||
const ui = scene.scene.get('UIScene');
|
||||
if (ui && ui[elementId] && ui.setBarValue) {
|
||||
ui.setBarValue(ui[elementId], percent);
|
||||
}
|
||||
},
|
||||
|
||||
drawRectangle: function (scene, x, y, width, height, color = 0xffffff, alpha = 1, isHUD = false) {
|
||||
const rect = scene.add.rectangle(x, y, width, height, color, alpha);
|
||||
if (isHUD) {
|
||||
rect.setScrollFactor(0);
|
||||
rect.setOrigin(0, 0);
|
||||
rect.setDepth(10000);
|
||||
}
|
||||
return rect;
|
||||
},
|
||||
|
||||
strokeRectangle: function (scene, x, y, width, height, color = 0xffffff, thickness = 2, isHUD = false) {
|
||||
const g = scene.add.graphics();
|
||||
g.lineStyle(thickness, color, 1);
|
||||
|
||||
if (isHUD) {
|
||||
g.strokeRect(x, y, width, height);
|
||||
g.setScrollFactor(0);
|
||||
g.setDepth(10000);
|
||||
} else {
|
||||
g.strokeRect(x - width / 2, y - height / 2, width, height);
|
||||
}
|
||||
return g;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Glavni update loop za Engine
|
||||
* @param {Phaser.Scene} scene
|
||||
|
||||
@@ -1,10 +1,30 @@
|
||||
const CROP_DATA = {
|
||||
'wheat': {
|
||||
name: 'Wheat',
|
||||
seedItem: 'seeds_wheat',
|
||||
harvestItem: 'wheat',
|
||||
stages: 4,
|
||||
growthTime: 10, // Seconds per stage (Total 30s)
|
||||
regrow: false,
|
||||
color: 0xffdd00
|
||||
},
|
||||
'corn': {
|
||||
name: 'Corn',
|
||||
seedItem: 'seeds_corn',
|
||||
harvestItem: 'corn',
|
||||
stages: 4,
|
||||
growthTime: 15, // Slower (Total 45s)
|
||||
regrow: true, // Corn regrows!
|
||||
regrowStage: 2, // Goes back to stage 2
|
||||
color: 0xffaa00
|
||||
}
|
||||
};
|
||||
|
||||
class FarmingSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.growthTimer = 0;
|
||||
this.growthTickRate = 5000; // Check growth every 5 seconds (real time)
|
||||
// Or better: based on TimeSystem days?
|
||||
// For fast testing: rapid growth.
|
||||
this.growthTickRate = 1000;
|
||||
}
|
||||
|
||||
// Called by InteractionSystem
|
||||
@@ -14,40 +34,45 @@ class FarmingSystem {
|
||||
|
||||
if (!tile) return false;
|
||||
|
||||
// 1. HARVEST (Right click or just click ripe crop?)
|
||||
// Let's say if it has crop and it is ripe, harvest it regardless of tool.
|
||||
// 1. HARVEST
|
||||
if (tile.hasCrop) {
|
||||
const crop = terrain.cropsMap.get(`${gridX},${gridY}`);
|
||||
console.log('🌾 Check harvest:', crop);
|
||||
if (crop && crop.stage === 4) {
|
||||
if (crop && crop.stage === CROP_DATA[crop.type].stages) {
|
||||
this.harvest(gridX, gridY);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. TILLING (Requires Hoe)
|
||||
// 2. TILLING
|
||||
if (toolType === 'hoe') {
|
||||
const typeName = tile.type.name || tile.type;
|
||||
if (typeName.includes('grass') || typeName === 'dirt') {
|
||||
if (!tile.hasDecoration && !tile.hasCrop) {
|
||||
console.log('🚜 Tilling soil...');
|
||||
terrain.setTileType(gridX, gridY, 'farmland'); // This sets it to string 'farmland' usually? or object? Assuming method handles it.
|
||||
// Play sound
|
||||
terrain.setTileType(gridX, gridY, 'farmland');
|
||||
if (this.scene.soundManager) this.scene.soundManager.playDig();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. PLANTING (Requires Seeds)
|
||||
if (toolType === 'seeds') {
|
||||
// 3. PLANTING
|
||||
// Check if tool is a seed
|
||||
const isSeed = toolType.startsWith('seeds_') || toolType === 'seeds';
|
||||
|
||||
if (isSeed) {
|
||||
const typeName = tile.type.name || tile.type;
|
||||
if (typeName === 'farmland' && !tile.hasCrop && !tile.hasDecoration) {
|
||||
console.log('🌱 Planting seeds...');
|
||||
this.plant(gridX, gridY);
|
||||
// Determine crop type from seed name
|
||||
// "seeds_corn" -> "corn", "seeds" -> "wheat" (default)
|
||||
let cropType = 'wheat';
|
||||
if (toolType === 'seeds_corn') cropType = 'corn';
|
||||
if (toolType === 'seeds_wheat') cropType = 'wheat';
|
||||
|
||||
// Remove 1 seed from inventory
|
||||
this.plant(gridX, gridY, cropType);
|
||||
|
||||
// Consumption
|
||||
if (this.scene.inventorySystem) {
|
||||
this.scene.inventorySystem.removeItem('seeds', 1);
|
||||
this.scene.inventorySystem.removeItem(toolType, 1);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -56,57 +81,72 @@ class FarmingSystem {
|
||||
return false;
|
||||
}
|
||||
|
||||
plant(x, y) {
|
||||
plant(x, y, type = 'wheat') {
|
||||
const terrain = this.scene.terrainSystem;
|
||||
const data = CROP_DATA[type];
|
||||
|
||||
const cropData = {
|
||||
gridX: x,
|
||||
gridY: y,
|
||||
stage: 1, // Seeds
|
||||
type: 'wheat', // Default for now
|
||||
stage: 1,
|
||||
type: type,
|
||||
timer: 0,
|
||||
maxTime: 10 // Seconds per stage?
|
||||
maxTime: data.growthTime
|
||||
};
|
||||
terrain.addCrop(x, y, cropData);
|
||||
|
||||
// Plant Sound
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playPlant();
|
||||
}
|
||||
|
||||
// Quest Tracking
|
||||
if (this.scene.questSystem) this.scene.questSystem.trackAction('plant');
|
||||
console.log(`🌱 Planted ${type} at ${x},${y}`);
|
||||
}
|
||||
|
||||
harvest(x, y) {
|
||||
const terrain = this.scene.terrainSystem;
|
||||
console.log('🌾 Harvesting!');
|
||||
const crop = terrain.cropsMap.get(`${x},${y}`);
|
||||
if (!crop) return;
|
||||
|
||||
// Harvest Sound
|
||||
const data = CROP_DATA[crop.type];
|
||||
|
||||
// Sound
|
||||
if (this.scene.soundManager) {
|
||||
this.scene.soundManager.playHarvest();
|
||||
}
|
||||
|
||||
// Spawn loot
|
||||
// Loot
|
||||
if (this.scene.interactionSystem) {
|
||||
this.scene.interactionSystem.spawnLoot(x, y, 'wheat');
|
||||
this.scene.interactionSystem.spawnLoot(x, y, 'seeds'); // Return seeds
|
||||
// 50% chance for extra seeds
|
||||
if (Math.random() > 0.5) this.scene.interactionSystem.spawnLoot(x, y, 'seeds');
|
||||
this.scene.interactionSystem.spawnLoot(x, y, data.harvestItem, 1);
|
||||
|
||||
// Chance for seeds
|
||||
if (Math.random() > 0.4) {
|
||||
this.scene.interactionSystem.spawnLoot(x, y, data.seedItem, 1);
|
||||
}
|
||||
|
||||
// Extra harvest chance
|
||||
if (Math.random() > 0.5) {
|
||||
this.scene.interactionSystem.spawnLoot(x, y, data.harvestItem, 1);
|
||||
}
|
||||
|
||||
// XP Gain
|
||||
if (this.scene.statsSystem) {
|
||||
this.scene.statsSystem.addXP(data.harvestItem === 'corn' ? 15 : 10);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove crop
|
||||
terrain.removeCrop(x, y);
|
||||
|
||||
// Revert to dirt? Or keep farmland? Usually keeps farmland.
|
||||
// Regrow or Destroy
|
||||
if (data.regrow) {
|
||||
crop.stage = data.regrowStage;
|
||||
crop.timer = 0;
|
||||
terrain.updateCropVisual(x, y, crop.stage);
|
||||
console.log(`🔄 ${crop.type} regrowing...`);
|
||||
} else {
|
||||
terrain.removeCrop(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
update(delta) {
|
||||
// Growth Logic
|
||||
// Iterate all crops? Expensive?
|
||||
// Better: Random tick like Minecraft or list iteration.
|
||||
// Since we have cropsMap, iteration is easy.
|
||||
|
||||
// Only run every 1 second (1000ms) to save PERF
|
||||
this.growthTimer += delta;
|
||||
if (this.growthTimer < 1000) return;
|
||||
const secondsPassed = this.growthTimer / 1000;
|
||||
@@ -116,20 +156,15 @@ class FarmingSystem {
|
||||
if (!terrain) return;
|
||||
|
||||
for (const [key, crop] of terrain.cropsMap) {
|
||||
if (crop.stage < 4) {
|
||||
const data = CROP_DATA[crop.type];
|
||||
if (!data) continue;
|
||||
|
||||
if (crop.stage < data.stages) {
|
||||
crop.timer += secondsPassed;
|
||||
|
||||
// Growth thresholds (fast for testing)
|
||||
// Stage 1 -> 2: 5s
|
||||
// Stage 2 -> 3: 10s
|
||||
// Stage 3 -> 4: 15s
|
||||
const needed = 5;
|
||||
|
||||
if (crop.timer >= needed) {
|
||||
if (crop.timer >= data.growthTime) {
|
||||
crop.stage++;
|
||||
crop.timer = 0;
|
||||
terrain.updateCropVisual(crop.gridX, crop.gridY, crop.stage);
|
||||
// Particle effect?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,6 +209,11 @@ class InteractionSystem {
|
||||
}
|
||||
|
||||
if (decor.hp <= 0) {
|
||||
// XP REWARD (Requested by Logic)
|
||||
if (this.scene.statsSystem) {
|
||||
this.scene.statsSystem.addXP(5);
|
||||
}
|
||||
|
||||
const prevType = decor.type;
|
||||
|
||||
// Logic: If Tree (and not sapling), turn into Sapling immediately (Regrowth)
|
||||
|
||||
@@ -26,6 +26,8 @@ class SoundManager {
|
||||
this.beepHarvest();
|
||||
} else if (key === 'build') {
|
||||
this.beepBuild();
|
||||
} else if (key === 'dig') {
|
||||
this.beepDig();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -297,10 +299,28 @@ class SoundManager {
|
||||
playHarvest() { this.playSFX('harvest'); }
|
||||
playBuild() { this.playSFX('build'); }
|
||||
playPickup() { this.playSFX('pickup'); }
|
||||
playDig() { this.playSFX('dig'); } // Dodano
|
||||
playAttack() { this.beepAttack(); }
|
||||
playHit() { this.beepHit(); }
|
||||
playFootstep() { this.beepFootstep(); }
|
||||
playDeath() { this.beepDeath(); }
|
||||
playRainSound() { this.startRainNoise(); }
|
||||
stopRainSound() { this.stopRainNoise(); }
|
||||
|
||||
beepDig() {
|
||||
if (!this.scene.sound.context) return;
|
||||
const ctx = this.scene.sound.context;
|
||||
const osc = ctx.createOscillator();
|
||||
const gain = ctx.createGain();
|
||||
osc.connect(gain);
|
||||
gain.connect(ctx.destination);
|
||||
// Low "thud" for dirt interaction
|
||||
osc.frequency.setValueAtTime(80, ctx.currentTime);
|
||||
osc.frequency.exponentialRampToValueAtTime(10, ctx.currentTime + 0.15);
|
||||
osc.type = 'triangle';
|
||||
gain.gain.setValueAtTime(0.2, ctx.currentTime);
|
||||
gain.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.15);
|
||||
osc.start();
|
||||
osc.stop(ctx.currentTime + 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,18 @@
|
||||
// ========================================================
|
||||
// KONSTANTE IN IGRALČEVI PODATKI
|
||||
// ========================================================
|
||||
const XP_REQUIRED_BASE = 100; // Osnovni XP, potrebni za LVL 2
|
||||
const XP_GROWTH_FACTOR = 1.5; // Za vsak LVL potrebujete 1.5x več XP
|
||||
|
||||
class StatsSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
|
||||
// Leveling System
|
||||
this.currentLevel = 1;
|
||||
this.currentXP = 0;
|
||||
this.xpToNextLevel = XP_REQUIRED_BASE;
|
||||
|
||||
// Stats
|
||||
this.health = 100;
|
||||
this.maxHealth = 100;
|
||||
@@ -130,6 +141,18 @@ class StatsSystem {
|
||||
if (uiScene.hungerBar) uiScene.setBarValue(uiScene.hungerBar, this.hunger);
|
||||
if (uiScene.thirstBar) uiScene.setBarValue(uiScene.thirstBar, this.thirst);
|
||||
}
|
||||
this.updateLevelUI();
|
||||
}
|
||||
|
||||
updateLevelUI() {
|
||||
const xpPercent = (this.currentXP / this.xpToNextLevel) * 100;
|
||||
const levelText = `LV: ${this.currentLevel}`;
|
||||
|
||||
// Uporaba Antigravity Engine UI klicev, kot zahtevano
|
||||
if (window.Antigravity && window.Antigravity.UI) {
|
||||
window.Antigravity.UI.setText(this.scene, 'LevelDisplay', levelText);
|
||||
window.Antigravity.UI.setBarValue(this.scene, 'XPBar', xpPercent);
|
||||
}
|
||||
}
|
||||
|
||||
// Friendship System
|
||||
@@ -149,4 +172,49 @@ class StatsSystem {
|
||||
this.friendship[npcType] = amount;
|
||||
}
|
||||
}
|
||||
|
||||
// ========================================================
|
||||
// LEVELING SYSTEM
|
||||
// ========================================================
|
||||
|
||||
addXP(amount) {
|
||||
this.currentXP += amount;
|
||||
|
||||
// 1. Preverimo, ali je igralec pripravljen za Level Up
|
||||
while (this.currentXP >= this.xpToNextLevel) {
|
||||
this.levelUp();
|
||||
}
|
||||
|
||||
this.updateUI();
|
||||
}
|
||||
|
||||
levelUp() {
|
||||
// Povečamo Level
|
||||
this.currentLevel++;
|
||||
|
||||
// Izračunamo nov XP prag
|
||||
this.xpToNextLevel = Math.floor(this.xpToNextLevel * XP_GROWTH_FACTOR);
|
||||
|
||||
// Preostanek XP prenesemo v nov Level
|
||||
this.currentXP = this.currentXP - (this.xpToNextLevel / XP_GROWTH_FACTOR);
|
||||
|
||||
// Bonus Stats
|
||||
this.maxHealth += 10;
|
||||
this.health = this.maxHealth;
|
||||
this.maxHunger += 5;
|
||||
this.maxThirst += 5;
|
||||
this.hunger = this.maxHunger;
|
||||
this.thirst = this.maxThirst;
|
||||
|
||||
// Vizualni učinek / Prikaz sporočila
|
||||
console.log(`🎉 LEVEL UP! Dosežen level ${this.currentLevel}!`);
|
||||
|
||||
if (window.Antigravity && window.Antigravity.UI) {
|
||||
window.Antigravity.UI.showMessage(
|
||||
this.scene,
|
||||
`LEVEL UP! Dosežen level ${this.currentLevel}!`,
|
||||
'#FFD700'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,10 +279,10 @@ class TerrainSystem {
|
||||
};
|
||||
|
||||
// Place Trees dynamically during generation
|
||||
this.placeTree(x, y, terrainType.name);
|
||||
// this.placeTree(x, y, terrainType.name);
|
||||
|
||||
// Place Rocks dynamically
|
||||
this.placeRock(x, y, terrainType.name);
|
||||
// this.placeRock(x, y, terrainType.name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,7 +699,18 @@ class TerrainSystem {
|
||||
const sprite = this.cropPool.get();
|
||||
const screenPos = this.iso.toScreen(x, y);
|
||||
sprite.setPosition(Math.round(screenPos.x + this.offsetX), Math.round(screenPos.y + this.offsetY - voxelOffset));
|
||||
sprite.setTexture(`crop_stage_${crop.stage}`);
|
||||
|
||||
const cropType = crop.type || 'wheat';
|
||||
// Če je wheat, uporabimo 'crop_stage_' za nazaj združljivost s TextureGeneratorjem?
|
||||
// TextureGenerator dela 'crop_stage_X'.
|
||||
// Če dodam 'wheat_stage_X', moram posodobiti TextureGenerator.
|
||||
// Za zdaj:
|
||||
let textureKey = `crop_stage_${crop.stage}`;
|
||||
if (cropType === 'corn') textureKey = `corn_stage_${crop.stage}`;
|
||||
if (cropType === 'wheat' && this.scene.textures.exists('wheat_stage_1')) textureKey = `wheat_stage_${crop.stage}`;
|
||||
|
||||
sprite.setTexture(textureKey);
|
||||
|
||||
sprite.setOrigin(0.5, 1);
|
||||
// Layer Objects (da igralec hodi okoli njih)
|
||||
sprite.setDepth(this.iso.getDepth(x, y, this.iso.LAYER_OBJECTS));
|
||||
|
||||
Reference in New Issue
Block a user