Files
novafarma/old_logic/src_backup_1768938138/scenes/TestVisualAudioScene.js
2026-01-21 01:08:21 +01:00

322 lines
9.4 KiB
JavaScript

/**
* TestVisualAudioScene.js
* Demo scene: Kai speaks, dreadlocks wave, leaves fall
*/
class TestVisualAudioScene extends Phaser.Scene {
constructor() {
super({ key: 'TestVisualAudioScene' });
}
preload() {
console.log('🎬 Loading Test Visual & Audio Scene...');
// Load Kai voice (Legacy path disabled)
// this.load.audio('kai_test_voice', 'assets/audio/voices/kai/kai_test_01.mp3');
// Load music (if exists)
if (this.cache.audio.exists('music/forest_ambient')) {
console.log('✅ Music ready');
}
// Load Kai sprite (placeholder using new structure)
this.load.image('kai_idle', 'assets/slike/liki/kai_main.png');
}
create() {
console.log('🎨 Creating Test Scene...');
const width = this.cameras.main.width;
const height = this.cameras.main.height;
// Background
this.cameras.main.setBackgroundColor('#7cfc00'); // Grassland green
// Title
const title = this.add.text(width / 2, 50, '🎨 VISUAL & AUDIO TEST', {
fontSize: '32px',
fontFamily: 'Arial',
color: '#ffffff',
stroke: '#000000',
strokeThickness: 4
});
title.setOrigin(0.5);
title.setDepth(1000);
// Instructions
const instructions = this.add.text(width / 2, 100,
'Use WASD to move Kai\nStep on YELLOW TILE to trigger voice\nWatch dreadlocks wave in wind\nWatch leaves fall', {
fontSize: '16px',
fontFamily: 'Arial',
color: '#ffffff',
stroke: '#000000',
strokeThickness: 3,
align: 'center'
});
instructions.setOrigin(0.5);
instructions.setDepth(1000);
// Create ground tiles
this.createGround();
// Create Kai (simple placeholder)
this.createKai();
// Initialize systems
this.initSystems();
// Create falling leaves
this.createFallingLeaves();
// Create wind effect on Kai's dreadlocks
this.createWindEffect();
// Camera follow
this.cameras.main.startFollow(this.kai, true, 0.1, 0.1);
this.cameras.main.setZoom(1.2);
// Controls
this.cursors = this.input.keyboard.createCursorKeys();
this.wasd = {
up: this.input.keyboard.addKey('W'),
down: this.input.keyboard.addKey('S'),
left: this.input.keyboard.addKey('A'),
right: this.input.keyboard.addKey('D')
};
console.log('✅ Test Scene Ready!');
}
createGround() {
// Simple grass tiles
const tileSize = 48;
const gridWidth = 20;
const gridHeight = 15;
for (let y = 0; y < gridHeight; y++) {
for (let x = 0; x < gridWidth; x++) {
const worldX = x * tileSize;
const worldY = y * tileSize;
// Grass tile (light/dark alternating)
const isLight = (x + y) % 2 === 0;
const color = isLight ? 0x7cfc00 : 0x6ab04c;
const tile = this.add.rectangle(worldX, worldY, tileSize, tileSize, color);
tile.setOrigin(0);
tile.setAlpha(0.5);
}
}
// Audio trigger tile (YELLOW)
const triggerX = 10;
const triggerY = 7;
const triggerTile = this.add.rectangle(triggerX * tileSize, triggerY * tileSize, tileSize, tileSize, 0xffff00);
triggerTile.setOrigin(0);
triggerTile.setAlpha(0.7);
// Label
const label = this.add.text(triggerX * tileSize + 24, triggerY * tileSize + 24, '🎙️', {
fontSize: '28px'
});
label.setOrigin(0.5);
}
createKai() {
// Simplified Kai representation
const kaiX = 240;
const kaiY = 240;
// Body
this.kai = this.add.circle(kaiX, kaiY, 20, 0xffc0cb); // Pink body
this.kai.setDepth(10);
// Add physics
this.physics.world.enable(this.kai);
this.kai.body.setCollideWorldBounds(true);
this.kai.speed = 150;
// Dreadlocks (will animate)
this.dreadlocks = [];
const dreadCount = 8;
const radius = 25;
for (let i = 0; i < dreadCount; i++) {
const angle = (i / dreadCount) * Math.PI * 2;
const x = kaiX + Math.cos(angle) * radius;
const y = kaiY + Math.sin(angle) * radius;
const dread = this.add.rectangle(x, y, 4, 30, 0xff1493); // Hot pink
dread.setOrigin(0.5, 0); // Pivot at top
dread.angle = (angle * 180 / Math.PI) + 90;
dread.setDepth(9);
dread.baseAngle = dread.angle;
dread.swayOffset = i * 0.5; // Stagger animation
this.dreadlocks.push(dread);
}
// Name label
this.kaiLabel = this.add.text(kaiX, kaiY - 40, 'KAI', {
fontSize: '14px',
fontFamily: 'Arial',
color: '#ffffff',
stroke: '#000000',
strokeThickness: 3
});
this.kaiLabel.setOrigin(0.5);
this.kaiLabel.setDepth(11);
}
initSystems() {
// Audio Trigger System
this.audioTriggers = new AudioTriggerSystem(this);
// Add trigger at yellow tile (10, 7)
this.audioTriggers.addTrigger(10, 7, 'kai_test_voice', {
radius: 0, // Exact tile only
volume: 1.0,
oneTime: true,
visualDebug: true,
callback: () => {
console.log('✅ Kai spoke her line!');
this.showSpeechBubble();
}
});
// Biome Music System (if music exists)
// this.biomeMusicSystem = new BiomeMusicSystem(this);
// this.biomeMusicSystem.playBiomeMusic('grassland');
}
showSpeechBubble() {
// Show speech bubble above Kai
const bubble = this.add.text(this.kai.x, this.kai.y - 60,
'"My name is Kai..."', {
fontSize: '12px',
fontFamily: 'Arial',
color: '#000000',
backgroundColor: '#ffffff',
padding: { x: 8, y: 4 }
});
bubble.setOrigin(0.5);
bubble.setDepth(100);
// Fade out after 3 seconds
this.tweens.add({
targets: bubble,
alpha: 0,
duration: 1000,
delay: 2000,
onComplete: () => bubble.destroy()
});
}
createFallingLeaves() {
// Particle emitter for falling leaves
this.leaves = [];
// Create 20 leaves
for (let i = 0; i < 20; i++) {
this.time.delayedCall(i * 300, () => {
this.spawnLeaf();
});
}
}
spawnLeaf() {
const x = Phaser.Math.Between(0, this.cameras.main.width);
const y = -20;
const leaf = this.add.ellipse(x, y, 8, 12, 0x90ee90);
leaf.setDepth(5);
leaf.setAlpha(0.7);
// Fall animation
this.tweens.add({
targets: leaf,
y: this.cameras.main.height + 50,
duration: Phaser.Math.Between(4000, 7000),
ease: 'Sine.InOut',
onComplete: () => {
leaf.destroy();
// Spawn new leaf
this.spawnLeaf();
}
});
// Sway side-to-side
this.tweens.add({
targets: leaf,
x: x + Phaser.Math.Between(-50, 50),
duration: 2000,
yoyo: true,
repeat: -1,
ease: 'Sine.InOut'
});
// Rotate
this.tweens.add({
targets: leaf,
angle: 360,
duration: 3000,
repeat: -1,
ease: 'Linear'
});
}
createWindEffect() {
// Dreadlocks sway in wind
this.time.addEvent({
delay: 50,
loop: true,
callback: () => {
const time = this.time.now / 1000;
this.dreadlocks.forEach((dread, i) => {
const sway = Math.sin(time * 2 + dread.swayOffset) * 15;
dread.angle = dread.baseAngle + sway;
});
}
});
}
update() {
if (!this.kai) return;
// Movement
this.kai.body.setVelocity(0);
if (this.cursors.left.isDown || this.wasd.left.isDown) {
this.kai.body.setVelocityX(-this.kai.speed);
} else if (this.cursors.right.isDown || this.wasd.right.isDown) {
this.kai.body.setVelocityX(this.kai.speed);
}
if (this.cursors.up.isDown || this.wasd.up.isDown) {
this.kai.body.setVelocityY(-this.kai.speed);
} else if (this.cursors.down.isDown || this.wasd.down.isDown) {
this.kai.body.setVelocityY(this.kai.speed);
}
// Update dreadlocks position
this.dreadlocks.forEach((dread, i) => {
const angle = (i / this.dreadlocks.length) * Math.PI * 2;
const radius = 25;
dread.x = this.kai.x + Math.cos(angle) * radius;
dread.y = this.kai.y + Math.sin(angle) * radius;
});
// Update label position
this.kaiLabel.setPosition(this.kai.x, this.kai.y - 40);
// Update audio triggers
this.audioTriggers.update(this.kai.x, this.kai.y);
// ESC to return to menu
if (this.input.keyboard.addKey('ESC').isDown) {
this.scene.start('GameScene');
}
}
}