// 🎮 DEMO SCENE - Simple 5-minute farming demo! // Shows core gameplay: Walk, talk to Gronk, plant wheat, complete quest class DemoScene extends Phaser.Scene { constructor() { super({ key: 'DemoScene' }); this.player = null; this.gronk = null; this.zombies = []; this.wheat = new Map(); // Track planted wheat this.inventory = { seeds: 0, wheat: 0, gold: 0 }; this.tools = { hoe: false, wateringCan: false, axe: false }; this.currentTool = null; this.quest = { active: false, target: 5, planted: 0, complete: false }; } create() { console.log('🎮 DemoScene: Starting demo!'); const width = 1024; const height = 768; // Setup camera this.cameras.main.setBackgroundColor('#7cfc00'); // Grass green this.cameras.main.setBounds(0, 0, 2000, 2000); this.physics.world.setBounds(0, 0, 2000, 2000); // Create simple world this.createSimpleWorld(); // Create player (Kai) this.createPlayer(); // Create Gronk NPC this.createGronk(); // Create ambient zombies this.createZombies(); // Setup controls this.setupControls(); // Create UI this.createUI(); // Camera follow player this.cameras.main.startFollow(this.player, true, 0.1, 0.1); this.cameras.main.setZoom(1); // Instructions this.showInstructions(); console.log('✅ DemoScene: Ready!'); } createSimpleWorld() { // Create simple grass background const graphics = this.add.graphics(); graphics.fillStyle(0x7cfc00, 1); graphics.fillRect(0, 0, 2000, 2000); // Add some dirt patches (farmable areas) graphics.fillStyle(0x8B4513, 1); for (let x = 5; x < 15; x++) { for (let y = 5; y < 10; y++) { graphics.fillRect(x * 64, y * 64, 64, 64); } } // Add farmhouse (simple rectangle) graphics.fillStyle(0xCD853F, 1); graphics.fillRect(800, 300, 200, 150); graphics.fillStyle(0x8B4513, 1); graphics.fillTriangle(800, 300, 1000, 300, 900, 200); // Add barn graphics.fillStyle(0xB22222, 1); graphics.fillRect(1200, 400, 180, 140); graphics.fillStyle(0x8B0000, 1); graphics.fillTriangle(1200, 400, 1380, 400, 1290, 300); } createPlayer() { // Create player sprite (simple circle for now) const playerX = 500; const playerY = 500; this.player = this.physics.add.sprite(playerX, playerY, null); this.player.setCircle(16); this.player.setCollideWorldBounds(true); // Draw simple player (blue circle) const graphics = this.add.graphics(); graphics.fillStyle(0x0000FF, 1); graphics.fillCircle(0, 0, 16); graphics.generateTexture('player_temp', 32, 32); graphics.destroy(); this.player.setTexture('player_temp'); // Player properties this.player.speed = 200; this.player.facingDirection = 'down'; console.log('✅ Player created at', playerX, playerY); } createGronk() { // Gronk stands near barn const gronkX = 1200; const gronkY = 550; this.gronk = this.physics.add.sprite(gronkX, gronkY, null); // Draw simple Gronk (green circle) const graphics = this.add.graphics(); graphics.fillStyle(0x00FF00, 1); graphics.fillCircle(0, 0, 20); graphics.generateTexture('gronk_temp', 40, 40); graphics.destroy(); this.gronk.setTexture('gronk_temp'); // Add name label const label = this.add.text(gronkX, gronkY - 40, 'GRONK', { fontSize: '16px', color: '#ffffff', backgroundColor: '#000000', padding: { x: 5, y: 2 } }); label.setOrigin(0.5); this.gronk.label = label; console.log('✅ Gronk created at', gronkX, gronkY); } createZombies() { // 3 zombies wandering around const zombiePositions = [ { x: 600, y: 700 }, { x: 900, y: 600 }, { x: 700, y: 800 } ]; zombiePositions.forEach((pos, i) => { const zombie = this.physics.add.sprite(pos.x, pos.y, null); // Draw simple zombie (gray circle) if (i === 0) { const graphics = this.add.graphics(); graphics.fillStyle(0x808080, 1); graphics.fillCircle(0, 0, 14); graphics.generateTexture('zombie_temp', 28, 28); graphics.destroy(); } zombie.setTexture('zombie_temp'); // Random wandering zombie.wander = () => { const angle = Math.random() * Math.PI * 2; zombie.setVelocity( Math.cos(angle) * 30, Math.sin(angle) * 30 ); }; // Wander every 2 seconds this.time.addEvent({ delay: 2000, callback: zombie.wander, callbackScope: this, loop: true }); zombie.wander(); this.zombies.push(zombie); }); console.log('✅ 3 zombies created'); } setupControls() { // WASD movement 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), // Interact ONE: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.ONE), // Hoe TWO: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.TWO), // Seeds THREE: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.THREE) // Water }; // E key - interact this.keys.E.on('down', () => this.interact()); // Tool selection this.keys.ONE.on('down', () => this.selectTool('hoe')); this.keys.TWO.on('down', () => this.selectTool('seeds')); this.keys.THREE.on('down', () => this.selectTool('wateringCan')); console.log('✅ Controls setup'); } createUI() { // Inventory display 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); // Quest tracker 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); // Tool indicator 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: Seeds | 3: Water', { fontSize: '18px', color: '#ffffff', backgroundColor: '#000000', padding: { x: 15, y: 8 } } ); instructions.setOrigin(0.5); instructions.setScrollFactor(0); instructions.setDepth(100); // Fade out after 10 seconds this.time.delayedCall(10000, () => { this.tweens.add({ targets: instructions, alpha: 0, duration: 2000, onComplete: () => instructions.destroy() }); }); } interact() { // Check if near Gronk const distToGronk = Phaser.Math.Distance.Between( this.player.x, this.player.y, this.gronk.x, this.gronk.y ); if (distToGronk < 80) { this.talkToGronk(); return; } // Check if near 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 === 3) { this.harvestWheat(tileX, tileY); } } } talkToGronk() { console.log('💬 Talking to Gronk...'); if (!this.quest.active) { // Start quest this.showDialogue( 'GRONK', 'Hey! Want to learn farming?\nPlant 5 wheat seeds and I\'ll reward you!', () => { // Give quest 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) { // Quest complete! this.showDialogue( 'GRONK', 'Amazing! You\'re a natural farmer!\nHere\'s 100 gold. DEMO COMPLETE!', () => { this.inventory.gold += 100; this.updateUI(); this.showDemoComplete(); } ); } else { // Quest in progress this.showDialogue( 'GRONK', `Keep going! You've planted ${this.quest.planted}/5 wheat!` ); } } showDialogue(name, text, onClose) { // Create dialogue box const box = this.add.rectangle( this.cameras.main.width / 2, this.cameras.main.height - 100, 600, 120, 0x000000, 0.9 ); box.setScrollFactor(0); box.setDepth(200); const nameText = this.add.text( this.cameras.main.width / 2, this.cameras.main.height - 140, name, { fontSize: '20px', color: '#ffff00', 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: '16px', color: '#ffffff', align: 'center', wordWrap: { width: 550 } } ); dialogueText.setOrigin(0.5); dialogueText.setScrollFactor(0); dialogueText.setDepth(201); const closeText = this.add.text( this.cameras.main.width / 2, this.cameras.main.height - 50, '[Press E to close]', { fontSize: '14px', color: '#888888' } ); closeText.setOrigin(0.5); closeText.setScrollFactor(0); closeText.setDepth(201); // Close on E 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:', 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 === 'hoe') { // Till soil (no action needed, just visual feedback) console.log('🔧 Tilling soil at', tileX, tileY); } else if (this.currentTool === 'seeds') { // Plant wheat if (this.inventory.seeds > 0 && !this.wheat.has(key)) { this.plantWheat(tileX, tileY); } } else if (this.currentTool === 'wateringCan') { // Water wheat if (this.wheat.has(key)) { const crop = this.wheat.get(key); if (crop.stage < 3) { crop.stage++; crop.sprite.setTint(0x00ff00 * crop.stage / 3); console.log('💧 Watered wheat, now stage', crop.stage); } } } } plantWheat(tileX, tileY) { this.inventory.seeds--; this.quest.planted++; // Create wheat sprite const x = tileX * 64 + 32; const y = tileY * 64 + 32; const sprite = this.add.circle(x, y, 8, 0x228B22); const crop = { stage: 1, sprite: sprite, planted: Date.now() }; this.wheat.set(`${tileX},${tileY}`, crop); // Auto-grow after 10 seconds this.time.delayedCall(10000, () => { if (crop.stage < 3) { crop.stage = 3; crop.sprite.setRadius(12); crop.sprite.setFillStyle(0xFFD700); console.log('🌾 Wheat ready to harvest!'); } }); // Check quest if (this.quest.planted >= this.quest.target) { this.quest.complete = true; } this.updateUI(); console.log('🌱 Planted wheat at', tileX, tileY); } harvestWheat(tileX, tileY) { const key = `${tileX},${tileY}`; const crop = this.wheat.get(key); if (crop) { crop.sprite.destroy(); this.wheat.delete(key); this.inventory.wheat++; this.inventory.seeds++; // Get seeds back this.updateUI(); console.log('✅ Harvested wheat at', tileX, tileY); } } showDemoComplete() { // Show completion screen 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.9 ); bg.setScrollFactor(0); bg.setDepth(300); const title = this.add.text( this.cameras.main.width / 2, this.cameras.main.height / 2 - 100, '🎉 DEMO COMPLETE! 🎉', { fontSize: '48px', color: '#ffff00', fontStyle: 'bold' } ); title.setOrigin(0.5); title.setScrollFactor(0); title.setDepth(301); const text = this.add.text( this.cameras.main.width / 2, this.cameras.main.height / 2, 'Thank you for playing!\nFull game coming soon on Kickstarter!', { fontSize: '24px', color: '#ffffff', align: 'center' } ); text.setOrigin(0.5); text.setScrollFactor(0); text.setDepth(301); console.log('🎉 DEMO COMPLETE!'); } updateUI() { // Update inventory this.inventoryText.setText( `Seeds: ${this.inventory.seeds} | Wheat: ${this.inventory.wheat} | Gold: ${this.inventory.gold}` ); // Update quest if (this.quest.active) { this.questText.setText( `Quest: Plant Wheat ${this.quest.planted}/${this.quest.target}` + (this.quest.complete ? ' - COMPLETE!' : '') ); } // Update tool if (this.currentTool) { this.toolText.setText(`Tool: ${this.currentTool.toUpperCase()}`); } else { this.toolText.setText(''); } } update() { if (!this.player) return; // Player 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 movement 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 mouse click if (this.input.activePointer.isDown && this.currentTool) { this.useTool(); } // Update Gronk label position if (this.gronk && this.gronk.label) { this.gronk.label.setPosition(this.gronk.x, this.gronk.y - 40); } } }