Add Enhanced Demo Scene with Memory System

NEW FEATURES:
🎮 DemoSceneEnhanced.js - Full featured demo
💎 Locket memory trigger with flashback
🌾 Style 30 wheat with 4 growth stages (10s each)
💬 Gronk dialogue system
 Quest system (plant 5 wheat)
🎉 Demo complete screen with stats

ASSETS INTEGRATED:
- Mamin silver locket (memory trigger)
- Tool sprites (hoe, bucket, watering can)
- Wheat stages 1-4 (Style 30 correct!)

To test: Change BootScene to start DemoSceneEnhanced
Game is running in Electron!
This commit is contained in:
2026-01-03 19:39:24 +01:00
parent de6eb67c71
commit a63c1b60b7
4 changed files with 884 additions and 1 deletions

View File

@@ -68,7 +68,7 @@ const config = {
debug: false
}
},
scene: [BootScene, PreloadScene, DemoScene, TiledTestScene, StoryScene, PrologueScene, GameScene, UIScene, TownSquareScene],
scene: [BootScene, PreloadScene, DemoScene, DemoSceneEnhanced, TiledTestScene, StoryScene, PrologueScene, GameScene, UIScene, TownSquareScene],
scale: {
mode: Phaser.Scale.FIT,
autoCenter: Phaser.Scale.CENTER_BOTH

View File

@@ -0,0 +1,711 @@
// 🎮 ENHANCED DEMO SCENE - Full featured farming demo!
// ✨ Features: Real sprites, locket memory, 4-stage wheat, Gronk dialogue
class DemoSceneEnhanced extends Phaser.Scene {
constructor() {
super({ key: 'DemoSceneEnhanced' });
this.player = null;
this.gronk = null;
this.locket = null;
this.wheat = new Map();
this.inventory = {
seeds: 0,
wheat: 0,
gold: 0,
hasLocket: false
};
this.tools = {
hoe: false,
wateringCan: false
};
this.currentTool = null;
this.quest = {
active: false,
target: 5,
planted: 0,
complete: false
};
this.memoria = {
triggered: false
};
}
preload() {
console.log('🎮 DemoSceneEnhanced: Loading assets...');
// Load demo assets (using find results from earlier)
// Items
this.load.image('locket', 'assets/demo 🔴/items 🔴/item_locket_silver_1767464385940.png');
this.load.image('hoe', 'assets/demo 🔴/items 🔴/tool_hoe_rusty_1767464400663.png');
this.load.image('bucket', 'assets/demo 🔴/items 🔴/tool_bucket_old_1767464414881.png');
this.load.image('wateringCan', 'assets/demo 🔴/items 🔴/tool_watering_can_1767464429022.png');
// Wheat stages (Style 30!)
this.load.image('wheat_stage1', 'assets/demo 🔴/items 🔴/wheat_s30_stage1_seed_1767464954800.png');
this.load.image('wheat_stage2', 'assets/demo 🔴/items 🔴/wheat_s30_stage2_sprout_1767464969122.png');
this.load.image('wheat_stage3', 'assets/demo 🔴/items 🔴/wheat_s30_stage3_growing_1767464984588.png');
this.load.image('wheat_stage4', 'assets/demo 🔴/items 🔴/wheat_s30_stage4_harvest_1767465000017.png');
console.log('✅ Assets loaded!');
}
create() {
console.log('🎮 DemoSceneEnhanced: Starting enhanced demo!');
// Setup world
this.cameras.main.setBackgroundColor('#7cfc00');
this.cameras.main.setBounds(0, 0, 2000, 2000);
this.physics.world.setBounds(0, 0, 2000, 2000);
this.createWorld();
this.createPlayer();
this.createGronk();
this.createLocket(); // NEW: Memory trigger!
this.setupControls();
this.createUI();
// Camera
this.cameras.main.startFollow(this.player, true, 0.1, 0.1);
this.cameras.main.setZoom(1.5);
this.showInstructions();
console.log('✅ DemoSceneEnhanced: Ready!');
}
createWorld() {
const graphics = this.add.graphics();
// Grass
graphics.fillStyle(0x7cfc00, 1);
graphics.fillRect(0, 0, 2000, 2000);
// Farm plot (tilled soil)
graphics.fillStyle(0x8B4513, 1);
for (let x = 3; x < 13; x++) {
for (let y = 3; y < 8; y++) {
graphics.fillRect(x * 64, y * 64, 64, 64);
}
}
// Tent area
graphics.fillStyle(0xCD853F, 1);
graphics.fillRect(800, 300, 200, 150);
// Add text labels
this.add.text(850, 250, 'TENT', {
fontSize: '24px',
color: '#ffffff',
backgroundColor: '#000000',
padding: { x: 10, y: 5 }
}).setOrigin(0.5);
this.add.text(400, 200, 'FARM PLOT', {
fontSize: '20px',
color: '#ffffff',
backgroundColor: '#000000',
padding: { x: 8, y: 4 }
}).setOrigin(0.5);
}
createPlayer() {
const playerX = 500;
const playerY = 500;
this.player = this.physics.add.sprite(playerX, playerY, null);
this.player.setCircle(16);
this.player.setCollideWorldBounds(true);
// Simple player graphic
const graphics = this.add.graphics();
graphics.fillStyle(0x0088FF, 1);
graphics.fillCircle(0, 0, 16);
graphics.fillStyle(0xFFFFFF, 1);
graphics.fillCircle(-5, -3, 3); // Left eye
graphics.fillCircle(5, -3, 3); // Right eye
graphics.generateTexture('player_kai', 32, 32);
graphics.destroy();
this.player.setTexture('player_kai');
this.player.speed = 200;
console.log('✅ Player (Kai) created');
}
createGronk() {
const gronkX = 1200;
const gronkY = 550;
this.gronk = this.physics.add.sprite(gronkX, gronkY, null);
// Simple Gronk graphic
const graphics = this.add.graphics();
graphics.fillStyle(0x228B22, 1);
graphics.fillCircle(0, 0, 24);
graphics.fillStyle(0xFFFFFF, 1);
graphics.fillCircle(-8, -5, 4);
graphics.fillCircle(8, -5, 4);
graphics.fillStyle(0x000000, 1);
graphics.fillRect(-10, 8, 20, 3); // Smile
graphics.generateTexture('gronk_sprite', 48, 48);
graphics.destroy();
this.gronk.setTexture('gronk_sprite');
// Label
const label = this.add.text(gronkX, gronkY - 50, '💨 GRONK 💨', {
fontSize: '18px',
color: '#00ff00',
backgroundColor: '#000000',
padding: { x: 8, y: 4 }
});
label.setOrigin(0.5);
this.gronk.label = label;
console.log('✅ Gronk created with vape emoji!');
}
createLocket() {
// Spawn locket in grass near player
const locketX = 350;
const locketY = 650;
this.locket = this.physics.add.sprite(locketX, locketY, 'locket');
this.locket.setScale(0.5);
// Glowing effect
this.tweens.add({
targets: this.locket,
alpha: { from: 0.5, to: 1 },
scale: { from: 0.45, to: 0.55 },
duration: 1500,
yoyo: true,
repeat: -1
});
// Collision detection
this.physics.add.overlap(
this.player,
this.locket,
this.pickupLocket,
null,
this
);
console.log('✅ Locket placed - memory trigger ready!');
}
pickupLocket() {
if (this.inventory.hasLocket) return;
console.log('💎 LOCKET PICKED UP!');
this.inventory.hasLocket = true;
this.locket.destroy();
// Trigger memory flashback!
this.triggerMemoryFlashback();
}
triggerMemoryFlashback() {
console.log('💔 MEMORY FLASHBACK TRIGGERED!');
this.memoria.triggered = true;
// Screen flash
this.cameras.main.flash(1000, 255, 255, 255);
// Show memory overlay
const overlay = this.add.rectangle(
this.cameras.main.width / 2,
this.cameras.main.height / 2,
this.cameras.main.width,
this.cameras.main.height,
0x000000,
0.8
);
overlay.setScrollFactor(0);
overlay.setDepth(500);
const memoryText = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height / 2 - 80,
'💔 MEMORY FLASHBACK 💔',
{
fontSize: '42px',
color: '#ffff00',
fontStyle: 'bold'
}
);
memoryText.setOrigin(0.5);
memoryText.setScrollFactor(0);
memoryText.setDepth(501);
const storyText = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height / 2,
'Mamin srebrn obesek...\n\nSpomin na dan pred apokalipso.\n\n"Kai, vedno te bom varovala."\n\n- Mama',
{
fontSize: '20px',
color: '#ffffff',
align: 'center',
wordWrap: { width: 600 }
}
);
storyText.setOrigin(0.5);
storyText.setScrollFactor(0);
storyText.setDepth(501);
const closeText = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height / 2 + 120,
'[Press E to continue]',
{
fontSize: '16px',
color: '#888888'
}
);
closeText.setOrigin(0.5);
closeText.setScrollFactor(0);
closeText.setDepth(501);
// Pulse effect
this.tweens.add({
targets: [memoryText, storyText],
alpha: { from: 0, to: 1 },
duration: 1000
});
// Close on E
const closeHandler = () => {
overlay.destroy();
memoryText.destroy();
storyText.destroy();
closeText.destroy();
this.keys.E.off('down', closeHandler);
console.log('✅ Memory complete - locket added to inventory');
};
this.keys.E.once('down', closeHandler);
}
setupControls() {
this.keys = {
W: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W),
A: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A),
S: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S),
D: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D),
E: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E),
ONE: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.ONE),
TWO: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.TWO)
};
this.keys.E.on('down', () => this.interact());
this.keys.ONE.on('down', () => this.selectTool('hoe'));
this.keys.TWO.on('down', () => this.selectTool('seeds'));
}
createUI() {
this.inventoryText = this.add.text(10, 10, '', {
fontSize: '16px',
color: '#ffffff',
backgroundColor: '#000000',
padding: { x: 10, y: 5 }
});
this.inventoryText.setScrollFactor(0);
this.inventoryText.setDepth(100);
this.questText = this.add.text(this.cameras.main.width - 10, 10, '', {
fontSize: '16px',
color: '#ffff00',
backgroundColor: '#000000',
padding: { x: 10, y: 5 }
});
this.questText.setOrigin(1, 0);
this.questText.setScrollFactor(0);
this.questText.setDepth(100);
this.toolText = this.add.text(10, 50, '', {
fontSize: '14px',
color: '#00ff00',
backgroundColor: '#000000',
padding: { x: 8, y: 3 }
});
this.toolText.setScrollFactor(0);
this.toolText.setDepth(100);
this.updateUI();
}
showInstructions() {
const instructions = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height - 50,
'WASD: Move | E: Talk/Interact | 1: Hoe | 2: Plant Seeds | Click: Use Tool',
{
fontSize: '16px',
color: '#ffffff',
backgroundColor: '#000000',
padding: { x: 15, y: 8 }
}
);
instructions.setOrigin(0.5);
instructions.setScrollFactor(0);
instructions.setDepth(100);
// Fade out after 15 seconds
this.time.delayedCall(15000, () => {
this.tweens.add({
targets: instructions,
alpha: 0,
duration: 2000,
onComplete: () => instructions.destroy()
});
});
}
interact() {
// Check Gronk
const distToGronk = Phaser.Math.Distance.Between(
this.player.x, this.player.y,
this.gronk.x, this.gronk.y
);
if (distToGronk < 100) {
this.talkToGronk();
return;
}
// Check wheat harvest
const tileX = Math.floor(this.player.x / 64);
const tileY = Math.floor(this.player.y / 64);
const key = `${tileX},${tileY}`;
if (this.wheat.has(key)) {
const crop = this.wheat.get(key);
if (crop.stage === 4) {
this.harvestWheat(tileX, tileY);
}
}
}
talkToGronk() {
console.log('💬 Talking to Gronk...');
if (!this.quest.active) {
this.showDialogue(
'💨 GRONK',
'*vapes*\n\nYo! Want to learn farming?\nPlant 5 wheat and I\'ll hook you up with gold!',
() => {
this.quest.active = true;
this.inventory.seeds = 5;
this.tools.hoe = true;
this.tools.wateringCan = true;
this.updateUI();
console.log('✅ Quest started!');
}
);
} else if (this.quest.complete) {
this.showDialogue(
'💨 GRONK',
'*vapes*\n\nYo that\'s fire! 🔥\n\nHere\'s 100 gold. You\'re a natural!\n\nDEMO COMPLETE!',
() => {
this.inventory.gold += 100;
this.updateUI();
this.showDemoComplete();
}
);
} else {
this.showDialogue(
'💨 GRONK',
`*vapes*\n\nKeep going! ${this.quest.planted}/5 wheat planted.`
);
}
}
showDialogue(name, text, onClose) {
const box = this.add.rectangle(
this.cameras.main.width / 2,
this.cameras.main.height - 100,
700, 140,
0x000000, 0.9
);
box.setScrollFactor(0);
box.setDepth(200);
const nameText = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height - 150,
name,
{
fontSize: '22px',
color: '#00ff00',
fontStyle: 'bold'
}
);
nameText.setOrigin(0.5);
nameText.setScrollFactor(0);
nameText.setDepth(201);
const dialogueText = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height - 100,
text,
{
fontSize: '18px',
color: '#ffffff',
align: 'center',
wordWrap: { width: 650 }
}
);
dialogueText.setOrigin(0.5);
dialogueText.setScrollFactor(0);
dialogueText.setDepth(201);
const closeText = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height - 40,
'[Press E to close]',
{
fontSize: '14px',
color: '#888888'
}
);
closeText.setOrigin(0.5);
closeText.setScrollFactor(0);
closeText.setDepth(201);
const closeHandler = () => {
box.destroy();
nameText.destroy();
dialogueText.destroy();
closeText.destroy();
this.keys.E.off('down', closeHandler);
if (onClose) onClose();
};
this.keys.E.once('down', closeHandler);
}
selectTool(tool) {
if (this.tools[tool]) {
this.currentTool = tool;
this.updateUI();
console.log('🔧 Selected:', tool);
}
}
useTool() {
if (!this.currentTool) return;
const tileX = Math.floor(this.player.x / 64);
const tileY = Math.floor(this.player.y / 64);
const key = `${tileX},${tileY}`;
if (this.currentTool === 'seeds') {
if (this.inventory.seeds > 0 && !this.wheat.has(key)) {
this.plantWheat(tileX, tileY);
}
}
}
plantWheat(tileX, tileY) {
this.inventory.seeds--;
this.quest.planted++;
const x = tileX * 64 + 32;
const y = tileY * 64 + 32;
// Create wheat sprite at stage 1
const sprite = this.add.sprite(x, y, 'wheat_stage1');
sprite.setScale(0.8);
const crop = {
stage: 1,
sprite: sprite,
planted: Date.now(),
growTimer: null
};
this.wheat.set(key, crop);
// Auto-grow stages every 10 seconds
crop.growTimer = this.time.addEvent({
delay: 10000,
callback: () => this.growWheat(key),
repeat: 3
});
if (this.quest.planted >= this.quest.target) {
this.quest.complete = true;
}
this.updateUI();
console.log(`🌱 Planted wheat at ${tileX},${tileY}`);
}
growWheat(key) {
if (!this.wheat.has(key)) return;
const crop = this.wheat.get(key);
if (crop.stage >= 4) return;
crop.stage++;
crop.sprite.setTexture(`wheat_stage${crop.stage}`);
// Scale up as it grows
crop.sprite.setScale(0.6 + (crop.stage * 0.1));
console.log(`🌾 Wheat grew to stage ${crop.stage}`);
if (crop.stage === 4) {
// Add sparkle effect for ready harvest
this.tweens.add({
targets: crop.sprite,
alpha: { from: 0.8, to: 1 },
duration: 800,
yoyo: true,
repeat: -1
});
}
}
harvestWheat(tileX, tileY) {
const key = `${tileX},${tileY}`;
const crop = this.wheat.get(key);
if (crop) {
crop.sprite.destroy();
if (crop.growTimer) crop.growTimer.destroy();
this.wheat.delete(key);
this.inventory.wheat++;
this.inventory.seeds++; // Get seeds back
this.updateUI();
console.log('✅ Harvested wheat!');
}
}
showDemoComplete() {
const bg = this.add.rectangle(
this.cameras.main.width / 2,
this.cameras.main.height / 2,
this.cameras.main.width,
this.cameras.main.height,
0x000000, 0.85
);
bg.setScrollFactor(0);
bg.setDepth(300);
const title = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height / 2 - 120,
'🎉 DEMO COMPLETE! 🎉',
{
fontSize: '52px',
color: '#ffff00',
fontStyle: 'bold'
}
);
title.setOrigin(0.5);
title.setScrollFactor(0);
title.setDepth(301);
const stats = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height / 2 - 20,
`Wheat Planted: ${this.quest.planted}\nWheat Harvested: ${this.inventory.wheat}\nGold Earned: ${this.inventory.gold}g\n\n💎 Locket Found: ${this.inventory.hasLocket ? 'YES' : 'NO'}`,
{
fontSize: '22px',
color: '#ffffff',
align: 'center'
}
);
stats.setOrigin(0.5);
stats.setScrollFactor(0);
stats.setDepth(301);
const footer = this.add.text(
this.cameras.main.width / 2,
this.cameras.main.height / 2 + 100,
'Thank you for playing!\nFull game coming soon on Kickstarter!',
{
fontSize: '20px',
color: '#00ff00',
align: 'center'
}
);
footer.setOrigin(0.5);
footer.setScrollFactor(0);
footer.setDepth(301);
// Pulse animation
this.tweens.add({
targets: title,
scale: { from: 1, to: 1.1 },
duration: 1000,
yoyo: true,
repeat: -1
});
console.log('🎉 DEMO COMPLETE!');
}
updateUI() {
// Inventory
let invText = `Seeds: ${this.inventory.seeds} | Wheat: ${this.inventory.wheat} | Gold: ${this.inventory.gold}g`;
if (this.inventory.hasLocket) {
invText += ' | 💎 Locket';
}
this.inventoryText.setText(invText);
// Quest
if (this.quest.active) {
this.questText.setText(
`Quest: Plant Wheat ${this.quest.planted}/${this.quest.target}` +
(this.quest.complete ? ' - COMPLETE!' : '')
);
}
// Tool
if (this.currentTool) {
this.toolText.setText(`Tool: ${this.currentTool.toUpperCase()}`);
} else {
this.toolText.setText('');
}
}
update() {
if (!this.player) return;
// Movement
let velocityX = 0;
let velocityY = 0;
if (this.keys.W.isDown) velocityY = -1;
if (this.keys.S.isDown) velocityY = 1;
if (this.keys.A.isDown) velocityX = -1;
if (this.keys.D.isDown) velocityX = 1;
// Normalize diagonal
if (velocityX !== 0 && velocityY !== 0) {
velocityX *= 0.707;
velocityY *= 0.707;
}
this.player.setVelocity(
velocityX * this.player.speed,
velocityY * this.player.speed
);
// Use tool with click
if (this.input.activePointer.isDown && this.currentTool) {
this.useTool();
}
// Update Gronk label
if (this.gronk && this.gronk.label) {
this.gronk.label.setPosition(this.gronk.x, this.gronk.y - 50);
}
}
}