// UI Polish System - Smooth transitions, animations, tooltips class UIPolishSystem { constructor(scene) { this.scene = scene; // Tooltip management this.currentTooltip = null; this.tooltipDelay = 500; // Show after 500ms hover this.tooltipTimer = null; // Button animations cache this.buttonAnimations = new Map(); console.log('🎨 UIPolishSystem initialized'); } // Fade in a UI element smoothly fadeIn(element, duration = 300, delay = 0) { if (!element) return; element.setAlpha(0); this.scene.tweens.add({ targets: element, alpha: 1, duration: duration, delay: delay, ease: 'Power2' }); } // Fade out a UI element fadeOut(element, duration = 300, onComplete = null) { if (!element) return; this.scene.tweens.add({ targets: element, alpha: 0, duration: duration, ease: 'Power2', onComplete: onComplete }); } // Slide in element from direction slideIn(element, direction = 'left', duration = 400, distance = 200) { if (!element) return; const startX = element.x; const startY = element.y; // Set starting position switch (direction) { case 'left': element.x -= distance; break; case 'right': element.x += distance; break; case 'top': element.y -= distance; break; case 'bottom': element.y += distance; break; } element.setAlpha(0); // Animate to original position this.scene.tweens.add({ targets: element, x: startX, y: startY, alpha: 1, duration: duration, ease: 'Back.easeOut' }); } // Add hover effect to button addButtonHover(button, scaleUp = 1.1, duration = 200) { if (!button || this.buttonAnimations.has(button)) return; const originalScale = button.scaleX || 1; // Mouse over button.on('pointerover', () => { this.scene.tweens.add({ targets: button, scaleX: originalScale * scaleUp, scaleY: originalScale * scaleUp, duration: duration, ease: 'Back.easeOut' }); // Play UI click sound if (this.scene.soundManager && this.scene.soundManager.beepUIClick) { this.scene.soundManager.beepUIClick(); } }); // Mouse out button.on('pointerout', () => { this.scene.tweens.add({ targets: button, scaleX: originalScale, scaleY: originalScale, duration: duration, ease: 'Power2' }); }); this.buttonAnimations.set(button, { originalScale, scaleUp }); } // Pulse animation (for important elements) pulse(element, minScale = 0.95, maxScale = 1.05, duration = 1000) { if (!element) return; return this.scene.tweens.add({ targets: element, scale: { from: minScale, to: maxScale }, duration: duration, yoyo: true, repeat: -1, ease: 'Sine.easeInOut' }); } // Shake animation (for errors or attention) shake(element, intensity = 10, duration = 500) { if (!element) return; const originalX = element.x; this.scene.tweens.add({ targets: element, x: originalX + intensity, duration: 50, yoyo: true, repeat: Math.floor(duration / 100), ease: 'Sine.easeInOut', onComplete: () => { element.x = originalX; // Reset to original position } }); } // Show tooltip on hover showTooltip(x, y, text, options = {}) { // Clear existing tooltip this.hideTooltip(); const { backgroundColor = '#000000', textColor = '#ffffff', padding = 10, fontSize = '14px', maxWidth = 200, offsetX = 10, offsetY = -30 } = options; // Create tooltip background const bg = this.scene.add.rectangle( x + offsetX, y + offsetY, maxWidth, 40, Phaser.Display.Color.HexStringToColor(backgroundColor).color, 0.9 ); // Create tooltip text const tooltip = this.scene.add.text( x + offsetX, y + offsetY, text, { fontSize: fontSize, color: textColor, align: 'center', wordWrap: { width: maxWidth - padding * 2 } } ); tooltip.setOrigin(0.5, 0.5); bg.setSize(tooltip.width + padding * 2, tooltip.height + padding * 2); // Create container this.currentTooltip = this.scene.add.container(0, 0, [bg, tooltip]); this.currentTooltip.setDepth(1000000); // Always on top // Fade in this.fadeIn(this.currentTooltip, 200); } // Hide current tooltip hideTooltip() { if (this.currentTooltip) { this.fadeOut(this.currentTooltip, 150, () => { this.currentTooltip.destroy(); this.currentTooltip = null; }); } } // Add tooltip to interactive object addTooltip(object, text, options = {}) { if (!object) return; let hoverTimer = null; object.on('pointerover', (pointer) => { // Delay tooltip appearance hoverTimer = this.scene.time.delayedCall(this.tooltipDelay, () => { this.showTooltip(pointer.worldX, pointer.worldY, text, options); }); }); object.on('pointerout', () => { // Cancel delayed tooltip if (hoverTimer) { hoverTimer.destroy(); hoverTimer = null; } this.hideTooltip(); }); object.on('pointermove', (pointer) => { // Move tooltip with mouse if (this.currentTooltip) { this.currentTooltip.setPosition( pointer.worldX + 10, pointer.worldY - 30 ); } }); } // Typewriter text effect typewriterText(textObject, fullText, speed = 50) { if (!textObject) return; textObject.setText(''); let index = 0; const timer = this.scene.time.addEvent({ delay: speed, callback: () => { if (index < fullText.length) { textObject.setText(textObject.text + fullText[index]); index++; } else { timer.destroy(); } }, loop: true }); return timer; } // Number counter animation (for scores, resources) animateNumber(textObject, startValue, endValue, duration = 1000, prefix = '', suffix = '') { if (!textObject) return; const data = { value: startValue }; this.scene.tweens.add({ targets: data, value: endValue, duration: duration, ease: 'Power2', onUpdate: () => { textObject.setText(`${prefix}${Math.floor(data.value)}${suffix}`); } }); } // Flash effect (for notifications) flash(element, color = 0xffffff, duration = 300) { if (!element) return; const originalTint = element.tint || 0xffffff; element.setTint(color); this.scene.tweens.add({ targets: element, alpha: { from: 1, to: 0.5 }, duration: duration / 2, yoyo: true, onComplete: () => { element.setTint(originalTint); } }); } // Smooth scroll container (for long lists) enableSmoothScroll(container, scrollSpeed = 5) { if (!container || !this.scene.input.keyboard) return; const upKey = this.scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP); const downKey = this.scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.DOWN); this.scene.events.on('update', () => { if (upKey.isDown) { container.y += scrollSpeed; } if (downKey.isDown) { container.y -= scrollSpeed; } }); } // Clean up destroy() { this.hideTooltip(); this.buttonAnimations.clear(); console.log('🎨 UIPolishSystem destroyed'); } }