Files
kaltaquise-gamification/sys_digger/atom.js
2026-04-20 14:44:51 +02:00

85 lines
3.0 KiB
JavaScript

class IncomingAtom {
constructor(anchorIndex) {
this.anchorIndex = anchorIndex;
const ap = anchorPoints[anchorIndex];
const far = Math.max(canvas.width, canvas.height) * 0.9;
this.x = CX + Math.cos(ap.angle) * far;
this.y = CY + Math.sin(ap.angle) * far;
this.tx = ap.x;
this.ty = ap.y;
this.speed = ATOM_SPEED_MIN + Math.random() * (ATOM_SPEED_MAX - ATOM_SPEED_MIN);
this.radius = ATOM_RADIUS_MIN + Math.random() * (ATOM_RADIUS_MAX - ATOM_RADIUS_MIN);
this.hue = ATOM_HUE_MIN + Math.random() * ATOM_HUE_RANGE;
this.dead = false;
this.eAngle = Math.random() * Math.PI * 2;
this.eSpeed = ATOM_ELECTRON_SPEED_MIN + Math.random() * (ATOM_ELECTRON_SPEED_MAX - ATOM_ELECTRON_SPEED_MIN);
// ap.active is set once the atom enters the visible screen (see update)
}
update() {
if (this.dead || gameOver) return;
// Activate the anchor the moment the atom becomes visible
const ap = anchorPoints[this.anchorIndex];
if (!ap.active &&
this.x >= 0 && this.x <= canvas.width &&
this.y >= 0 && this.y <= canvas.height) {
ap.active = true;
}
const dx = this.tx - this.x;
const dy = this.ty - this.y;
const dist = Math.hypot(dx, dy);
if (dist < this.speed) {
this.dead = true;
anchorPoints[this.anchorIndex].active = false;
docks++;
document.getElementById('docks-count').textContent = `${docks} / ${MAX_DOCKS} docks`;
updateCystinstein();
burst(this.tx, this.ty, '#ff4444');
if (docks >= MAX_DOCKS) triggerGameOver();
} else {
this.x += (dx / dist) * this.speed;
this.y += (dy / dist) * this.speed;
this.eAngle += this.eSpeed;
}
}
draw() {
if (this.dead) return;
const c = `hsl(${this.hue}, 80%, 60%)`;
const g = ctx.createRadialGradient(this.x, this.y, 0, this.x, this.y, this.radius * 2.5);
g.addColorStop(0, `hsla(${this.hue}, 80%, 60%, 0.4)`);
g.addColorStop(1, 'transparent');
ctx.fillStyle = g;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius * 2.5, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = c;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius * 0.55, 0, Math.PI * 2);
ctx.fill();
ctx.save();
ctx.translate(this.x, this.y);
ctx.strokeStyle = `hsla(${this.hue}, 80%, 70%, 0.35)`;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.ellipse(0, 0, this.radius, this.radius * 0.4, this.eAngle * 0.25, 0, Math.PI * 2);
ctx.stroke();
ctx.fillStyle = '#fff';
ctx.beginPath();
ctx.arc(
Math.cos(this.eAngle) * this.radius,
Math.sin(this.eAngle) * (this.radius * 0.4),
3, 0, Math.PI * 2
);
ctx.fill();
ctx.restore();
}
}