import type { OnitamaScene } from "@/scenes/OnitamaScene"; import { CELL_SIZE, COLORS, createHighlightInnerPulseTween, createHighlightOuterPulseTween, } from "@/config"; export interface HighlightRenderOptions { x: number; y: number; } /** * Renderer for move target highlight visuals * Extracts visual creation logic from HighlightSpawner */ export class HighlightRenderer { constructor(private readonly scene: OnitamaScene) {} /** * Render highlight visuals into a container * @param container - The container to add visuals to * @param options - Highlight rendering options */ render( container: Phaser.GameObjects.Container, options: HighlightRenderOptions, ): void { const { x, y } = options; // Set container position container.setPosition(x, y); // Outer circle (animated pulse) const outerCircle = this.scene.add.circle( 0, 0, CELL_SIZE / 3, COLORS.black, 0.2, ); container.add(outerCircle); // Inner circle const innerCircle = this.scene.add.circle( 0, 0, CELL_SIZE / 4, COLORS.black, 0.4, ); container.add(innerCircle); // Store references for animation container.setData("outerCircle", outerCircle); container.setData("innerCircle", innerCircle); } /** * Create a standalone highlight visual at the specified position * Useful for previews or temporary displays */ createStandalone(x: number, y: number): Phaser.GameObjects.Container { const container = this.scene.add.container(x, y); this.render(container, { x, y }); return container; } /** * Setup pulse animations for highlight circles * @param container - The highlight container */ setupPulseAnimations(container: Phaser.GameObjects.Container): void { const outerCircle = container.getData("outerCircle") as | Phaser.GameObjects.Arc | undefined; const innerCircle = container.getData("innerCircle") as | Phaser.GameObjects.Arc | undefined; if (!outerCircle || !innerCircle) return; // Inner circle pulse createHighlightInnerPulseTween(this.scene, [outerCircle, innerCircle]); // Outer circle staggered pulse createHighlightOuterPulseTween(this.scene, outerCircle); } }