kockasta mapa
This commit is contained in:
118
src/systems/LootSystem.js
Normal file
118
src/systems/LootSystem.js
Normal file
@@ -0,0 +1,118 @@
|
||||
class LootSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.drops = []; // Active loot drops
|
||||
this.iso = scene.terrainSystem ? scene.terrainSystem.iso : null; // Reference to IsoUtils
|
||||
|
||||
// Settings
|
||||
this.pickupRadius = 1.0; // Grid based
|
||||
this.magnetRadius = 3.0; // Optional: fly towards player
|
||||
}
|
||||
|
||||
spawnLoot(gridX, gridY, type, count = 1) {
|
||||
if (!this.iso && this.scene.terrainSystem) this.iso = this.scene.terrainSystem.iso;
|
||||
if (!this.iso) return; // Safety check
|
||||
|
||||
console.log(`🎁 Spawning ${count}x ${type} at ${gridX},${gridY}`);
|
||||
|
||||
const screenPos = this.iso.toScreen(gridX, gridY);
|
||||
const x = screenPos.x + (this.scene.terrainOffsetX || 0);
|
||||
const y = screenPos.y + (this.scene.terrainOffsetY || 0);
|
||||
|
||||
// Visual Symbol Mapping
|
||||
let symbol = '?';
|
||||
const symbols = {
|
||||
'wood': '🪵', 'stone': '🪨', 'seeds': '🌱', 'wheat': '🌾',
|
||||
'axe': '🪓', 'pickaxe': '⛏️', 'sword': '⚔️', 'hoe': '🚜',
|
||||
'item_bone': '🦴', 'flower': '🌸'
|
||||
};
|
||||
if (symbols[type]) symbol = symbols[type];
|
||||
|
||||
// Create Sprite/Text
|
||||
// Using Text for now as it supports emojis easily, but could be Sprite
|
||||
const drop = this.scene.add.text(x, y - 20, symbol, { fontSize: '20px' });
|
||||
drop.setOrigin(0.5);
|
||||
drop.setDepth(this.iso.getDepth(gridX, gridY) + 500);
|
||||
|
||||
// Animation (Bobbing)
|
||||
this.scene.tweens.add({
|
||||
targets: drop,
|
||||
y: y - 40,
|
||||
duration: 600,
|
||||
yoyo: true,
|
||||
ease: 'Sine.easeInOut',
|
||||
repeat: -1
|
||||
});
|
||||
|
||||
// Add to list
|
||||
this.drops.push({
|
||||
gridX, gridY,
|
||||
x, y,
|
||||
sprite: drop,
|
||||
type: type,
|
||||
count: count,
|
||||
spawnTime: Date.now()
|
||||
});
|
||||
}
|
||||
|
||||
update() {
|
||||
if (!this.scene.player) return;
|
||||
|
||||
const playerPos = this.scene.player.getPosition();
|
||||
|
||||
// Loop backwards to allow removal
|
||||
for (let i = this.drops.length - 1; i >= 0; i--) {
|
||||
const drop = this.drops[i];
|
||||
|
||||
// Distance Check
|
||||
const dist = Math.abs(drop.gridX - playerPos.x) + Math.abs(drop.gridY - playerPos.y); // Manhattan-ish
|
||||
|
||||
// Pickup Logic
|
||||
if (dist < 0.8) {
|
||||
this.collectLoot(drop, i);
|
||||
}
|
||||
// Magnet Logic (Visual fly to player) - Optional
|
||||
else if (dist < 3.0) {
|
||||
// Move visual slightly towards player?
|
||||
// Implementing full physics/velocity might be overkill for now.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
collectLoot(drop, index) {
|
||||
if (this.scene.inventorySystem) {
|
||||
const leftover = this.scene.inventorySystem.addItem(drop.type, drop.count);
|
||||
|
||||
if (leftover === 0) {
|
||||
// Success
|
||||
this.scene.sound.play('pickup_sound')
|
||||
// (Assuming sound exists, if not it will just warn silently or fail)
|
||||
// Actually, let's skip sound call if not sure to avoid error spam
|
||||
|
||||
// Float text effect
|
||||
this.showFloatingText(`+${drop.count} ${drop.type}`, drop.x, drop.y);
|
||||
|
||||
// Remove
|
||||
drop.sprite.destroy();
|
||||
this.drops.splice(index, 1);
|
||||
} else {
|
||||
// Config full? Update count?
|
||||
drop.count = leftover;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showFloatingText(text, x, y) {
|
||||
const txt = this.scene.add.text(x, y - 50, text, {
|
||||
fontSize: '14px', fill: '#ffff00', stroke: '#000', strokeThickness: 2
|
||||
}).setOrigin(0.5).setDepth(20000);
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: txt,
|
||||
y: y - 100,
|
||||
alpha: 0,
|
||||
duration: 800,
|
||||
onComplete: () => txt.destroy()
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user