Spaces:
Running on Zero
Running on Zero
| /** | |
| * ============================================================================ | |
| * TWEEN PRESETS - Common UI animations for UI-heavy games | |
| * ============================================================================ | |
| * | |
| * Utility functions for common UI animations. These are ADDITIONAL helpers | |
| * that supplement core/utils.ts (which is NOT overwritten by this module). | |
| * | |
| * This file exports INDIVIDUAL FUNCTIONS, not a class or object. | |
| * | |
| * CORRECT IMPORT: | |
| * import { fadeIn, shake, popIn } from '../ui/TweenPresets'; | |
| * fadeIn(this, myImage, 300); | |
| * shake(this, enemy, 5, 200); | |
| * | |
| * ALSO VALID (namespace import): | |
| * import * as TweenPresets from '../ui/TweenPresets'; | |
| * TweenPresets.fadeIn(this, myImage, 300); | |
| * | |
| * !! WRONG - WILL CAUSE RUNTIME ERROR !! | |
| * import { TweenPresets } from '../ui/TweenPresets'; // <-- NO SUCH EXPORT | |
| * new TweenPresets(...) // <-- NOT A CLASS | |
| * ============================================================================ | |
| */ | |
| import Phaser from 'phaser'; | |
| /** Fade in a game object. */ | |
| export const fadeIn = ( | |
| scene: Phaser.Scene, | |
| target: Phaser.GameObjects.GameObject, | |
| duration: number = 300, | |
| onComplete?: () => void, | |
| ): Phaser.Tweens.Tween => { | |
| (target as any).alpha = 0; | |
| return scene.tweens.add({ | |
| targets: target, | |
| alpha: 1, | |
| duration, | |
| onComplete, | |
| }); | |
| }; | |
| /** Fade out a game object. */ | |
| export const fadeOut = ( | |
| scene: Phaser.Scene, | |
| target: Phaser.GameObjects.GameObject, | |
| duration: number = 300, | |
| onComplete?: () => void, | |
| ): Phaser.Tweens.Tween => { | |
| return scene.tweens.add({ | |
| targets: target, | |
| alpha: 0, | |
| duration, | |
| onComplete, | |
| }); | |
| }; | |
| /** Slide a game object to a position. */ | |
| export const slideTo = ( | |
| scene: Phaser.Scene, | |
| target: Phaser.GameObjects.GameObject, | |
| toX: number, | |
| toY: number, | |
| duration: number = 400, | |
| ease: string = 'Cubic.easeOut', | |
| onComplete?: () => void, | |
| ): Phaser.Tweens.Tween => { | |
| return scene.tweens.add({ | |
| targets: target, | |
| x: toX, | |
| y: toY, | |
| duration, | |
| ease, | |
| onComplete, | |
| }); | |
| }; | |
| /** Scale bounce effect (pop in). */ | |
| export const popIn = ( | |
| scene: Phaser.Scene, | |
| target: Phaser.GameObjects.GameObject, | |
| duration: number = 200, | |
| onComplete?: () => void, | |
| ): Phaser.Tweens.Tween => { | |
| (target as any).setScale(0); | |
| return scene.tweens.add({ | |
| targets: target, | |
| scaleX: 1, | |
| scaleY: 1, | |
| duration, | |
| ease: 'Back.easeOut', | |
| onComplete, | |
| }); | |
| }; | |
| /** Shake effect (for damage feedback, errors). */ | |
| export const shake = ( | |
| scene: Phaser.Scene, | |
| target: Phaser.GameObjects.GameObject, | |
| intensity: number = 5, | |
| duration: number = 200, | |
| onComplete?: () => void, | |
| ): void => { | |
| const originalX = (target as any).x; | |
| scene.tweens.add({ | |
| targets: target, | |
| x: originalX + intensity, | |
| duration: duration / 8, | |
| yoyo: true, | |
| repeat: 3, | |
| onComplete: () => { | |
| (target as any).x = originalX; | |
| onComplete?.(); | |
| }, | |
| }); | |
| }; | |
| /** Pulse/breathe effect (infinite loop). */ | |
| export const pulse = ( | |
| scene: Phaser.Scene, | |
| target: Phaser.GameObjects.GameObject, | |
| minScale: number = 0.95, | |
| maxScale: number = 1.05, | |
| duration: number = 600, | |
| ): Phaser.Tweens.Tween => { | |
| // Set initial scale to minScale so the tween oscillates between min and max | |
| (target as any).setScale(minScale); | |
| return scene.tweens.add({ | |
| targets: target, | |
| scaleX: { from: minScale, to: maxScale }, | |
| scaleY: { from: minScale, to: maxScale }, | |
| duration: duration / 2, | |
| yoyo: true, | |
| repeat: -1, | |
| ease: 'Sine.easeInOut', | |
| }); | |
| }; | |
| /** Get screen center coordinates. */ | |
| export const getScreenCenter = ( | |
| scene: Phaser.Scene, | |
| ): { x: number; y: number } => { | |
| return { | |
| x: scene.cameras.main.width / 2, | |
| y: scene.cameras.main.height / 2, | |
| }; | |
| }; | |
| /** Distribute items evenly across a horizontal line. Returns x positions. */ | |
| export const distributeHorizontally = ( | |
| count: number, | |
| totalWidth: number, | |
| padding: number = 0, | |
| ): number[] => { | |
| if (count <= 0) return []; | |
| if (count === 1) return [totalWidth / 2]; | |
| const usableWidth = totalWidth - 2 * padding; | |
| const spacing = usableWidth / (count - 1); | |
| return Array.from({ length: count }, (_, i) => padding + i * spacing); | |
| }; | |