refactor(onitama): extract tweens into factory functions

Centralize Onitama animation logic by moving inline Phaser tweens
into a dedicated `tweens.ts` configuration file. This improves
reusability and cleans up spawners and renderers.

Also updated documentation to warn against adding interruptions to
looped tweens to prevent game logic hangs.
This commit is contained in:
2026-04-19 12:45:05 +08:00
parent 3568d99e6e
commit c25759d147
9 changed files with 440 additions and 179 deletions
@@ -1,6 +1,11 @@
import type { OnitamaScene } from "@/scenes/OnitamaScene";
import { CELL_SIZE, COLORS } from "@/config";
import {
CELL_SIZE,
COLORS,
createHighlightInnerPulseTween,
createHighlightOuterPulseTween,
} from "@/config";
export interface HighlightRenderOptions {
x: number;
@@ -78,26 +83,9 @@ export class HighlightRenderer {
if (!outerCircle || !innerCircle) return;
// Inner circle pulse
this.scene.tweens.add({
targets: [outerCircle, innerCircle],
scale: 1.2,
alpha: 0.6,
duration: 600,
ease: "Sine.easeInOut",
yoyo: true,
repeat: -1,
});
createHighlightInnerPulseTween(this.scene, [outerCircle, innerCircle]);
// Outer circle staggered pulse
this.scene.tweens.add({
targets: outerCircle,
scale: 1.3,
alpha: 0.3,
duration: 800,
ease: "Sine.easeInOut",
yoyo: true,
repeat: -1,
delay: 200,
});
createHighlightOuterPulseTween(this.scene, outerCircle);
}
}
@@ -2,7 +2,13 @@ import { GameObjects } from "phaser";
import type { OnitamaScene } from "@/scenes/OnitamaScene";
import { CELL_SIZE, COLORS, ANIMATIONS } from "@/config";
import {
CELL_SIZE,
COLORS,
createSelectionShowTween,
createSelectionRingPulseTween,
createSelectionHideTween,
} from "@/config";
export interface SelectionRenderOptions {
x: number;
@@ -51,23 +57,9 @@ export class SelectionRenderer {
// Fade in animation
// DO NOT add interruption here
// otherwise the game will stop indefinitely
tweens.add({
targets: ring,
alpha: 0.8,
duration: ANIMATIONS.selectionFadeIn,
ease: "Power2",
onComplete: () => {
// Start pulse animation after fade-in completes
pulseTween = tweens.add({
targets: ring,
scale: 1.15,
alpha: 0.6,
duration: ANIMATIONS.selectionPulse,
ease: "Sine.easeInOut",
yoyo: true,
repeat: -1,
});
},
createSelectionShowTween(this.scene, ring, () => {
// Start pulse animation after fade-in completes
pulseTween = createSelectionRingPulseTween(this.scene, ring);
});
// Return cleanup function
@@ -97,17 +89,7 @@ export class SelectionRenderer {
tweens.killTweensOf(ring);
// Fade out animation
tweens.add({
targets: ring,
alpha: 0,
scale: 0.9,
duration: ANIMATIONS.selectionFadeOut,
ease: "Power2",
onComplete: () => {
ring.destroy();
onComplete?.();
},
});
createSelectionHideTween(this.scene, ring, () => onComplete?.());
}
/**