// Ring configs: drawn once, rotated each frame const RINGS = [ { radius: 34, segments: 4, gapDeg: 10, lineWidth: 2, color: 0x00ffff, alpha: 0.65, speed: 0.40 }, { radius: 22, segments: 3, gapDeg: 18, lineWidth: 1.5, color: 0x44aaff, alpha: 0.80, speed: -0.85 }, { radius: 12, segments: 6, gapDeg: 8, lineWidth: 1.5, color: 0xffffff, alpha: 0.90, speed: 1.70 }, ]; export class Reticle { constructor(scene) { this.scene = scene; // Hide the native OS cursor over the canvas scene.game.canvas.style.cursor = 'none'; this._angles = RINGS.map(() => 0); // Container holds all rings; drawn in screen-space at high depth this._container = scene.add.container(640, 360).setDepth(200); // Build one Graphics object per ring, drawn once this._ringGfx = RINGS.map(cfg => { const g = scene.add.graphics(); this._drawRing(g, cfg); this._container.add(g); return g; }); // Center: small dot + short crosshair lines (fixed, not rotating) const center = scene.add.graphics(); center.fillStyle(0xffffff, 1); center.fillCircle(0, 0, 2); center.lineStyle(1, 0xffffff, 0.7); const L = 7, GAP = 4; [[-L, 0, -GAP, 0], [GAP, 0, L, 0], [0, -L, 0, -GAP], [0, GAP, 0, L]].forEach(([x1, y1, x2, y2]) => { center.beginPath(); center.moveTo(x1, y1); center.lineTo(x2, y2); center.strokePath(); }); this._container.add(center); } _drawRing(g, { radius, segments, gapDeg, lineWidth, color, alpha }) { g.lineStyle(lineWidth, color, alpha); const gapAngle = Phaser.Math.DegToRad(gapDeg); const arcSpan = (Math.PI * 2 - segments * gapAngle) / segments; for (let i = 0; i < segments; i++) { const start = i * (arcSpan + gapAngle); g.beginPath(); g.arc(0, 0, radius, start, start + arcSpan, false); g.strokePath(); } } /** Call every frame from GameScene.update(), even while frozen. */ update(delta) { const ptr = this.scene.input.activePointer; this._container.setPosition(ptr.x, ptr.y); const dt = delta / 1000; RINGS.forEach((cfg, i) => { this._angles[i] += cfg.speed * dt; this._ringGfx[i].setRotation(this._angles[i]); }); } destroy() { this._container.destroy(); this.scene.game.canvas.style.cursor = 'default'; } }