phase 12 koncxana
This commit is contained in:
181
src/systems/OceanSystem.js
Normal file
181
src/systems/OceanSystem.js
Normal file
@@ -0,0 +1,181 @@
|
||||
class OceanSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
|
||||
this.isDiving = false;
|
||||
this.oxygen = 100;
|
||||
this.maxOxygen = 100;
|
||||
this.oxygenDecayRate = 10; // Oxygen lost per second
|
||||
this.oxygenRegenRate = 20; // Oxygen gained per second
|
||||
|
||||
this.damageTimer = 0;
|
||||
|
||||
// Visual Effects
|
||||
this.overlay = null;
|
||||
this.bubbleParticles = null;
|
||||
|
||||
// Boat
|
||||
this.currentBoat = null;
|
||||
this.isBoating = false;
|
||||
|
||||
// Init UI Event Listener
|
||||
this.scene.events.on('update', (time, delta) => {
|
||||
this.update(time, delta);
|
||||
this.updateBoatVisuals();
|
||||
});
|
||||
}
|
||||
|
||||
update(time, delta) {
|
||||
if (!this.scene.player) return;
|
||||
|
||||
const playerPos = this.scene.player.getPosition();
|
||||
const tile = this.scene.terrainSystem.getTile(playerPos.x, playerPos.y);
|
||||
|
||||
if (tile && tile.type && tile.type.name === 'water') {
|
||||
|
||||
// Check if boating
|
||||
if (this.isBoating) {
|
||||
// No drowning logic if in boat
|
||||
this.oxygen = this.maxOxygen; // Regaining oxygen/safe
|
||||
} else {
|
||||
this.enterWater();
|
||||
this.handleDiving(delta);
|
||||
}
|
||||
} else {
|
||||
// LAND LOGIC
|
||||
// If boating on land -> Beaching/Stop boating
|
||||
if (this.isBoating) {
|
||||
this.exitBoat();
|
||||
}
|
||||
this.exitWater();
|
||||
this.handleRegen(delta);
|
||||
}
|
||||
|
||||
// Update UI
|
||||
if (this.isDiving || this.oxygen < this.maxOxygen) {
|
||||
this.scene.events.emit('update-oxygen', { current: this.oxygen, max: this.maxOxygen });
|
||||
} else {
|
||||
this.scene.events.emit('hide-oxygen');
|
||||
}
|
||||
}
|
||||
|
||||
enterWater() {
|
||||
if (this.isDiving) return;
|
||||
this.isDiving = true;
|
||||
console.log('🌊 Entered Water');
|
||||
|
||||
// Visuals
|
||||
if (!this.overlay) {
|
||||
this.overlay = this.scene.add.rectangle(0, 0, this.scene.scale.width, this.scene.scale.height, 0x0000FF, 0.3);
|
||||
this.overlay.setScrollFactor(0);
|
||||
this.overlay.setDepth(9000); // Above most things, below UI
|
||||
}
|
||||
this.overlay.setVisible(true);
|
||||
|
||||
// Slow player?
|
||||
// Slow player?
|
||||
this.scene.player.moveSpeed = 60; // Slower in water
|
||||
}
|
||||
|
||||
useBoat(boatItem) {
|
||||
if (this.isBoating) {
|
||||
this.exitBoat();
|
||||
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.
|
||||
|
||||
const playerPos = this.scene.player.getPosition();
|
||||
const tile = this.scene.terrainSystem.getTile(playerPos.x, playerPos.y);
|
||||
|
||||
if (tile && tile.type && tile.type.name === 'water') {
|
||||
this.enterBoat(playerPos.x, playerPos.y);
|
||||
} else {
|
||||
this.scene.events.emit('show-floating-text', {
|
||||
x: this.scene.player.sprite.x, y: this.scene.player.sprite.y - 50, text: 'Must be in water!', color: '#FF0000'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
enterBoat() {
|
||||
this.isBoating = true;
|
||||
this.isDiving = false;
|
||||
if (this.overlay) this.overlay.setVisible(false); // No blue overlay on boat
|
||||
|
||||
// Visual change
|
||||
this.scene.player.moveSpeed = 200; // Fast speed!
|
||||
|
||||
// Create boat visual under player?
|
||||
// Simplified: Change player texture or add container
|
||||
if (!this.currentBoat) {
|
||||
this.currentBoat = this.scene.add.sprite(0, 0, 'boat');
|
||||
this.currentBoat.setDepth(this.scene.player.sprite.depth - 1);
|
||||
}
|
||||
this.currentBoat.setVisible(true);
|
||||
|
||||
this.scene.events.emit('show-floating-text', {
|
||||
x: this.scene.player.sprite.x, y: this.scene.player.sprite.y - 50, text: 'Deployed Boat!', color: '#00FFFF'
|
||||
});
|
||||
}
|
||||
|
||||
exitBoat() {
|
||||
this.isBoating = false;
|
||||
if (this.currentBoat) this.currentBoat.setVisible(false);
|
||||
|
||||
// Return to normal or water speed?
|
||||
// Logic in update loop will handle re-entering water state if still on water
|
||||
this.scene.player.moveSpeed = 150;
|
||||
}
|
||||
|
||||
exitWater() {
|
||||
if (!this.isDiving) return;
|
||||
this.isDiving = false;
|
||||
console.log('🏖️ Exited Water');
|
||||
|
||||
if (this.overlay) this.overlay.setVisible(false);
|
||||
|
||||
// Restore speed
|
||||
this.scene.player.moveSpeed = 150; // Normal speed
|
||||
}
|
||||
|
||||
handleDiving(delta) {
|
||||
this.oxygen -= (this.oxygenDecayRate * delta) / 1000;
|
||||
|
||||
if (this.oxygen <= 0) {
|
||||
this.oxygen = 0;
|
||||
this.damageTimer += delta;
|
||||
if (this.damageTimer > 1000) {
|
||||
this.damageTimer = 0;
|
||||
this.scene.player.takeDamage(5);
|
||||
this.scene.events.emit('show-floating-text', {
|
||||
x: this.scene.player.sprite.x,
|
||||
y: this.scene.player.sprite.y - 50,
|
||||
text: 'Drowning!',
|
||||
color: '#FF0000'
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
handleRegen(delta) {
|
||||
if (this.oxygen < this.maxOxygen) {
|
||||
this.oxygen += (this.oxygenRegenRate * delta) / 1000;
|
||||
if (this.oxygen > this.maxOxygen) this.oxygen = this.maxOxygen;
|
||||
}
|
||||
updateBoatVisuals() {
|
||||
if (this.isBoating && this.currentBoat && this.scene.player) {
|
||||
this.currentBoat.x = this.scene.player.sprite.x;
|
||||
this.currentBoat.y = this.scene.player.sprite.y + 10; // Slightly below
|
||||
this.currentBoat.setDepth(this.scene.player.sprite.depth - 1);
|
||||
|
||||
// Flip based on movement?
|
||||
// Access input vector or previous pos?
|
||||
// Simplified:
|
||||
if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('A'), 100)) this.currentBoat.setFlipX(false);
|
||||
if (this.scene.input.keyboard.checkDown(this.scene.input.keyboard.addKey('D'), 100)) this.currentBoat.setFlipX(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user