/** * BREEDING UI SYSTEM * Visual family tree and genetics display for animal breeding */ class BreedingUISystem { constructor(scene) { this.scene = scene; this.enabled = true; // UI elements this.container = null; this.familyTreeView = null; this.geneticsPanel = null; this.isVisible = false; // Selected animal this.selectedAnimal = null; // Family tree data this.familyTree = new Map(); // UI settings this.settings = { nodeWidth: 80, nodeHeight: 60, horizontalSpacing: 100, verticalSpacing: 80, maxGenerations: 5 }; this.init(); console.log('✅ Breeding UI System initialized'); } init() { this.createUI(); console.log('🌳 Family tree UI ready'); } // ========== UI CREATION ========== createUI() { // Main container (hidden by default) this.container = this.scene.add.container(0, 0); this.container.setDepth(1000); this.container.setVisible(false); // Background overlay const overlay = this.scene.add.rectangle( this.scene.cameras.main.width / 2, this.scene.cameras.main.height / 2, this.scene.cameras.main.width, this.scene.cameras.main.height, 0x000000, 0.8 ); overlay.setInteractive(); overlay.on('pointerdown', () => this.hide()); this.container.add(overlay); // Panel background const panelWidth = 800; const panelHeight = 600; const panelX = this.scene.cameras.main.width / 2; const panelY = this.scene.cameras.main.height / 2; const panel = this.scene.add.rectangle( panelX, panelY, panelWidth, panelHeight, 0x2a2a2a ); panel.setStrokeStyle(2, 0x4a4a4a); this.container.add(panel); // Title const title = this.scene.add.text( panelX, panelY - panelHeight / 2 + 30, 'Family Tree & Genetics', { fontSize: '24px', fontStyle: 'bold', color: '#ffffff' } ); title.setOrigin(0.5); this.container.add(title); // Close button const closeBtn = this.scene.add.text( panelX + panelWidth / 2 - 30, panelY - panelHeight / 2 + 30, '✕', { fontSize: '32px', color: '#ff4444' } ); closeBtn.setOrigin(0.5); closeBtn.setInteractive({ useHandCursor: true }); closeBtn.on('pointerdown', () => this.hide()); this.container.add(closeBtn); // Family tree view area this.familyTreeView = this.scene.add.container(panelX - 300, panelY); this.container.add(this.familyTreeView); // Genetics panel this.geneticsPanel = this.scene.add.container(panelX + 200, panelY); this.container.add(this.geneticsPanel); } // ========== SHOW/HIDE ========== show(animalId) { if (!this.scene.animalBreeding) { console.log('❌ Animal Breeding System not found'); return; } const animal = this.scene.animalBreeding.animals.get(animalId); if (!animal) { console.log('❌ Animal not found'); return; } this.selectedAnimal = animal; this.buildFamilyTree(animal); this.displayGeneticsInfo(animal); this.container.setVisible(true); this.isVisible = true; } hide() { this.container.setVisible(false); this.isVisible = false; this.selectedAnimal = null; } // ========== FAMILY TREE ========== buildFamilyTree(animal) { // Clear previous tree this.familyTreeView.removeAll(true); // Build tree structure const tree = this.generateTreeStructure(animal); // Render tree this.renderTree(tree, 0, 0, 0); } generateTreeStructure(animal, generation = 0) { if (generation >= this.settings.maxGenerations) { return null; } const node = { animal, generation, parents: [] }; // Get parents (if stored) if (animal.parents) { node.parents = animal.parents.map(parentId => { const parent = this.scene.animalBreeding.animals.get(parentId); return parent ? this.generateTreeStructure(parent, generation + 1) : null; }).filter(p => p !== null); } return node; } renderTree(node, x, y, generation) { if (!node) return; const settings = this.settings; // Draw node this.drawAnimalNode(node.animal, x, y); // Draw parents if (node.parents.length > 0) { const parentY = y - settings.verticalSpacing; const parentSpacing = settings.horizontalSpacing; node.parents.forEach((parent, index) => { const parentX = x + (index - 0.5) * parentSpacing; // Draw connection line const line = this.scene.add.line( 0, 0, x, y - settings.nodeHeight / 2, parentX, parentY + settings.nodeHeight / 2, 0x888888 ); line.setLineWidth(2); this.familyTreeView.add(line); // Render parent node this.renderTree(parent, parentX, parentY, generation + 1); }); } } drawAnimalNode(animal, x, y) { const settings = this.settings; // Node background const nodeColor = this.getNodeColor(animal); const node = this.scene.add.rectangle( x, y, settings.nodeWidth, settings.nodeHeight, nodeColor ); node.setStrokeStyle(2, 0xffffff); this.familyTreeView.add(node); // Animal icon/emoji const icon = this.getAnimalIcon(animal.species); const iconText = this.scene.add.text(x, y - 10, icon, { fontSize: '24px' }); iconText.setOrigin(0.5); this.familyTreeView.add(iconText); // Animal name/gender const genderSymbol = animal.gender === 'male' ? '♂' : '♀'; const nameText = this.scene.add.text( x, y + 15, `${genderSymbol} ${animal.species}`, { fontSize: '10px', color: '#ffffff' } ); nameText.setOrigin(0.5); this.familyTreeView.add(nameText); // Mutation indicator if (animal.genetics.mutation) { const mutationBadge = this.scene.add.text( x + settings.nodeWidth / 2 - 5, y - settings.nodeHeight / 2 + 5, '⭐', { fontSize: '12px' } ); mutationBadge.setOrigin(0.5); this.familyTreeView.add(mutationBadge); } // Make interactive node.setInteractive({ useHandCursor: true }); node.on('pointerdown', () => { this.selectedAnimal = animal; this.displayGeneticsInfo(animal); }); } getNodeColor(animal) { // Color based on genetics const colorMap = { brown: 0x8B4513, black: 0x000000, white: 0xFFFFFF, golden: 0xFFD700, rainbow: 0xFF00FF }; return colorMap[animal.genetics.color] || 0x888888; } getAnimalIcon(species) { const icons = { sheep: '🐑', cow: '🐄', chicken: '🐔', pig: '🐷', horse: '🐴' }; return icons[species] || '🐾'; } // ========== GENETICS PANEL ========== displayGeneticsInfo(animal) { // Clear previous info this.geneticsPanel.removeAll(true); let yOffset = -200; // Title const title = this.scene.add.text(0, yOffset, 'Genetics Info', { fontSize: '18px', fontStyle: 'bold', color: '#ffffff' }); title.setOrigin(0.5); this.geneticsPanel.add(title); yOffset += 40; // Animal info const info = [ `Species: ${animal.species}`, `Gender: ${animal.gender}`, `Age: ${Math.floor(animal.age)} days`, `Stage: ${animal.stage}`, '', '--- Genetics ---', `Color: ${animal.genetics.color}`, `Size: ${animal.genetics.size}`, `Speed: ${animal.genetics.speed}`, `Production: ${animal.genetics.production}` ]; // Mutation info if (animal.genetics.mutation) { info.push('', '--- Mutation ---'); info.push(`Type: ${animal.genetics.mutation}`); info.push('⭐ RARE MUTATION!'); } // Breeding info if (animal.pregnant) { info.push('', '--- Breeding ---'); info.push(`Pregnant: ${Math.floor(animal.gestationProgress * 100)}%`); } // Display all info info.forEach(line => { const text = this.scene.add.text(0, yOffset, line, { fontSize: '14px', color: line.includes('---') ? '#ffff00' : '#ffffff' }); text.setOrigin(0.5); this.geneticsPanel.add(text); yOffset += 20; }); // DNA Helix Animation if (animal.genetics.mutation) { this.addDNAHelixAnimation(0, yOffset + 50); } } addDNAHelixAnimation(x, y) { // Create mini DNA helix const helix = this.scene.add.container(x, y); for (let i = 0; i < 10; i++) { const yPos = i * 5 - 25; const angle = (i / 10) * Math.PI * 2; const x1 = Math.cos(angle) * 10; const x2 = Math.cos(angle + Math.PI) * 10; const dot1 = this.scene.add.circle(x1, yPos, 2, 0x00ff00); const dot2 = this.scene.add.circle(x2, yPos, 2, 0x00ffff); helix.add(dot1); helix.add(dot2); } // Rotate animation this.scene.tweens.add({ targets: helix, rotation: Math.PI * 2, duration: 3000, repeat: -1, ease: 'Linear' }); this.geneticsPanel.add(helix); } // ========== BREEDING PREDICTION ========== showBreedingPrediction(animal1, animal2) { if (!animal1 || !animal2) return; // Predict offspring genetics const prediction = this.predictOffspring(animal1, animal2); // Show in UI this.displayPrediction(prediction); } predictOffspring(parent1, parent2) { // Simulate genetics inheritance const prediction = { possibleColors: this.predictColor(parent1, parent2), possibleSizes: this.predictTrait(parent1.genetics.size, parent2.genetics.size), possibleSpeeds: this.predictTrait(parent1.genetics.speed, parent2.genetics.speed), mutationChance: 0.05 // 5% }; return prediction; } predictColor(p1, p2) { const colors = [p1.genetics.color, p2.genetics.color]; // Add dominant/recessive logic const dominant = ['brown', 'black']; const recessive = ['white', 'golden']; if (dominant.includes(p1.genetics.color)) { return [p1.genetics.color]; } if (dominant.includes(p2.genetics.color)) { return [p2.genetics.color]; } return colors; } predictTrait(trait1, trait2) { return [trait1, trait2]; } displayPrediction(prediction) { // Clear genetics panel this.geneticsPanel.removeAll(true); let yOffset = -200; const title = this.scene.add.text(0, yOffset, 'Breeding Prediction', { fontSize: '18px', fontStyle: 'bold', color: '#ffff00' }); title.setOrigin(0.5); this.geneticsPanel.add(title); yOffset += 40; // Display predictions const info = [ 'Possible Offspring:', '', `Colors: ${prediction.possibleColors.join(', ')}`, `Sizes: ${prediction.possibleSizes.join(', ')}`, `Speeds: ${prediction.possibleSpeeds.join(', ')}`, '', `Mutation Chance: ${prediction.mutationChance * 100}%` ]; info.forEach(line => { const text = this.scene.add.text(0, yOffset, line, { fontSize: '14px', color: '#ffffff' }); text.setOrigin(0.5); this.geneticsPanel.add(text); yOffset += 20; }); } // ========== KEYBOARD SHORTCUT ========== setupKeyboard() { // Press 'F' to open family tree for selected animal this.scene.input.keyboard.on('keydown-F', () => { if (this.selectedAnimal) { if (this.isVisible) { this.hide(); } else { this.show(this.selectedAnimal.id); } } }); } // ========== UPDATE ========== update(delta) { // Update animations if visible if (this.isVisible) { // Any dynamic updates here } } destroy() { if (this.container) { this.container.destroy(); } console.log('🌳 Breeding UI System destroyed'); } }