Files
novafarma/src/systems/ParallaxSystem.js
2025-12-07 04:19:57 +01:00

200 lines
5.7 KiB
JavaScript

class ParallaxSystem {
constructor(scene) {
this.scene = scene;
this.layers = [];
// Layer depths (Phaser depth sorting)
this.DEPTH = {
SKY: -1000,
DISTANT_HILLS: -500,
FAR_TREES: -100,
TERRAIN: 0,
GAME_OBJECTS: 1000,
FOREGROUND_GRASS: 5000,
FOREGROUND_LEAVES: 5500
};
this.init();
}
init() {
console.log('🌄 ParallaxSystem: Initialized');
// Layer 1: Sky/Hills (Distant background)
// Layer 1: Sky/Hills (Disabled by request)
// this.createSkyLayer();
// this.createDistantHills();
// Layer 4: Foreground overlay (High grass patches)
this.createForegroundGrass();
}
createSkyLayer() {
// Gradient sky rectangle
const width = 3000;
const height = 2000;
const skyBg = this.scene.add.rectangle(0, 0, width, height, 0x87CEEB); // Sky blue
skyBg.setOrigin(0, 0);
skyBg.setScrollFactor(0); // Fixed (no parallax)
skyBg.setDepth(this.DEPTH.SKY);
this.layers.push({
name: 'sky',
objects: [skyBg],
scrollFactor: 0
});
}
createDistantHills() {
// Create simple hill silhouettes in background
const hillCount = 5;
const hills = [];
for (let i = 0; i < hillCount; i++) {
const x = i * 800 - 1000;
const y = 600;
const width = Phaser.Math.Between(400, 800);
const height = Phaser.Math.Between(150, 300);
// Create hill as ellipse
const hill = this.scene.add.ellipse(x, y, width, height, 0x4a5f3a); // Dark green
hill.setAlpha(0.4);
hill.setDepth(this.DEPTH.DISTANT_HILLS);
hill.setScrollFactor(0.2, 0.2); // Slow parallax
hills.push(hill);
}
this.layers.push({
name: 'distant_hills',
objects: hills,
scrollFactor: 0.2
});
}
createForegroundGrass() {
// Create tall grass patches that appear in front of player
const grassPatches = [];
const patchCount = 30;
for (let i = 0; i < patchCount; i++) {
const x = Phaser.Math.Between(-500, 2500);
const y = Phaser.Math.Between(-500, 2500);
const grass = this.createGrassPatch(x, y);
grass.setDepth(this.DEPTH.FOREGROUND_GRASS);
grass.setScrollFactor(1.05, 1.05); // Slight forward parallax
grass.setAlpha(0.6);
grassPatches.push(grass);
}
this.layers.push({
name: 'foreground_grass',
objects: grassPatches,
scrollFactor: 1.05
});
}
createGrassPatch(x, y) {
// Create procedural grass patch
const graphics = this.scene.add.graphics();
// Draw several grass blades
for (let i = 0; i < 6; i++) {
const offsetX = Phaser.Math.Between(-10, 10);
const offsetY = Phaser.Math.Between(-5, 5);
const height = Phaser.Math.Between(20, 40);
graphics.fillStyle(0x3a5f2a, 0.8); // Dark grass green
// Draw grass blade (thin triangle)
graphics.beginPath();
graphics.moveTo(x + offsetX, y + offsetY);
graphics.lineTo(x + offsetX - 2, y + offsetY + height);
graphics.lineTo(x + offsetX + 2, y + offsetY + height);
graphics.closePath();
graphics.fillPath();
}
return graphics;
}
update(playerX, playerY) {
// Update foreground grass visibility based on player position
// Hide/show grass patches that are too close to player for better gameplay
const foregroundLayer = this.layers.find(l => l.name === 'foreground_grass');
if (!foregroundLayer) return;
for (const grass of foregroundLayer.objects) {
const distance = Phaser.Math.Distance.Between(
grass.x, grass.y,
playerX, playerY
);
// Fade out grass when player is very close
if (distance < 50) {
grass.setAlpha(0.2);
} else if (distance < 100) {
grass.setAlpha(0.4);
} else {
grass.setAlpha(0.6);
}
}
}
addFarTree(x, y) {
// Add a background tree (Layer 2)
if (!this.scene.textures.exists('tree')) return;
const tree = this.scene.add.sprite(x, y, 'tree');
tree.setDepth(this.DEPTH.FAR_TREES);
tree.setScrollFactor(0.7, 0.7); // Medium parallax
tree.setAlpha(0.7);
tree.setScale(1.5);
return tree;
}
addForegroundLeaves(x, y) {
// Add falling leaves or branch overlay (Layer 4)
const graphics = this.scene.add.graphics();
// Draw some leaves
for (let i = 0; i < 3; i++) {
const leafX = x + Phaser.Math.Between(-20, 20);
const leafY = y + Phaser.Math.Between(-10, 10);
graphics.fillStyle(0x2d4a1f, 0.5); // Dark green leaf
graphics.fillEllipse(leafX, leafY, 8, 12);
}
graphics.setDepth(this.DEPTH.FOREGROUND_LEAVES);
graphics.setScrollFactor(1.1, 1.1); // Fastest parallax (closest)
return graphics;
}
clearLayer(layerName) {
const layer = this.layers.find(l => l.name === layerName);
if (!layer) return;
for (const obj of layer.objects) {
obj.destroy();
}
layer.objects = [];
}
destroy() {
for (const layer of this.layers) {
for (const obj of layer.objects) {
obj.destroy();
}
}
this.layers = [];
}
}