overrun/js/ui/Reticle.js

72 lines
2.3 KiB
JavaScript

// 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';
}
}