easter-egg-quest 1.0.22 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -2178,6 +2178,41 @@ class ThreeRenderer {
|
|
|
2178
2178
|
}
|
|
2179
2179
|
}
|
|
2180
2180
|
}
|
|
2181
|
+
burstRhythmParticles(progress, cycles) {
|
|
2182
|
+
if (!this.THREE || !this.scene) return;
|
|
2183
|
+
const T = this.THREE;
|
|
2184
|
+
const burstSize = Math.min(14, 6 + Math.floor(progress * 6) + Math.min(3, Math.floor(cycles)));
|
|
2185
|
+
for (let i = 0; i < burstSize; i++) {
|
|
2186
|
+
const angle = Math.PI * 2 * i / burstSize + (Math.random() - 0.5) * 0.35;
|
|
2187
|
+
const radius = 0.45 + Math.random() * 2.15;
|
|
2188
|
+
const x = Math.cos(angle) * radius;
|
|
2189
|
+
const y = -2.95 - Math.random() * 0.75;
|
|
2190
|
+
const size = 0.036 + Math.random() * 0.038;
|
|
2191
|
+
const geo = this._createMiniEggGeo(T, size);
|
|
2192
|
+
const mat = this._createMiniEggMat(T, 0.18 + Math.random() * 0.12);
|
|
2193
|
+
const particle = new T.Mesh(geo, mat);
|
|
2194
|
+
particle.position.set(x, y, -1 + Math.random() * 0.8);
|
|
2195
|
+
particle.rotation.set(
|
|
2196
|
+
Math.random() * Math.PI,
|
|
2197
|
+
Math.random() * Math.PI,
|
|
2198
|
+
Math.random() * Math.PI
|
|
2199
|
+
);
|
|
2200
|
+
this.scene.add(particle);
|
|
2201
|
+
this._ambientParticles.push({
|
|
2202
|
+
mesh: particle,
|
|
2203
|
+
life: 1.7 + Math.random() * 0.45,
|
|
2204
|
+
vy: 0.85 + Math.random() * 0.65,
|
|
2205
|
+
fadeIn: true
|
|
2206
|
+
});
|
|
2207
|
+
}
|
|
2208
|
+
while (this._ambientParticles.length > 120) {
|
|
2209
|
+
const old = this._ambientParticles.shift();
|
|
2210
|
+
if (!old) break;
|
|
2211
|
+
this.scene.remove(old.mesh);
|
|
2212
|
+
old.mesh.geometry.dispose();
|
|
2213
|
+
old.mesh.material.dispose();
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2181
2216
|
/** Mark all ambient particles for rapid fade-out (rhythm lost). */
|
|
2182
2217
|
fadeOutAmbientParticles() {
|
|
2183
2218
|
for (const p of this._ambientParticles) {
|
|
@@ -4500,6 +4535,7 @@ class ScoringEngine {
|
|
|
4500
4535
|
}
|
|
4501
4536
|
const STORAGE_KEY = "eeq_scores";
|
|
4502
4537
|
const PROGRESS_KEY = "eeq_progress";
|
|
4538
|
+
const COMPLETION_KEY = "eeq_completed";
|
|
4503
4539
|
class Persistence {
|
|
4504
4540
|
constructor(enabled) {
|
|
4505
4541
|
this._enabled = enabled;
|
|
@@ -4572,6 +4608,22 @@ class Persistence {
|
|
|
4572
4608
|
} catch {
|
|
4573
4609
|
}
|
|
4574
4610
|
}
|
|
4611
|
+
markCompleted() {
|
|
4612
|
+
if (!this._enabled) return;
|
|
4613
|
+
try {
|
|
4614
|
+
localStorage.setItem(COMPLETION_KEY, "1");
|
|
4615
|
+
localStorage.removeItem(PROGRESS_KEY);
|
|
4616
|
+
} catch {
|
|
4617
|
+
}
|
|
4618
|
+
}
|
|
4619
|
+
isCompleted() {
|
|
4620
|
+
if (!this._enabled) return false;
|
|
4621
|
+
try {
|
|
4622
|
+
return localStorage.getItem(COMPLETION_KEY) === "1";
|
|
4623
|
+
} catch {
|
|
4624
|
+
return false;
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4575
4627
|
}
|
|
4576
4628
|
class StillnessStage {
|
|
4577
4629
|
constructor(config, script, input, bus) {
|
|
@@ -4841,6 +4893,10 @@ class RhythmStage {
|
|
|
4841
4893
|
if (isGood) {
|
|
4842
4894
|
this._goodCycles++;
|
|
4843
4895
|
this._lastGoodCycleAt = Date.now();
|
|
4896
|
+
this.bus.emit("rhythm:cycle", {
|
|
4897
|
+
progress: Math.min(1, this._goodCycles / requiredCycles),
|
|
4898
|
+
cycles: this._goodCycles
|
|
4899
|
+
});
|
|
4844
4900
|
} else {
|
|
4845
4901
|
this._goodCycles = Math.max(0, this._goodCycles - 0.5);
|
|
4846
4902
|
this._showReaction();
|
|
@@ -5038,7 +5094,6 @@ class PageBreather {
|
|
|
5038
5094
|
this._targetIntensity = 0;
|
|
5039
5095
|
this._rafId = 0;
|
|
5040
5096
|
this._overlay = null;
|
|
5041
|
-
this._label = null;
|
|
5042
5097
|
this._startTime = 0;
|
|
5043
5098
|
this._isUserMoving = false;
|
|
5044
5099
|
this._inSync = false;
|
|
@@ -5059,12 +5114,6 @@ class PageBreather {
|
|
|
5059
5114
|
const opacity = this._intensity * (baseOpacity + syncBonus);
|
|
5060
5115
|
this._overlay.style.opacity = String(Math.min(0.9, opacity));
|
|
5061
5116
|
this._overlay.style.transform = `scale(${1 + wave * (shouldMove ? 0.01 : 0.02)})`;
|
|
5062
|
-
if (this._label) {
|
|
5063
|
-
this._label.textContent = shouldMove ? "In" : "Out";
|
|
5064
|
-
this._label.style.opacity = this._phaseMatch ? "0.98" : "0.78";
|
|
5065
|
-
this._label.style.boxShadow = this._inSync ? "0 0 28px rgba(212,165,80,0.4)" : "0 0 20px rgba(255,255,255,0.08)";
|
|
5066
|
-
this._label.style.borderColor = this._inSync ? "rgba(212,165,80,0.55)" : "rgba(255,255,255,0.12)";
|
|
5067
|
-
}
|
|
5068
5117
|
};
|
|
5069
5118
|
}
|
|
5070
5119
|
start() {
|
|
@@ -5086,29 +5135,6 @@ class PageBreather {
|
|
|
5086
5135
|
].join(";");
|
|
5087
5136
|
document.body.appendChild(el);
|
|
5088
5137
|
this._overlay = el;
|
|
5089
|
-
const label = document.createElement("div");
|
|
5090
|
-
label.style.cssText = [
|
|
5091
|
-
"position:fixed",
|
|
5092
|
-
"left:50%",
|
|
5093
|
-
"top:18%",
|
|
5094
|
-
"transform:translateX(-50%)",
|
|
5095
|
-
"pointer-events:none",
|
|
5096
|
-
"z-index:999981",
|
|
5097
|
-
"padding:8px 14px",
|
|
5098
|
-
"border-radius:999px",
|
|
5099
|
-
"font-family:Georgia, Times New Roman, serif",
|
|
5100
|
-
"font-size:12px",
|
|
5101
|
-
"letter-spacing:0.12em",
|
|
5102
|
-
"text-transform:uppercase",
|
|
5103
|
-
"color:rgba(255,248,232,0.95)",
|
|
5104
|
-
"background:rgba(8,10,18,0.36)",
|
|
5105
|
-
"border:1px solid rgba(255,255,255,0.12)",
|
|
5106
|
-
"box-shadow:0 0 20px rgba(255,255,255,0.08)",
|
|
5107
|
-
"opacity:0.78"
|
|
5108
|
-
].join(";");
|
|
5109
|
-
label.textContent = "In";
|
|
5110
|
-
document.body.appendChild(label);
|
|
5111
|
-
this._label = label;
|
|
5112
5138
|
this._tick();
|
|
5113
5139
|
}
|
|
5114
5140
|
update(accuracy, isMoving, targetPhase, phaseMatch, signal) {
|
|
@@ -5126,14 +5152,12 @@ class PageBreather {
|
|
|
5126
5152
|
return this._inSync;
|
|
5127
5153
|
}
|
|
5128
5154
|
stop() {
|
|
5129
|
-
var _a2
|
|
5155
|
+
var _a2;
|
|
5130
5156
|
if (!this._active) return;
|
|
5131
5157
|
this._active = false;
|
|
5132
5158
|
cancelAnimationFrame(this._rafId);
|
|
5133
5159
|
(_a2 = this._overlay) == null ? void 0 : _a2.remove();
|
|
5134
5160
|
this._overlay = null;
|
|
5135
|
-
(_b2 = this._label) == null ? void 0 : _b2.remove();
|
|
5136
|
-
this._label = null;
|
|
5137
5161
|
this._intensity = 0;
|
|
5138
5162
|
this._targetIntensity = 0;
|
|
5139
5163
|
this._inSync = false;
|
|
@@ -5218,6 +5242,10 @@ class GameController {
|
|
|
5218
5242
|
// ─── Lifecycle ─────────────────────────────────────────────────────────
|
|
5219
5243
|
async init() {
|
|
5220
5244
|
var _a2, _b2;
|
|
5245
|
+
if (this.persistence.isCompleted()) {
|
|
5246
|
+
this._destroyed = true;
|
|
5247
|
+
return;
|
|
5248
|
+
}
|
|
5221
5249
|
this.fsm.onTransition((from, to) => this._onTransition(from, to));
|
|
5222
5250
|
this.bus.on("narrative:show", (text) => {
|
|
5223
5251
|
var _a3;
|
|
@@ -5238,6 +5266,10 @@ class GameController {
|
|
|
5238
5266
|
var _a3;
|
|
5239
5267
|
(_a3 = this.eggRenderer) == null ? void 0 : _a3.addTrail(data.x, data.y, data.velocity);
|
|
5240
5268
|
});
|
|
5269
|
+
this.bus.on("rhythm:cycle", (data) => {
|
|
5270
|
+
if (!this.threeRenderer) return;
|
|
5271
|
+
this.threeRenderer.burstRhythmParticles(data.progress, data.cycles);
|
|
5272
|
+
});
|
|
5241
5273
|
this.bus.on("rhythm:breathe", (data) => {
|
|
5242
5274
|
var _a3, _b3;
|
|
5243
5275
|
(_a3 = this.eggRenderer) == null ? void 0 : _a3.setBreathIntensity(data.accuracy);
|
|
@@ -5248,9 +5280,7 @@ class GameController {
|
|
|
5248
5280
|
data.phaseMatch,
|
|
5249
5281
|
Math.max(data.liveConfidence * 0.55, data.cycleSignal)
|
|
5250
5282
|
);
|
|
5251
|
-
if (data.cycleSignal
|
|
5252
|
-
this.threeRenderer.showProgressParticles(0.35 + Math.max(data.progress, data.cycleSignal) * 0.65, "rhythm");
|
|
5253
|
-
} else if (this.threeRenderer) {
|
|
5283
|
+
if (data.cycleSignal <= 0.12 && this.threeRenderer) {
|
|
5254
5284
|
this.threeRenderer.fadeOutAmbientParticles();
|
|
5255
5285
|
}
|
|
5256
5286
|
});
|
|
@@ -5432,6 +5462,7 @@ class GameController {
|
|
|
5432
5462
|
// ─── Entry ─────────────────────────────────────────────────────────────
|
|
5433
5463
|
async _startEntry() {
|
|
5434
5464
|
var _a2;
|
|
5465
|
+
if (this.persistence.isCompleted()) return;
|
|
5435
5466
|
try {
|
|
5436
5467
|
if (localStorage.getItem("eeq_optout") === "1") return;
|
|
5437
5468
|
} catch {
|
|
@@ -5681,7 +5712,9 @@ class GameController {
|
|
|
5681
5712
|
this.results.show(
|
|
5682
5713
|
score,
|
|
5683
5714
|
() => {
|
|
5715
|
+
this.persistence.markCompleted();
|
|
5684
5716
|
this.destroy();
|
|
5717
|
+
window.location.reload();
|
|
5685
5718
|
}
|
|
5686
5719
|
);
|
|
5687
5720
|
(_c = (_b2 = this.config.callbacks).onComplete) == null ? void 0 : _c.call(_b2, score);
|