@hypersocial/cli-games 0.1.0 → 0.2.0
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.
- package/README.md +40 -15
- package/dist/cli.js +215 -164
- package/dist/cli.js.map +1 -1
- package/dist/create-NVLKKJX6.js +416 -0
- package/dist/create-NVLKKJX6.js.map +1 -0
- package/dist/index.d.ts +111 -1
- package/dist/index.js +314 -164
- package/dist/index.js.map +1 -1
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -663,7 +663,7 @@ function run2048Game(terminal) {
|
|
|
663
663
|
"\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2582\u2580\u2580\u2588 \u2580\u2580\u2588 \u2584 \u2588\u2580\u2580 \u2580\u2588\u2580",
|
|
664
664
|
"\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2584\u2580\u2580\u2584 \u2580\u2580\u2584 \u2588\u2580\u2584 \u2588\u2588\u2584 \u2588 "
|
|
665
665
|
];
|
|
666
|
-
function
|
|
666
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
667
667
|
for (let i = 0; i < count; i++) {
|
|
668
668
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
669
669
|
const speed = 0.3 + Math.random() * 0.5;
|
|
@@ -683,12 +683,12 @@ function run2048Game(terminal) {
|
|
|
683
683
|
const screenY = gridY * TILE_HEIGHT + TILE_HEIGHT / 2;
|
|
684
684
|
const color = TILE_COLORS[value] || "\x1B[97m";
|
|
685
685
|
const dataChars = ["\u2588", "\u2593", "\u2592", "\u2591", "\u25A0", "\u25A1"];
|
|
686
|
-
|
|
686
|
+
spawnParticles3(screenX, screenY, 8, color, dataChars);
|
|
687
687
|
}
|
|
688
|
-
function
|
|
688
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
689
689
|
scorePopups.push({ x, y, text, frames: 20, color });
|
|
690
690
|
}
|
|
691
|
-
function
|
|
691
|
+
function triggerShake2(frames, intensity) {
|
|
692
692
|
shakeFrames = frames;
|
|
693
693
|
shakeIntensity = intensity;
|
|
694
694
|
}
|
|
@@ -754,7 +754,7 @@ function run2048Game(terminal) {
|
|
|
754
754
|
for (let x = 0; x < GRID_SIZE; x++) {
|
|
755
755
|
if (merged[x] && result[x] > 0) {
|
|
756
756
|
spawnMergeParticles(x, y, result[x]);
|
|
757
|
-
|
|
757
|
+
addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[x]}`, TILE_COLORS[result[x]]);
|
|
758
758
|
}
|
|
759
759
|
}
|
|
760
760
|
grid[y] = result;
|
|
@@ -770,7 +770,7 @@ function run2048Game(terminal) {
|
|
|
770
770
|
for (let x = 0; x < GRID_SIZE; x++) {
|
|
771
771
|
if (finalMerged[x] && finalRow[x] > 0) {
|
|
772
772
|
spawnMergeParticles(x, y, finalRow[x]);
|
|
773
|
-
|
|
773
|
+
addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalRow[x]}`, TILE_COLORS[finalRow[x]]);
|
|
774
774
|
}
|
|
775
775
|
}
|
|
776
776
|
grid[y] = finalRow;
|
|
@@ -785,7 +785,7 @@ function run2048Game(terminal) {
|
|
|
785
785
|
for (let y = 0; y < GRID_SIZE; y++) {
|
|
786
786
|
if (merged[y] && result[y] > 0) {
|
|
787
787
|
spawnMergeParticles(x, y, result[y]);
|
|
788
|
-
|
|
788
|
+
addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${result[y]}`, TILE_COLORS[result[y]]);
|
|
789
789
|
}
|
|
790
790
|
grid[y][x] = result[y];
|
|
791
791
|
}
|
|
@@ -803,7 +803,7 @@ function run2048Game(terminal) {
|
|
|
803
803
|
for (let y = 0; y < GRID_SIZE; y++) {
|
|
804
804
|
if (finalMerged[y] && finalCol[y] > 0) {
|
|
805
805
|
spawnMergeParticles(x, y, finalCol[y]);
|
|
806
|
-
|
|
806
|
+
addScorePopup2(x * TILE_WIDTH + TILE_WIDTH / 2, y * TILE_HEIGHT + 1, `+${finalCol[y]}`, TILE_COLORS[finalCol[y]]);
|
|
807
807
|
}
|
|
808
808
|
grid[y][x] = finalCol[y];
|
|
809
809
|
}
|
|
@@ -812,13 +812,13 @@ function run2048Game(terminal) {
|
|
|
812
812
|
if (anyMoved) {
|
|
813
813
|
score += totalMergeScore;
|
|
814
814
|
if (totalMergeScore > 0) {
|
|
815
|
-
|
|
815
|
+
triggerShake2(4, 1);
|
|
816
816
|
}
|
|
817
817
|
spawnTile();
|
|
818
818
|
if (!won && !continuedAfterWin && has2048()) {
|
|
819
819
|
won = true;
|
|
820
820
|
if (score > highScore) highScore = score;
|
|
821
|
-
|
|
821
|
+
triggerShake2(8, 2);
|
|
822
822
|
for (let y = 0; y < GRID_SIZE; y++) {
|
|
823
823
|
for (let x = 0; x < GRID_SIZE; x++) {
|
|
824
824
|
if (grid[y][x] === 2048) {
|
|
@@ -1320,11 +1320,11 @@ function runAsteroidsGame(terminal) {
|
|
|
1320
1320
|
if (value >= max) return value - max;
|
|
1321
1321
|
return value;
|
|
1322
1322
|
}
|
|
1323
|
-
function
|
|
1323
|
+
function triggerShake2(frames, intensity) {
|
|
1324
1324
|
shakeFrames = frames;
|
|
1325
1325
|
shakeIntensity = intensity;
|
|
1326
1326
|
}
|
|
1327
|
-
function
|
|
1327
|
+
function spawnParticles3(x, y, count, color) {
|
|
1328
1328
|
const chars = ["*", "+", ".", "\xB7"];
|
|
1329
1329
|
for (let i = 0; i < count; i++) {
|
|
1330
1330
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
@@ -1356,8 +1356,8 @@ function runAsteroidsGame(terminal) {
|
|
|
1356
1356
|
function hitShip() {
|
|
1357
1357
|
if (invincibilityFrames > 0) return;
|
|
1358
1358
|
lives--;
|
|
1359
|
-
|
|
1360
|
-
|
|
1359
|
+
spawnParticles3(ship.x, ship.y, 15, "\x1B[91m");
|
|
1360
|
+
triggerShake2(10, 3);
|
|
1361
1361
|
if (lives <= 0) {
|
|
1362
1362
|
gameOver = true;
|
|
1363
1363
|
if (score > highScore) highScore = score;
|
|
@@ -1370,7 +1370,7 @@ function runAsteroidsGame(terminal) {
|
|
|
1370
1370
|
}
|
|
1371
1371
|
}
|
|
1372
1372
|
function splitAsteroid(asteroid) {
|
|
1373
|
-
|
|
1373
|
+
spawnParticles3(asteroid.x, asteroid.y, 8, "\x1B[93m");
|
|
1374
1374
|
score += ASTEROID_SCORES[asteroid.size];
|
|
1375
1375
|
if (asteroid.size === "large") {
|
|
1376
1376
|
for (let i = 0; i < 2; i++) {
|
|
@@ -1438,7 +1438,7 @@ function runAsteroidsGame(terminal) {
|
|
|
1438
1438
|
bullets.splice(j, 1);
|
|
1439
1439
|
splitAsteroid(ast);
|
|
1440
1440
|
asteroids.splice(i, 1);
|
|
1441
|
-
|
|
1441
|
+
triggerShake2(4, 1);
|
|
1442
1442
|
break;
|
|
1443
1443
|
}
|
|
1444
1444
|
}
|
|
@@ -1721,17 +1721,17 @@ function runBreakoutGame(terminal) {
|
|
|
1721
1721
|
];
|
|
1722
1722
|
const brickColors = ["\x1B[1;91m", "\x1B[1;93m", "\x1B[1;92m", "\x1B[1;96m", "\x1B[1;95m"];
|
|
1723
1723
|
const brickPoints = [50, 40, 30, 20, 10];
|
|
1724
|
-
function
|
|
1724
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
1725
1725
|
for (let i = 0; i < count; i++) {
|
|
1726
1726
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
1727
1727
|
const speed = 0.2 + Math.random() * 0.4;
|
|
1728
1728
|
particles.push({ x, y, char: chars[Math.floor(Math.random() * chars.length)], color, vx: Math.cos(angle) * speed, vy: Math.sin(angle) * speed * 0.5, life: 10 + Math.floor(Math.random() * 8) });
|
|
1729
1729
|
}
|
|
1730
1730
|
}
|
|
1731
|
-
function
|
|
1731
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
1732
1732
|
scorePopups.push({ x, y, text, frames: 18, color });
|
|
1733
1733
|
}
|
|
1734
|
-
function
|
|
1734
|
+
function triggerShake2(frames, intensity) {
|
|
1735
1735
|
shakeFrames = frames;
|
|
1736
1736
|
shakeIntensity = intensity;
|
|
1737
1737
|
}
|
|
@@ -1788,7 +1788,7 @@ function runBreakoutGame(terminal) {
|
|
|
1788
1788
|
powerUps.push({ x, y, type: types[Math.floor(Math.random() * types.length)], vy: 0.15 });
|
|
1789
1789
|
}
|
|
1790
1790
|
function applyPowerUp(type) {
|
|
1791
|
-
|
|
1791
|
+
triggerShake2(8, 2);
|
|
1792
1792
|
borderFlash = 15;
|
|
1793
1793
|
switch (type) {
|
|
1794
1794
|
case "multiball": {
|
|
@@ -1801,18 +1801,18 @@ function runBreakoutGame(terminal) {
|
|
|
1801
1801
|
balls.push({ x: src.x, y: src.y, vx: Math.cos(angle) * speed, vy: -Math.abs(Math.sin(angle) * speed), active: true });
|
|
1802
1802
|
}
|
|
1803
1803
|
}
|
|
1804
|
-
|
|
1804
|
+
addScorePopup2(paddleX, GAME_HEIGHT - 5, "MULTI-BALL!", "\x1B[1;96m");
|
|
1805
1805
|
break;
|
|
1806
1806
|
}
|
|
1807
1807
|
case "wide":
|
|
1808
1808
|
paddleWidth = PADDLE_WIDTH_WIDE;
|
|
1809
1809
|
paddleWidthTimer = 600;
|
|
1810
|
-
|
|
1810
|
+
addScorePopup2(paddleX, GAME_HEIGHT - 5, "WIDE PADDLE!", "\x1B[1;92m");
|
|
1811
1811
|
break;
|
|
1812
1812
|
case "laser":
|
|
1813
1813
|
laserActive = true;
|
|
1814
1814
|
laserTimer = 400;
|
|
1815
|
-
|
|
1815
|
+
addScorePopup2(paddleX, GAME_HEIGHT - 5, "LASER!", "\x1B[1;91m");
|
|
1816
1816
|
break;
|
|
1817
1817
|
case "slow":
|
|
1818
1818
|
slowActive = true;
|
|
@@ -1821,11 +1821,11 @@ function runBreakoutGame(terminal) {
|
|
|
1821
1821
|
b.vx *= 0.6;
|
|
1822
1822
|
b.vy *= 0.6;
|
|
1823
1823
|
}
|
|
1824
|
-
|
|
1824
|
+
addScorePopup2(paddleX, GAME_HEIGHT - 5, "SLOW-MO!", "\x1B[1;93m");
|
|
1825
1825
|
break;
|
|
1826
1826
|
case "extra":
|
|
1827
1827
|
lives++;
|
|
1828
|
-
|
|
1828
|
+
addScorePopup2(paddleX, GAME_HEIGHT - 5, "+1 LIFE!", "\x1B[1;95m");
|
|
1829
1829
|
break;
|
|
1830
1830
|
}
|
|
1831
1831
|
}
|
|
@@ -1901,8 +1901,8 @@ function runBreakoutGame(terminal) {
|
|
|
1901
1901
|
brick.alive = false;
|
|
1902
1902
|
const pts = brickPoints[brick.type] || 10;
|
|
1903
1903
|
score += pts;
|
|
1904
|
-
|
|
1905
|
-
|
|
1904
|
+
spawnParticles3(brick.x + brick.width / 2, brick.y, 6, brickColors[brick.type]);
|
|
1905
|
+
addScorePopup2(brick.x + 1, brick.y - 1, `+${pts}`, brickColors[brick.type]);
|
|
1906
1906
|
spawnPowerUp(brick.x + brick.width / 2, brick.y);
|
|
1907
1907
|
}
|
|
1908
1908
|
lasers.splice(i, 1);
|
|
@@ -1923,17 +1923,17 @@ function runBreakoutGame(terminal) {
|
|
|
1923
1923
|
if (ball.x <= 0) {
|
|
1924
1924
|
ball.x = 0;
|
|
1925
1925
|
ball.vx = Math.abs(ball.vx);
|
|
1926
|
-
|
|
1926
|
+
spawnParticles3(0, ball.y, 3, themeColor, ["\xB7", "\u2022"]);
|
|
1927
1927
|
}
|
|
1928
1928
|
if (ball.x >= GAME_WIDTH - 1) {
|
|
1929
1929
|
ball.x = GAME_WIDTH - 1;
|
|
1930
1930
|
ball.vx = -Math.abs(ball.vx);
|
|
1931
|
-
|
|
1931
|
+
spawnParticles3(GAME_WIDTH - 1, ball.y, 3, themeColor, ["\xB7", "\u2022"]);
|
|
1932
1932
|
}
|
|
1933
1933
|
if (ball.y <= 0) {
|
|
1934
1934
|
ball.y = 0;
|
|
1935
1935
|
ball.vy = Math.abs(ball.vy);
|
|
1936
|
-
|
|
1936
|
+
spawnParticles3(ball.x, 0, 3, themeColor, ["\xB7", "\u2022"]);
|
|
1937
1937
|
}
|
|
1938
1938
|
const pL = paddleX - paddleWidth / 2, pR = paddleX + paddleWidth / 2, pY = GAME_HEIGHT - 2;
|
|
1939
1939
|
if (ball.vy > 0 && ball.y >= pY - 0.5 && ball.y <= pY + 0.5 && ball.x >= pL - 0.5 && ball.x <= pR + 0.5) {
|
|
@@ -1944,7 +1944,7 @@ function runBreakoutGame(terminal) {
|
|
|
1944
1944
|
ball.vx = Math.sin(angle) * newSpeed;
|
|
1945
1945
|
ball.vy = -Math.cos(angle) * newSpeed;
|
|
1946
1946
|
ball.y = pY - 1;
|
|
1947
|
-
|
|
1947
|
+
spawnParticles3(ball.x, pY, 4, themeColor, ["\u2726", "\u25CF"]);
|
|
1948
1948
|
}
|
|
1949
1949
|
for (const brick of bricks) {
|
|
1950
1950
|
if (!brick.alive) continue;
|
|
@@ -1964,12 +1964,12 @@ function runBreakoutGame(terminal) {
|
|
|
1964
1964
|
const totalPts = basePts + comboBonus;
|
|
1965
1965
|
score += totalPts;
|
|
1966
1966
|
const intensity = Math.min(comboCount, 8);
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1967
|
+
triggerShake2(3 + intensity, 1 + Math.floor(intensity / 3));
|
|
1968
|
+
spawnParticles3(brick.x + brick.width / 2, brick.y, 6 + intensity, brickColors[brick.type]);
|
|
1969
|
+
addScorePopup2(brick.x + 1, brick.y - 1, comboCount > 1 ? `+${totalPts}!` : `+${totalPts}`, brickColors[brick.type]);
|
|
1970
1970
|
spawnPowerUp(brick.x + brick.width / 2, brick.y);
|
|
1971
1971
|
} else {
|
|
1972
|
-
|
|
1972
|
+
spawnParticles3(ball.x, ball.y, 3, "\x1B[2m" + brickColors[brick.type], ["\xB7", "x"]);
|
|
1973
1973
|
}
|
|
1974
1974
|
break;
|
|
1975
1975
|
}
|
|
@@ -1982,12 +1982,12 @@ function runBreakoutGame(terminal) {
|
|
|
1982
1982
|
if (lives <= 0) {
|
|
1983
1983
|
gameOver = true;
|
|
1984
1984
|
if (score > highScore) highScore = score;
|
|
1985
|
-
|
|
1986
|
-
|
|
1985
|
+
triggerShake2(20, 4);
|
|
1986
|
+
spawnParticles3(paddleX, GAME_HEIGHT - 2, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593"]);
|
|
1987
1987
|
} else {
|
|
1988
1988
|
ballAttached = true;
|
|
1989
1989
|
balls = [{ x: paddleX, y: GAME_HEIGHT - 3, vx: 0, vy: 0, active: true }];
|
|
1990
|
-
|
|
1990
|
+
triggerShake2(10, 2);
|
|
1991
1991
|
}
|
|
1992
1992
|
}
|
|
1993
1993
|
const aliveBricks = bricks.filter((b) => b.alive);
|
|
@@ -1996,8 +1996,8 @@ function runBreakoutGame(terminal) {
|
|
|
1996
1996
|
gameOver = true;
|
|
1997
1997
|
level++;
|
|
1998
1998
|
if (score > highScore) highScore = score;
|
|
1999
|
-
|
|
2000
|
-
for (let i = 0; i < 5; i++) setTimeout(() =>
|
|
1999
|
+
triggerShake2(12, 2);
|
|
2000
|
+
for (let i = 0; i < 5; i++) setTimeout(() => spawnParticles3(Math.random() * GAME_WIDTH, Math.random() * GAME_HEIGHT / 2, 15, brickColors[Math.floor(Math.random() * brickColors.length)], ["\u2605", "\u2726", "\u25C6", "\u25CF", "\u2727"]), i * 100);
|
|
2001
2001
|
}
|
|
2002
2002
|
}
|
|
2003
2003
|
function render() {
|
|
@@ -4005,7 +4005,7 @@ function runCrackGame(terminal) {
|
|
|
4005
4005
|
lng: (Math.random() * 360 - 180).toFixed(6)
|
|
4006
4006
|
};
|
|
4007
4007
|
}
|
|
4008
|
-
function
|
|
4008
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2588", "\u2593", "\u2592", "\u2591", "\u25CF", "\u25C6", "\u2726"]) {
|
|
4009
4009
|
for (let i = 0; i < count; i++) {
|
|
4010
4010
|
particles.push({
|
|
4011
4011
|
x,
|
|
@@ -4018,7 +4018,7 @@ function runCrackGame(terminal) {
|
|
|
4018
4018
|
});
|
|
4019
4019
|
}
|
|
4020
4020
|
}
|
|
4021
|
-
function
|
|
4021
|
+
function addScorePopup2(x, y, text, color) {
|
|
4022
4022
|
scorePopups.push({ x, y, text, frames: 30, color });
|
|
4023
4023
|
}
|
|
4024
4024
|
const controller = {
|
|
@@ -4108,17 +4108,17 @@ function runCrackGame(terminal) {
|
|
|
4108
4108
|
layerBreachFlash = 20;
|
|
4109
4109
|
screenShake = 8;
|
|
4110
4110
|
shakeIntensity = 3;
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4111
|
+
spawnParticles3(effectX, effectY, 25, "\x1B[1;32m", ["\u2588", "\u2593", "\u2726", "\u2605", "\u25C6", "\u25CF"]);
|
|
4112
|
+
spawnParticles3(effectX - 5, effectY, 15, "\x1B[1;92m", ["\u2591", "\u2592", "\u2593"]);
|
|
4113
|
+
spawnParticles3(effectX + 5, effectY, 15, "\x1B[1;92m", ["\u2591", "\u2592", "\u2593"]);
|
|
4114
4114
|
if (currentLayer >= totalLayers) {
|
|
4115
4115
|
won = true;
|
|
4116
4116
|
gameOver = true;
|
|
4117
|
-
|
|
4117
|
+
addScorePopup2(effectX, effectY - 2, "\u25C6 SYSTEM COMPROMISED \u25C6", "\x1B[1;32m");
|
|
4118
4118
|
for (let i = 0; i < 5; i++) {
|
|
4119
4119
|
setTimeout(() => {
|
|
4120
4120
|
if (running) {
|
|
4121
|
-
|
|
4121
|
+
spawnParticles3(
|
|
4122
4122
|
Math.floor(cols / 4) + Math.random() * cols / 2,
|
|
4123
4123
|
5 + Math.random() * 10,
|
|
4124
4124
|
10,
|
|
@@ -4129,7 +4129,7 @@ function runCrackGame(terminal) {
|
|
|
4129
4129
|
}, i * 100);
|
|
4130
4130
|
}
|
|
4131
4131
|
} else {
|
|
4132
|
-
|
|
4132
|
+
addScorePopup2(effectX, effectY - 2, `LAYER ${currentLayer} BREACHED!`, "\x1B[1;32m");
|
|
4133
4133
|
currentLayer++;
|
|
4134
4134
|
setTimeout(() => {
|
|
4135
4135
|
if (running && !gameOver) initLayer();
|
|
@@ -4144,21 +4144,21 @@ function runCrackGame(terminal) {
|
|
|
4144
4144
|
gameOver = true;
|
|
4145
4145
|
gameOverFrame = 0;
|
|
4146
4146
|
generateFakeCoords();
|
|
4147
|
-
|
|
4148
|
-
|
|
4147
|
+
spawnParticles3(effectX, effectY, 20, "\x1B[1;31m", ["\u2588", "\u2593", "\u2592", "!", "@", "#"]);
|
|
4148
|
+
addScorePopup2(effectX, effectY - 2, "\u25C6 TRACED \u25C6", "\x1B[1;31m");
|
|
4149
4149
|
} else if (hasPartial) {
|
|
4150
4150
|
addLog("partial");
|
|
4151
4151
|
correctFlash = 4 + correctCount * 2;
|
|
4152
4152
|
screenShake = Math.min(correctCount + 1, 4);
|
|
4153
4153
|
shakeIntensity = 1;
|
|
4154
4154
|
if (correctCount > 0) {
|
|
4155
|
-
|
|
4156
|
-
|
|
4155
|
+
spawnParticles3(effectX, effectY, 3 + correctCount * 2, "\x1B[1;32m", ["\u2588", "\u25CF", "\u25C6"]);
|
|
4156
|
+
addScorePopup2(effectX, effectY - 1, `${correctCount} EXACT!`, "\x1B[1;32m");
|
|
4157
4157
|
}
|
|
4158
4158
|
if (presentCount > 0) {
|
|
4159
|
-
|
|
4159
|
+
spawnParticles3(effectX + 3, effectY, 2 + presentCount, "\x1B[1;33m", ["\u2591", "\u2592", "\u25CF"]);
|
|
4160
4160
|
if (correctCount === 0) {
|
|
4161
|
-
|
|
4161
|
+
addScorePopup2(effectX, effectY - 1, `${presentCount} CLOSE`, "\x1B[1;33m");
|
|
4162
4162
|
}
|
|
4163
4163
|
}
|
|
4164
4164
|
} else {
|
|
@@ -4166,8 +4166,8 @@ function runCrackGame(terminal) {
|
|
|
4166
4166
|
wrongFlash = 6;
|
|
4167
4167
|
screenShake = 3;
|
|
4168
4168
|
shakeIntensity = 2;
|
|
4169
|
-
|
|
4170
|
-
|
|
4169
|
+
spawnParticles3(effectX, effectY, 5, "\x1B[31m", ["\u2591", "\u2592", "\xD7", "\xB7"]);
|
|
4170
|
+
addScorePopup2(effectX, effectY - 1, "DENIED", "\x1B[2;31m");
|
|
4171
4171
|
}
|
|
4172
4172
|
currentGuess = "";
|
|
4173
4173
|
}
|
|
@@ -4441,7 +4441,7 @@ function runCrackGame(terminal) {
|
|
|
4441
4441
|
borderFlash = 3;
|
|
4442
4442
|
wrongFlash = 3;
|
|
4443
4443
|
if (timeLeft % 2 === 0) {
|
|
4444
|
-
|
|
4444
|
+
spawnParticles3(Math.random() * cols, 2, 3, "\x1B[1;31m", ["!", "\u2593", "\u2591"]);
|
|
4445
4445
|
}
|
|
4446
4446
|
}
|
|
4447
4447
|
if (timeLeft <= 0) {
|
|
@@ -4455,8 +4455,8 @@ function runCrackGame(terminal) {
|
|
|
4455
4455
|
borderFlash = 25;
|
|
4456
4456
|
const centerX = Math.floor(cols / 2);
|
|
4457
4457
|
const centerY = Math.floor(rows / 2);
|
|
4458
|
-
|
|
4459
|
-
|
|
4458
|
+
spawnParticles3(centerX, centerY, 30, "\x1B[1;31m", ["\u2588", "\u2593", "\u2592", "!", "@", "#", "\xD7"]);
|
|
4459
|
+
addScorePopup2(centerX, centerY - 3, "\u25C6\u25C6 TRACE COMPLETE \u25C6\u25C6", "\x1B[1;31m");
|
|
4460
4460
|
}
|
|
4461
4461
|
}
|
|
4462
4462
|
if (gameOver) {
|
|
@@ -4603,7 +4603,7 @@ function runCrackGame(terminal) {
|
|
|
4603
4603
|
currentGuess += key.toUpperCase();
|
|
4604
4604
|
const inputX = 4 + currentGuess.length * 2;
|
|
4605
4605
|
const inputY = 12 + guesses.length;
|
|
4606
|
-
|
|
4606
|
+
spawnParticles3(inputX, inputY, 1, themeColor, ["\xB7", "\u25CF"]);
|
|
4607
4607
|
if (currentGuess.length === 5) {
|
|
4608
4608
|
screenShake = 2;
|
|
4609
4609
|
shakeIntensity = 1;
|
|
@@ -4691,7 +4691,7 @@ function runFroggerGame(terminal) {
|
|
|
4691
4691
|
"\u2588\u2580\u2580 \u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588\u2580\u2588",
|
|
4692
4692
|
"\u2588\u2580 \u2588\u2580\u2584 \u2588\u2584\u2588 \u2588\u2584\u2588 \u2588\u2584\u2588 \u2588\u2588\u2584 \u2588\u2580\u2584"
|
|
4693
4693
|
];
|
|
4694
|
-
function
|
|
4694
|
+
function spawnParticles3(x, y, count, color, chars) {
|
|
4695
4695
|
for (let i = 0; i < count; i++) {
|
|
4696
4696
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
4697
4697
|
const speed = 0.1 + Math.random() * 0.15;
|
|
@@ -4708,13 +4708,13 @@ function runFroggerGame(terminal) {
|
|
|
4708
4708
|
}
|
|
4709
4709
|
}
|
|
4710
4710
|
function spawnSplash2(x, y) {
|
|
4711
|
-
|
|
4711
|
+
spawnParticles3(x, y, 8, "\x1B[96m", ["~", "\u223C", "\u2248", "\u25CB"]);
|
|
4712
4712
|
}
|
|
4713
4713
|
function spawnCrash(x, y) {
|
|
4714
|
-
|
|
4714
|
+
spawnParticles3(x, y, 10, "\x1B[91m", ["*", "x", "\xD7", "#"]);
|
|
4715
4715
|
}
|
|
4716
4716
|
function spawnSuccess(x, y) {
|
|
4717
|
-
|
|
4717
|
+
spawnParticles3(x, y, 12, "\x1B[92m", ["*", "+", "\u2666", "\u25C7"]);
|
|
4718
4718
|
}
|
|
4719
4719
|
function calculateLilyPads() {
|
|
4720
4720
|
lilyPadX = [];
|
|
@@ -5520,7 +5520,7 @@ function runHangmanGame(terminal) {
|
|
|
5520
5520
|
winAnimation = 0;
|
|
5521
5521
|
loseAnimation = 0;
|
|
5522
5522
|
}
|
|
5523
|
-
function
|
|
5523
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
5524
5524
|
for (let i = 0; i < count; i++) {
|
|
5525
5525
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
5526
5526
|
const speed = 0.3 + Math.random() * 0.5;
|
|
@@ -5535,7 +5535,7 @@ function runHangmanGame(terminal) {
|
|
|
5535
5535
|
});
|
|
5536
5536
|
}
|
|
5537
5537
|
}
|
|
5538
|
-
function
|
|
5538
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
5539
5539
|
scorePopups.push({ x, y, text, frames: 22, color });
|
|
5540
5540
|
}
|
|
5541
5541
|
function getDisplayWord() {
|
|
@@ -5562,12 +5562,12 @@ function runHangmanGame(terminal) {
|
|
|
5562
5562
|
screenShake = 2 + Math.floor(effectIntensity / 2);
|
|
5563
5563
|
const centerX = Math.floor(terminal.cols / 2);
|
|
5564
5564
|
const wordY = gameTop + 9;
|
|
5565
|
-
|
|
5565
|
+
spawnParticles3(centerX, wordY, 4 + effectIntensity, "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
|
|
5566
5566
|
const popupText = letterCount > 1 ? `+${points}!` : `+${points}`;
|
|
5567
5567
|
const popupColor = correctStreak >= 3 ? "\x1B[1;93m" : "\x1B[1;92m";
|
|
5568
|
-
|
|
5568
|
+
addScorePopup2(centerX - 2, wordY - 2, popupText, popupColor);
|
|
5569
5569
|
if (correctStreak >= 3) {
|
|
5570
|
-
|
|
5570
|
+
addScorePopup2(centerX - 4, wordY - 4, `${correctStreak}x STREAK!`, "\x1B[1;96m");
|
|
5571
5571
|
}
|
|
5572
5572
|
if (checkWin()) {
|
|
5573
5573
|
won = true;
|
|
@@ -5578,9 +5578,9 @@ function runHangmanGame(terminal) {
|
|
|
5578
5578
|
score += bonus;
|
|
5579
5579
|
winAnimation = 30;
|
|
5580
5580
|
screenShake = 8;
|
|
5581
|
-
|
|
5581
|
+
spawnParticles3(centerX, wordY, 15, "\x1B[1;93m", ["\u2605", "\u2726", "\u2666", "\u25C6", "\u25CF"]);
|
|
5582
5582
|
if (bonus > 0) {
|
|
5583
|
-
|
|
5583
|
+
addScorePopup2(centerX - 3, wordY + 2, `+${bonus} BONUS!`, "\x1B[1;93m");
|
|
5584
5584
|
}
|
|
5585
5585
|
}
|
|
5586
5586
|
} else {
|
|
@@ -5590,14 +5590,14 @@ function runHangmanGame(terminal) {
|
|
|
5590
5590
|
screenShake = 4 + wrongGuesses;
|
|
5591
5591
|
const hangmanX = gameLeft + 6;
|
|
5592
5592
|
const hangmanY = gameTop + 4;
|
|
5593
|
-
|
|
5593
|
+
spawnParticles3(hangmanX, hangmanY, 5, "\x1B[1;91m", ["\u2717", "\xD7", "\xB7", "\u25CB"]);
|
|
5594
5594
|
if (wrongGuesses >= MAX_WRONG) {
|
|
5595
5595
|
gameOver = true;
|
|
5596
5596
|
streak = 0;
|
|
5597
5597
|
loseAnimation = 40;
|
|
5598
5598
|
screenShake = 20;
|
|
5599
|
-
|
|
5600
|
-
|
|
5599
|
+
spawnParticles3(hangmanX, hangmanY, 12, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2592", "\u2591"]);
|
|
5600
|
+
addScorePopup2(hangmanX - 3, hangmanY - 2, "FAILED!", "\x1B[1;91m");
|
|
5601
5601
|
}
|
|
5602
5602
|
}
|
|
5603
5603
|
}
|
|
@@ -5953,7 +5953,7 @@ function runMinesweeperGame(terminal) {
|
|
|
5953
5953
|
"\u2588\u2584 \u2584\u2588 \u2588 \u2588\u2584 \u2588 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588 \u2588 \u2588 \u2588\u2580\u2580 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588",
|
|
5954
5954
|
"\u2588 \u2580 \u2588 \u2588 \u2588 \u2580\u2588 \u2588\u2588\u2584 \u2584\u2584\u2588 \u2580\u2584\u2580\u2584\u2580 \u2588\u2588\u2584 \u2588\u2588\u2584 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584"
|
|
5955
5955
|
];
|
|
5956
|
-
function
|
|
5956
|
+
function spawnParticles3(x, y, count, color, chars = ["*", "+", ".", "o"]) {
|
|
5957
5957
|
for (let i = 0; i < count; i++) {
|
|
5958
5958
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
5959
5959
|
const speed = 0.2 + Math.random() * 0.4;
|
|
@@ -5985,10 +5985,10 @@ function runMinesweeperGame(terminal) {
|
|
|
5985
5985
|
});
|
|
5986
5986
|
}
|
|
5987
5987
|
}
|
|
5988
|
-
function
|
|
5988
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
5989
5989
|
scorePopups.push({ x, y, text, frames: 20, color });
|
|
5990
5990
|
}
|
|
5991
|
-
function
|
|
5991
|
+
function triggerShake2(frames, intensity) {
|
|
5992
5992
|
shakeFrames = frames;
|
|
5993
5993
|
shakeIntensity = intensity;
|
|
5994
5994
|
}
|
|
@@ -6075,14 +6075,14 @@ function runMinesweeperGame(terminal) {
|
|
|
6075
6075
|
if (cell.isMine) {
|
|
6076
6076
|
gameOver = true;
|
|
6077
6077
|
won = false;
|
|
6078
|
-
|
|
6078
|
+
triggerShake2(25, 4);
|
|
6079
6079
|
spawnExplosion(x * 2 + 1, y);
|
|
6080
|
-
|
|
6080
|
+
addScorePopup2(x * 2, y - 1, "MALWARE!", "\x1B[1;91m");
|
|
6081
6081
|
revealAllMines();
|
|
6082
6082
|
return;
|
|
6083
6083
|
}
|
|
6084
6084
|
if (!isChain) {
|
|
6085
|
-
|
|
6085
|
+
spawnParticles3(x * 2 + 1, y, 4, themeColor, [".", "*", "+"]);
|
|
6086
6086
|
}
|
|
6087
6087
|
if (cell.adjacentMines === 0) {
|
|
6088
6088
|
for (let dy = -1; dy <= 1; dy++) {
|
|
@@ -6105,7 +6105,7 @@ function runMinesweeperGame(terminal) {
|
|
|
6105
6105
|
cell.isFlagged = !cell.isFlagged;
|
|
6106
6106
|
if (cell.isFlagged) {
|
|
6107
6107
|
flagsPlaced++;
|
|
6108
|
-
|
|
6108
|
+
spawnParticles3(x * 2 + 1, y, 3, "\x1B[1;93m", ["!", "^", "*"]);
|
|
6109
6109
|
} else {
|
|
6110
6110
|
flagsPlaced--;
|
|
6111
6111
|
}
|
|
@@ -6124,13 +6124,13 @@ function runMinesweeperGame(terminal) {
|
|
|
6124
6124
|
if (cellsRevealed >= totalNonMines) {
|
|
6125
6125
|
gameOver = true;
|
|
6126
6126
|
won = true;
|
|
6127
|
-
|
|
6127
|
+
triggerShake2(10, 2);
|
|
6128
6128
|
for (let i = 0; i < 5; i++) {
|
|
6129
6129
|
const x = Math.floor(Math.random() * difficulty.width);
|
|
6130
6130
|
const y = Math.floor(Math.random() * difficulty.height);
|
|
6131
|
-
|
|
6131
|
+
spawnParticles3(x * 2 + 1, y, 6, "\x1B[1;92m", ["*", "+", "#"]);
|
|
6132
6132
|
}
|
|
6133
|
-
|
|
6133
|
+
addScorePopup2(difficulty.width, difficulty.height / 2, "GRID SECURE!", "\x1B[1;92m");
|
|
6134
6134
|
}
|
|
6135
6135
|
}
|
|
6136
6136
|
function update() {
|
|
@@ -6600,7 +6600,7 @@ function runPongGame(terminal) {
|
|
|
6600
6600
|
rallyCount = 0;
|
|
6601
6601
|
wallHitFlash = 0;
|
|
6602
6602
|
}
|
|
6603
|
-
function
|
|
6603
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
6604
6604
|
for (let i = 0; i < count; i++) {
|
|
6605
6605
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
6606
6606
|
const speed = 0.2 + Math.random() * 0.4;
|
|
@@ -6615,7 +6615,7 @@ function runPongGame(terminal) {
|
|
|
6615
6615
|
});
|
|
6616
6616
|
}
|
|
6617
6617
|
}
|
|
6618
|
-
function
|
|
6618
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
6619
6619
|
scorePopups.push({ x, y, text, frames: 20, color });
|
|
6620
6620
|
}
|
|
6621
6621
|
function createGoalExplosion(side) {
|
|
@@ -6868,7 +6868,7 @@ function runPongGame(terminal) {
|
|
|
6868
6868
|
ballVY = -ballVY;
|
|
6869
6869
|
ballY = Math.max(0, Math.min(GAME_HEIGHT - 1, ballY));
|
|
6870
6870
|
wallHitFlash = 6;
|
|
6871
|
-
|
|
6871
|
+
spawnParticles3(ballX, ballY <= 0 ? 1 : GAME_HEIGHT - 2, 4, "\x1B[1;93m", ["\xB7", "\u2022", "\u25CB"]);
|
|
6872
6872
|
}
|
|
6873
6873
|
if (ballX <= PADDLE_OFFSET + 1 && ballX >= PADDLE_OFFSET) {
|
|
6874
6874
|
if (ballY >= playerY && ballY <= playerY + PADDLE_HEIGHT) {
|
|
@@ -6883,9 +6883,9 @@ function runPongGame(terminal) {
|
|
|
6883
6883
|
const effectIntensity = Math.min(rallyCount, 10);
|
|
6884
6884
|
paddleHitFlash = 8;
|
|
6885
6885
|
if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);
|
|
6886
|
-
|
|
6886
|
+
spawnParticles3(PADDLE_OFFSET + 2, ballY, 4 + Math.floor(effectIntensity / 2), themeColor, ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
|
|
6887
6887
|
if (rallyCount >= 3 && rallyCount % 3 === 0) {
|
|
6888
|
-
|
|
6888
|
+
addScorePopup2(PADDLE_OFFSET + 4, ballY - 1, `${rallyCount}!`, "\x1B[1;96m");
|
|
6889
6889
|
}
|
|
6890
6890
|
}
|
|
6891
6891
|
}
|
|
@@ -6902,9 +6902,9 @@ function runPongGame(terminal) {
|
|
|
6902
6902
|
const effectIntensity = Math.min(rallyCount, 10);
|
|
6903
6903
|
paddleHitFlash = 8;
|
|
6904
6904
|
if (rallyCount >= 5) screenShake = Math.floor(effectIntensity / 4);
|
|
6905
|
-
|
|
6905
|
+
spawnParticles3(GAME_WIDTH - PADDLE_OFFSET - 2, ballY, 4 + Math.floor(effectIntensity / 2), "\x1B[1;91m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
|
|
6906
6906
|
if (rallyCount >= 3 && rallyCount % 3 === 0) {
|
|
6907
|
-
|
|
6907
|
+
addScorePopup2(GAME_WIDTH - PADDLE_OFFSET - 6, ballY - 1, `${rallyCount}!`, "\x1B[1;91m");
|
|
6908
6908
|
}
|
|
6909
6909
|
}
|
|
6910
6910
|
}
|
|
@@ -6916,13 +6916,13 @@ function runPongGame(terminal) {
|
|
|
6916
6916
|
screenShake = 8;
|
|
6917
6917
|
goalFlashSide = "left";
|
|
6918
6918
|
createGoalExplosion("left");
|
|
6919
|
-
|
|
6920
|
-
|
|
6919
|
+
addScorePopup2(GAME_WIDTH / 2 - 3, GAME_HEIGHT / 2 - 2, "CPU +1", "\x1B[1;91m");
|
|
6920
|
+
spawnParticles3(2, ballY, 10, "\x1B[1;91m", ["\u2717", "\xD7", "\u2592", "\u2591"]);
|
|
6921
6921
|
if (aiScore >= WIN_SCORE) {
|
|
6922
6922
|
gameOver = true;
|
|
6923
6923
|
scoreFreeze = 0;
|
|
6924
6924
|
screenShake = 15;
|
|
6925
|
-
|
|
6925
|
+
spawnParticles3(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593"]);
|
|
6926
6926
|
} else {
|
|
6927
6927
|
resetBall(true);
|
|
6928
6928
|
}
|
|
@@ -6935,13 +6935,13 @@ function runPongGame(terminal) {
|
|
|
6935
6935
|
goalFlashSide = "right";
|
|
6936
6936
|
createGoalExplosion("right");
|
|
6937
6937
|
const rallyBonus = rallyCount >= 5 ? ` (${rallyCount} rally!)` : "";
|
|
6938
|
-
|
|
6939
|
-
|
|
6938
|
+
addScorePopup2(GAME_WIDTH / 2 - 2, GAME_HEIGHT / 2 - 2, `+1${rallyBonus}`, "\x1B[1;92m");
|
|
6939
|
+
spawnParticles3(GAME_WIDTH - 3, ballY, 10, "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
|
|
6940
6940
|
if (playerScore >= WIN_SCORE) {
|
|
6941
6941
|
gameOver = true;
|
|
6942
6942
|
scoreFreeze = 0;
|
|
6943
6943
|
screenShake = 15;
|
|
6944
|
-
|
|
6944
|
+
spawnParticles3(GAME_WIDTH / 2, GAME_HEIGHT / 2, 20, "\x1B[1;93m", ["\u2605", "\u2726", "\u2666", "\u25C6"]);
|
|
6945
6945
|
} else {
|
|
6946
6946
|
resetBall(false);
|
|
6947
6947
|
}
|
|
@@ -7174,7 +7174,7 @@ function runRunnerGame(terminal) {
|
|
|
7174
7174
|
const factor = Math.pow(t, 0.6);
|
|
7175
7175
|
return Math.floor(ROAD_WIDTH_TOP + (ROAD_WIDTH_BOTTOM - ROAD_WIDTH_TOP) * factor);
|
|
7176
7176
|
}
|
|
7177
|
-
function
|
|
7177
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
7178
7178
|
for (let i = 0; i < count; i++) {
|
|
7179
7179
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
7180
7180
|
const speed2 = 0.3 + Math.random() * 0.5;
|
|
@@ -7189,7 +7189,7 @@ function runRunnerGame(terminal) {
|
|
|
7189
7189
|
});
|
|
7190
7190
|
}
|
|
7191
7191
|
}
|
|
7192
|
-
function
|
|
7192
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
7193
7193
|
scorePopups.push({ x, y, text, frames: 20, color });
|
|
7194
7194
|
}
|
|
7195
7195
|
function initGame() {
|
|
@@ -7312,8 +7312,8 @@ function runRunnerGame(terminal) {
|
|
|
7312
7312
|
const roadLeft = centerX - Math.floor(roadWidth / 2);
|
|
7313
7313
|
const coinX = roadLeft + Math.floor((coin.lane + 0.5) / LANES * roadWidth);
|
|
7314
7314
|
const coinY = gameTop + TRACK_HEIGHT - Math.floor(coin.y);
|
|
7315
|
-
|
|
7316
|
-
|
|
7315
|
+
spawnParticles3(coinX - gameLeft, coinY - gameTop, 6, "\x1B[1;93m", ["\u25C6", "\u2605", "\u25CF", "\u2666"]);
|
|
7316
|
+
addScorePopup2(coinX, coinY, `+${points}`, "\x1B[1;93m");
|
|
7317
7317
|
} else {
|
|
7318
7318
|
newCoins.push(coin);
|
|
7319
7319
|
}
|
|
@@ -7703,7 +7703,7 @@ function runRunnerGame(terminal) {
|
|
|
7703
7703
|
const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);
|
|
7704
7704
|
const roadLeft = centerX - Math.floor(roadWidth / 2);
|
|
7705
7705
|
const playerCenter = roadLeft + Math.floor((playerLane + 0.5) / LANES * roadWidth);
|
|
7706
|
-
|
|
7706
|
+
spawnParticles3(playerCenter - gameLeft, TRACK_HEIGHT - 2, 4, "\x1B[96m", ["\u2726", "\u2605", "\u25C7"]);
|
|
7707
7707
|
}
|
|
7708
7708
|
collectCoins();
|
|
7709
7709
|
if (checkCollision()) {
|
|
@@ -7716,7 +7716,7 @@ function runRunnerGame(terminal) {
|
|
|
7716
7716
|
const roadWidth = getRoadWidth(TRACK_HEIGHT - 1);
|
|
7717
7717
|
const roadLeft = centerX - Math.floor(roadWidth / 2);
|
|
7718
7718
|
const playerCenter = roadLeft + Math.floor((playerLane + 0.5) / LANES * roadWidth);
|
|
7719
|
-
|
|
7719
|
+
spawnParticles3(playerCenter - gameLeft, TRACK_HEIGHT - 1, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593", "\u2591"]);
|
|
7720
7720
|
return;
|
|
7721
7721
|
}
|
|
7722
7722
|
distance += 0.18 * speed;
|
|
@@ -7950,7 +7950,7 @@ function runSimonGame(terminal) {
|
|
|
7950
7950
|
"\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588 \u2588\u2580\u2580\u2588 \u2580\u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2580\u2588",
|
|
7951
7951
|
"\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2584\u2584\u2588 \u2588 \u2588\u2588\u2584 \u2588 \u2588 \u2588 \u2588\u2580\u2584 \u2588 \u2588"
|
|
7952
7952
|
];
|
|
7953
|
-
function
|
|
7953
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
7954
7954
|
for (let i = 0; i < count; i++) {
|
|
7955
7955
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
7956
7956
|
const speed = 0.3 + Math.random() * 0.5;
|
|
@@ -7985,12 +7985,12 @@ function runSimonGame(terminal) {
|
|
|
7985
7985
|
x = centerX - offset * 2;
|
|
7986
7986
|
break;
|
|
7987
7987
|
}
|
|
7988
|
-
|
|
7988
|
+
spawnParticles3(x, y, 8, QUADRANT_COLORS[quadrant], ["\u2726", "\u2605", "\u25C6", "\u25CF"]);
|
|
7989
7989
|
}
|
|
7990
|
-
function
|
|
7990
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
7991
7991
|
scorePopups.push({ x, y, text, frames: 20, color });
|
|
7992
7992
|
}
|
|
7993
|
-
function
|
|
7993
|
+
function triggerShake2(frames, intensity) {
|
|
7994
7994
|
shakeFrames = frames;
|
|
7995
7995
|
shakeIntensity = intensity;
|
|
7996
7996
|
}
|
|
@@ -8047,12 +8047,12 @@ function runSimonGame(terminal) {
|
|
|
8047
8047
|
score += currentRound * 10;
|
|
8048
8048
|
const centerX = GAME_WIDTH / 2;
|
|
8049
8049
|
const centerY = GAME_HEIGHT / 2;
|
|
8050
|
-
|
|
8051
|
-
|
|
8050
|
+
addScorePopup2(centerX - 2, centerY - 2, `+${currentRound * 10}`, "\x1B[1;92m");
|
|
8051
|
+
spawnParticles3(centerX, centerY, 20, "\x1B[1;92m", ["\u2726", "\u2605", "\u2606", "\u25C8"]);
|
|
8052
8052
|
statusMessage = "PATTERN ACCEPTED";
|
|
8053
8053
|
statusColor = "\x1B[1;92m";
|
|
8054
8054
|
statusBlink = true;
|
|
8055
|
-
|
|
8055
|
+
triggerShake2(6, 1);
|
|
8056
8056
|
}
|
|
8057
8057
|
} else {
|
|
8058
8058
|
phase = "failure";
|
|
@@ -8064,10 +8064,10 @@ function runSimonGame(terminal) {
|
|
|
8064
8064
|
statusMessage = "ACCESS DENIED";
|
|
8065
8065
|
statusColor = "\x1B[1;91m";
|
|
8066
8066
|
statusBlink = true;
|
|
8067
|
-
|
|
8067
|
+
triggerShake2(15, 3);
|
|
8068
8068
|
const centerX = GAME_WIDTH / 2;
|
|
8069
8069
|
const centerY = GAME_HEIGHT / 2;
|
|
8070
|
-
|
|
8070
|
+
spawnParticles3(centerX, centerY, 15, "\x1B[1;91m", ["\u2717", "\u2716", "\xD7", "\u2573"]);
|
|
8071
8071
|
}
|
|
8072
8072
|
}
|
|
8073
8073
|
function update() {
|
|
@@ -8545,7 +8545,7 @@ function runSnakeGame(terminal) {
|
|
|
8545
8545
|
attempts++;
|
|
8546
8546
|
} while (snake.some((s) => s.x === food.x && s.y === food.y) && attempts < 100);
|
|
8547
8547
|
}
|
|
8548
|
-
function
|
|
8548
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
8549
8549
|
for (let i = 0; i < count; i++) {
|
|
8550
8550
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
8551
8551
|
const speed = 0.3 + Math.random() * 0.4;
|
|
@@ -8561,7 +8561,7 @@ function runSnakeGame(terminal) {
|
|
|
8561
8561
|
});
|
|
8562
8562
|
}
|
|
8563
8563
|
}
|
|
8564
|
-
function
|
|
8564
|
+
function updateParticles3() {
|
|
8565
8565
|
for (let i = particles.length - 1; i >= 0; i--) {
|
|
8566
8566
|
const p = particles[i];
|
|
8567
8567
|
p.x += p.vx;
|
|
@@ -8586,7 +8586,7 @@ function runSnakeGame(terminal) {
|
|
|
8586
8586
|
scorePopup.y -= 0.3;
|
|
8587
8587
|
if (scorePopup.frames <= 0) scorePopup = null;
|
|
8588
8588
|
}
|
|
8589
|
-
|
|
8589
|
+
updateParticles3();
|
|
8590
8590
|
let renderGameLeft = gameLeft;
|
|
8591
8591
|
let renderGameTop = gameTop;
|
|
8592
8592
|
if (shakeFrames > 0) {
|
|
@@ -8737,7 +8737,7 @@ function runSnakeGame(terminal) {
|
|
|
8737
8737
|
shakeFrames = 20;
|
|
8738
8738
|
shakeIntensity = 3;
|
|
8739
8739
|
deathFlashFrames = 30;
|
|
8740
|
-
|
|
8740
|
+
spawnParticles3(snake[0].x, snake[0].y, 12, "\x1B[1;31m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
|
|
8741
8741
|
comboCount = 0;
|
|
8742
8742
|
return;
|
|
8743
8743
|
}
|
|
@@ -8747,7 +8747,7 @@ function runSnakeGame(terminal) {
|
|
|
8747
8747
|
shakeFrames = 20;
|
|
8748
8748
|
shakeIntensity = 3;
|
|
8749
8749
|
deathFlashFrames = 30;
|
|
8750
|
-
|
|
8750
|
+
spawnParticles3(snake[0].x, snake[0].y, 12, "\x1B[1;31m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
|
|
8751
8751
|
comboCount = 0;
|
|
8752
8752
|
return;
|
|
8753
8753
|
}
|
|
@@ -8775,7 +8775,7 @@ function runSnakeGame(terminal) {
|
|
|
8775
8775
|
frames: 20
|
|
8776
8776
|
};
|
|
8777
8777
|
const particleCount = 4 + Math.min(comboCount * 2, 10);
|
|
8778
|
-
|
|
8778
|
+
spawnParticles3(food.x, food.y, particleCount, "\x1B[1;33m", ["\u2726", "\u2605", "\u25C6", "\u2666"]);
|
|
8779
8779
|
spawnFood();
|
|
8780
8780
|
} else {
|
|
8781
8781
|
snake.pop();
|
|
@@ -9000,7 +9000,7 @@ function runSpaceInvadersGame(terminal) {
|
|
|
9000
9000
|
["|=|", "|#|"]
|
|
9001
9001
|
// Type 2 - top rows
|
|
9002
9002
|
];
|
|
9003
|
-
function
|
|
9003
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
9004
9004
|
for (let i = 0; i < count; i++) {
|
|
9005
9005
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
9006
9006
|
const speed = 0.2 + Math.random() * 0.4;
|
|
@@ -9015,7 +9015,7 @@ function runSpaceInvadersGame(terminal) {
|
|
|
9015
9015
|
});
|
|
9016
9016
|
}
|
|
9017
9017
|
}
|
|
9018
|
-
function
|
|
9018
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
9019
9019
|
scorePopups.push({ x, y, text, frames: 18, color });
|
|
9020
9020
|
}
|
|
9021
9021
|
function initGame() {
|
|
@@ -9340,10 +9340,10 @@ function runSpaceInvadersGame(terminal) {
|
|
|
9340
9340
|
shakeFrames = 3 + Math.min(killStreakCount, 5);
|
|
9341
9341
|
shakeIntensity = 1 + Math.floor(killStreakCount / 3);
|
|
9342
9342
|
const invaderColors = ["\x1B[1;92m", "\x1B[1;93m", "\x1B[1;95m"];
|
|
9343
|
-
|
|
9343
|
+
spawnParticles3(invader.x + 1, invader.y, 6 + Math.min(killStreakCount, 6), invaderColors[invader.type], ["\u2726", "\u2605", "\u25C6", "\xD7"]);
|
|
9344
9344
|
const popupText = killStreakCount >= 3 ? `+${totalScore}!` : `+${totalScore}`;
|
|
9345
9345
|
const popupColor = killStreakCount >= 3 ? "\x1B[1;91m" : "\x1B[1;93m";
|
|
9346
|
-
|
|
9346
|
+
addScorePopup2(invader.x + 1, invader.y - 1, popupText, popupColor);
|
|
9347
9347
|
}
|
|
9348
9348
|
}
|
|
9349
9349
|
}
|
|
@@ -9371,13 +9371,13 @@ function runSpaceInvadersGame(terminal) {
|
|
|
9371
9371
|
shakeIntensity = 3;
|
|
9372
9372
|
hitFlashFrames = 15;
|
|
9373
9373
|
killStreakCount = 0;
|
|
9374
|
-
|
|
9374
|
+
spawnParticles3(Math.floor(playerX), playerY, 10, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2592"]);
|
|
9375
9375
|
if (lives <= 0) {
|
|
9376
9376
|
gameOver = true;
|
|
9377
9377
|
gameOverFlashFrames = 30;
|
|
9378
9378
|
shakeFrames = 20;
|
|
9379
9379
|
shakeIntensity = 4;
|
|
9380
|
-
|
|
9380
|
+
spawnParticles3(Math.floor(playerX), playerY, 15, "\x1B[1;91m", ["\u2717", "\u2620", "\xD7", "\u2593", "\u2591"]);
|
|
9381
9381
|
if (score > highScore) highScore = score;
|
|
9382
9382
|
}
|
|
9383
9383
|
}
|
|
@@ -10356,7 +10356,7 @@ function runTowerGame(terminal) {
|
|
|
10356
10356
|
"\u2580\u2588\u2580 \u2588\u2580\u2588 \u2588 \u2588 \u2588 \u2588\u2580\u2580 \u2588\u2580\u2588",
|
|
10357
10357
|
" \u2588 \u2588\u2584\u2588 \u2580\u2584\u2580\u2584\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584"
|
|
10358
10358
|
];
|
|
10359
|
-
function
|
|
10359
|
+
function spawnParticles3(x, y, count, color) {
|
|
10360
10360
|
const chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"];
|
|
10361
10361
|
for (let i = 0; i < count; i++) {
|
|
10362
10362
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
@@ -10383,10 +10383,10 @@ function runTowerGame(terminal) {
|
|
|
10383
10383
|
vy: 0.1
|
|
10384
10384
|
});
|
|
10385
10385
|
}
|
|
10386
|
-
function
|
|
10386
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
10387
10387
|
scorePopups.push({ x, y, text, frames: 24, color });
|
|
10388
10388
|
}
|
|
10389
|
-
function
|
|
10389
|
+
function triggerShake2(frames, intensity) {
|
|
10390
10390
|
shakeFrames = frames;
|
|
10391
10391
|
shakeIntensity = intensity;
|
|
10392
10392
|
}
|
|
@@ -10446,8 +10446,8 @@ function runTowerGame(terminal) {
|
|
|
10446
10446
|
gameOver = true;
|
|
10447
10447
|
if (score > highScore) highScore = score;
|
|
10448
10448
|
if (perfectCombo > maxCombo) maxCombo = perfectCombo;
|
|
10449
|
-
|
|
10450
|
-
|
|
10449
|
+
spawnParticles3(dropX + dropWidth / 2, landY, 15, "\x1B[91m");
|
|
10450
|
+
triggerShake2(10, 3);
|
|
10451
10451
|
return;
|
|
10452
10452
|
}
|
|
10453
10453
|
const isPerfect = Math.abs(dropLeft - topLeft) < PERFECT_THRESHOLD && Math.abs(dropRight - topRight) < PERFECT_THRESHOLD;
|
|
@@ -10457,34 +10457,34 @@ function runTowerGame(terminal) {
|
|
|
10457
10457
|
const comboBonus = Math.min(perfectCombo * 5, 50);
|
|
10458
10458
|
points += 10 + comboBonus;
|
|
10459
10459
|
flashFrames = 6;
|
|
10460
|
-
|
|
10460
|
+
spawnParticles3(dropX + dropWidth / 2, landY, 12, "\x1B[93m");
|
|
10461
10461
|
const popupText = perfectCombo > 1 ? `PERFECT! x${perfectCombo}` : "PERFECT!";
|
|
10462
|
-
|
|
10462
|
+
addScorePopup2(
|
|
10463
10463
|
Math.floor(GAME_WIDTH / 2) - Math.floor(popupText.length / 2),
|
|
10464
10464
|
Math.floor(GAME_HEIGHT / 2),
|
|
10465
10465
|
popupText,
|
|
10466
10466
|
perfectCombo > 3 ? "\x1B[1;91m" : "\x1B[1;93m"
|
|
10467
10467
|
);
|
|
10468
|
-
|
|
10468
|
+
triggerShake2(4, 1);
|
|
10469
10469
|
} else {
|
|
10470
10470
|
if (perfectCombo > maxCombo) maxCombo = perfectCombo;
|
|
10471
10471
|
perfectCombo = 0;
|
|
10472
10472
|
if (dropLeft < topLeft) {
|
|
10473
10473
|
const overhangWidth = topLeft - dropLeft;
|
|
10474
10474
|
spawnFallingPiece(dropLeft, landY, overhangWidth, dropColor);
|
|
10475
|
-
|
|
10475
|
+
spawnParticles3(dropLeft + overhangWidth / 2, landY, 5, dropColor);
|
|
10476
10476
|
}
|
|
10477
10477
|
if (dropRight > topRight) {
|
|
10478
10478
|
const overhangWidth = dropRight - topRight;
|
|
10479
10479
|
spawnFallingPiece(topRight, landY, overhangWidth, dropColor);
|
|
10480
|
-
|
|
10480
|
+
spawnParticles3(topRight + overhangWidth / 2, landY, 5, dropColor);
|
|
10481
10481
|
}
|
|
10482
|
-
|
|
10482
|
+
triggerShake2(3, 1);
|
|
10483
10483
|
}
|
|
10484
10484
|
score += points;
|
|
10485
10485
|
height++;
|
|
10486
10486
|
if (points > 10) {
|
|
10487
|
-
|
|
10487
|
+
addScorePopup2(overlapLeft + overlapWidth / 2, landY - 1, `+${points}`, "\x1B[92m");
|
|
10488
10488
|
}
|
|
10489
10489
|
tower.push({
|
|
10490
10490
|
x: overlapLeft,
|
|
@@ -10850,7 +10850,7 @@ function runTronGame(terminal) {
|
|
|
10850
10850
|
"\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2580\u2588\u2580 \u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2584 \u2588",
|
|
10851
10851
|
"\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2588 \u2588\u2580\u2584 \u2588\u2584\u2588 \u2588 \u2580\u2588"
|
|
10852
10852
|
];
|
|
10853
|
-
function
|
|
10853
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2591", "\u2592", "\u2593", "\u2588", "\u25C6"]) {
|
|
10854
10854
|
for (let i = 0; i < count; i++) {
|
|
10855
10855
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
10856
10856
|
const speed = 0.3 + Math.random() * 0.5;
|
|
@@ -10866,10 +10866,10 @@ function runTronGame(terminal) {
|
|
|
10866
10866
|
}
|
|
10867
10867
|
}
|
|
10868
10868
|
function spawnExplosion(x, y, color) {
|
|
10869
|
-
|
|
10870
|
-
|
|
10869
|
+
spawnParticles3(x, y, 20, color, ["\u2717", "\xD7", "\u2591", "\u2592", "\u2593", "\u2588"]);
|
|
10870
|
+
triggerShake2(12, 3);
|
|
10871
10871
|
}
|
|
10872
|
-
function
|
|
10872
|
+
function triggerShake2(frames, intensity) {
|
|
10873
10873
|
shakeFrames = frames;
|
|
10874
10874
|
shakeIntensity = intensity;
|
|
10875
10875
|
}
|
|
@@ -11084,7 +11084,7 @@ function runTronGame(terminal) {
|
|
|
11084
11084
|
arenaMinY += SHRINK_AMOUNT;
|
|
11085
11085
|
arenaMaxY -= SHRINK_AMOUNT;
|
|
11086
11086
|
}
|
|
11087
|
-
|
|
11087
|
+
triggerShake2(4, 1);
|
|
11088
11088
|
}
|
|
11089
11089
|
}
|
|
11090
11090
|
}
|
|
@@ -11719,7 +11719,7 @@ function runTypingTest(terminal) {
|
|
|
11719
11719
|
borderFlash = 0;
|
|
11720
11720
|
errorFlash = 0;
|
|
11721
11721
|
}
|
|
11722
|
-
function
|
|
11722
|
+
function spawnParticles3(x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
11723
11723
|
for (let i = 0; i < count; i++) {
|
|
11724
11724
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
11725
11725
|
const speed = 0.2 + Math.random() * 0.3;
|
|
@@ -11734,7 +11734,7 @@ function runTypingTest(terminal) {
|
|
|
11734
11734
|
});
|
|
11735
11735
|
}
|
|
11736
11736
|
}
|
|
11737
|
-
function
|
|
11737
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
11738
11738
|
scorePopups.push({ x, y, text, frames: 18, color });
|
|
11739
11739
|
}
|
|
11740
11740
|
function calculateStats() {
|
|
@@ -11773,16 +11773,16 @@ function runTypingTest(terminal) {
|
|
|
11773
11773
|
correctStreak++;
|
|
11774
11774
|
if (correctStreak >= 5 && correctStreak % 5 === 0) {
|
|
11775
11775
|
borderFlash = 6;
|
|
11776
|
-
|
|
11777
|
-
|
|
11776
|
+
spawnParticles3(cursorX, textY, 4 + Math.floor(correctStreak / 5), "\x1B[1;92m", ["\u2726", "\u2605", "\u25C6"]);
|
|
11777
|
+
addScorePopup2(cursorX, textY - 1, `${correctStreak}!`, "\x1B[1;96m");
|
|
11778
11778
|
} else if (correctStreak >= 10) {
|
|
11779
11779
|
if (Math.random() < 0.3) {
|
|
11780
|
-
|
|
11780
|
+
spawnParticles3(cursorX, textY, 2, "\x1B[1;92m", ["\xB7", "\u2022", "\u25CB"]);
|
|
11781
11781
|
}
|
|
11782
11782
|
}
|
|
11783
11783
|
if (char === " " || typedText.length === currentText.length) {
|
|
11784
11784
|
wordsCompleted++;
|
|
11785
|
-
|
|
11785
|
+
spawnParticles3(cursorX - 2, textY, 3, "\x1B[1;96m", ["\u2726", "\xB7", "\u25CB"]);
|
|
11786
11786
|
}
|
|
11787
11787
|
if (typedText.length >= currentText.length - 20) {
|
|
11788
11788
|
if (mode === "words") {
|
|
@@ -11798,7 +11798,7 @@ function runTypingTest(terminal) {
|
|
|
11798
11798
|
correctStreak = 0;
|
|
11799
11799
|
errorFlash = 6;
|
|
11800
11800
|
screenShake = 3;
|
|
11801
|
-
|
|
11801
|
+
spawnParticles3(cursorX, textY, 3, "\x1B[1;91m", ["\u2717", "\xD7", "\xB7"]);
|
|
11802
11802
|
}
|
|
11803
11803
|
}
|
|
11804
11804
|
function handleBackspace() {
|
|
@@ -12542,7 +12542,7 @@ function runWordleGame(terminal) {
|
|
|
12542
12542
|
"\u2588 \u2588 \u2588\u2584\u2588 \u2588\u2580\u2588 \u2588\u2580\u2580 \u2588\u2580\u2588 \u2588 \u2588 \u2588 \u2588\u2580\u2588 \u2588\u2580\u2588 \u2588\u2580\u2584 \u2588 \u2588\u2580\u2580",
|
|
12543
12543
|
"\u2588\u2580\u2588 \u2588 \u2588\u2580\u2580 \u2588\u2588\u2584 \u2588\u2580\u2584 \u2580\u2584\u2580\u2584\u2580 \u2588\u2584\u2588 \u2588\u2580\u2584 \u2588\u2584\u2580 \u2588\u2584\u2584 \u2588\u2588\u2584"
|
|
12544
12544
|
];
|
|
12545
|
-
function
|
|
12545
|
+
function spawnParticles3(x, y, count, color, chars = ["*", "+", "o", "."]) {
|
|
12546
12546
|
for (let i = 0; i < count; i++) {
|
|
12547
12547
|
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
12548
12548
|
const speed = 0.3 + Math.random() * 0.5;
|
|
@@ -12557,7 +12557,7 @@ function runWordleGame(terminal) {
|
|
|
12557
12557
|
});
|
|
12558
12558
|
}
|
|
12559
12559
|
}
|
|
12560
|
-
function
|
|
12560
|
+
function spawnFirework3(x, y) {
|
|
12561
12561
|
const colors = ["\x1B[1;92m", "\x1B[1;93m", "\x1B[1;96m", "\x1B[1;95m"];
|
|
12562
12562
|
const color = colors[Math.floor(Math.random() * colors.length)];
|
|
12563
12563
|
const chars = ["*", "+", "o", ".", "`", "'"];
|
|
@@ -12575,10 +12575,10 @@ function runWordleGame(terminal) {
|
|
|
12575
12575
|
});
|
|
12576
12576
|
}
|
|
12577
12577
|
}
|
|
12578
|
-
function
|
|
12578
|
+
function addScorePopup2(x, y, text, color = "\x1B[1;33m") {
|
|
12579
12579
|
scorePopups.push({ x, y, text, frames: 25, color });
|
|
12580
12580
|
}
|
|
12581
|
-
function
|
|
12581
|
+
function triggerShake2(frames, intensity) {
|
|
12582
12582
|
shakeFrames = frames;
|
|
12583
12583
|
shakeIntensity = intensity;
|
|
12584
12584
|
}
|
|
@@ -12636,8 +12636,8 @@ function runWordleGame(terminal) {
|
|
|
12636
12636
|
}
|
|
12637
12637
|
function submitGuess() {
|
|
12638
12638
|
if (currentGuess.length !== WORD_LENGTH) {
|
|
12639
|
-
|
|
12640
|
-
|
|
12639
|
+
triggerShake2(4, 2);
|
|
12640
|
+
addScorePopup2(Math.floor(cols / 2), 8, "NOT ENOUGH LETTERS", "\x1B[1;91m");
|
|
12641
12641
|
return;
|
|
12642
12642
|
}
|
|
12643
12643
|
const result = checkGuess(currentGuess);
|
|
@@ -12662,15 +12662,15 @@ function runWordleGame(terminal) {
|
|
|
12662
12662
|
}
|
|
12663
12663
|
stats.guessDistribution[guesses.length - 1]++;
|
|
12664
12664
|
borderFlash = 20;
|
|
12665
|
-
|
|
12665
|
+
triggerShake2(10, 3);
|
|
12666
12666
|
const messages = ["CIPHER BREACHED!", "CODE CRACKED!", "DECRYPTED!", "BRILLIANT!"];
|
|
12667
|
-
|
|
12667
|
+
addScorePopup2(centerX, guessY - 2, messages[Math.floor(Math.random() * messages.length)], "\x1B[1;92m");
|
|
12668
12668
|
setTimeout(() => {
|
|
12669
12669
|
if (running) {
|
|
12670
12670
|
for (let i = 0; i < 5; i++) {
|
|
12671
12671
|
setTimeout(() => {
|
|
12672
12672
|
if (running && won) {
|
|
12673
|
-
|
|
12673
|
+
spawnFirework3(
|
|
12674
12674
|
10 + Math.random() * (cols - 20),
|
|
12675
12675
|
5 + Math.random() * 10
|
|
12676
12676
|
);
|
|
@@ -12683,15 +12683,15 @@ function runWordleGame(terminal) {
|
|
|
12683
12683
|
gameOver = true;
|
|
12684
12684
|
stats.gamesPlayed++;
|
|
12685
12685
|
stats.currentStreak = 0;
|
|
12686
|
-
|
|
12686
|
+
triggerShake2(8, 4);
|
|
12687
12687
|
borderFlash = 15;
|
|
12688
|
-
|
|
12689
|
-
|
|
12688
|
+
addScorePopup2(centerX, guessY - 2, "DECRYPTION FAILED", "\x1B[1;91m");
|
|
12689
|
+
spawnParticles3(centerX, guessY, 10, "\x1B[1;91m", ["X", "x", ".", "*"]);
|
|
12690
12690
|
} else {
|
|
12691
12691
|
if (correctCount > 0 || presentCount > 0) {
|
|
12692
12692
|
const hint = correctCount > 0 ? `${correctCount} EXACT` : `${presentCount} CLOSE`;
|
|
12693
|
-
|
|
12694
|
-
|
|
12693
|
+
addScorePopup2(centerX, guessY - 1, hint, correctCount > 0 ? "\x1B[1;92m" : "\x1B[1;93m");
|
|
12694
|
+
spawnParticles3(centerX, guessY, 3 + correctCount * 2, correctCount > 0 ? "\x1B[1;92m" : "\x1B[1;93m");
|
|
12695
12695
|
}
|
|
12696
12696
|
}
|
|
12697
12697
|
currentGuess = "";
|
|
@@ -13058,7 +13058,7 @@ function runWordleGame(terminal) {
|
|
|
13058
13058
|
submitGuess();
|
|
13059
13059
|
} else if (key.length === 1 && /[a-zA-Z]/.test(key) && currentGuess.length < WORD_LENGTH) {
|
|
13060
13060
|
currentGuess += key.toUpperCase();
|
|
13061
|
-
|
|
13061
|
+
spawnParticles3(
|
|
13062
13062
|
Math.floor(cols / 2) - 8 + currentGuess.length * 4,
|
|
13063
13063
|
4 + guesses.length * 2,
|
|
13064
13064
|
2,
|
|
@@ -13660,6 +13660,140 @@ function runRebootEffect(terminal) {
|
|
|
13660
13660
|
};
|
|
13661
13661
|
}
|
|
13662
13662
|
|
|
13663
|
+
// src/games/shared/effects.ts
|
|
13664
|
+
var MAX_PARTICLES2 = 100;
|
|
13665
|
+
var PARTICLE_CHARS = {
|
|
13666
|
+
explosion: ["\u2717", "\xD7", "\xB7", "\u25CB", "\u2592", "\u2591"],
|
|
13667
|
+
success: ["\u2726", "\u2605", "\u25C6", "\u25CF", "\u2666"],
|
|
13668
|
+
fire: ["\u2593", "\u2592", "\u2591", "\u25CF", "\u25C6"],
|
|
13669
|
+
death: ["\u2717", "\u2620", "\xD7", "\u2593", "\u2591"],
|
|
13670
|
+
sparkle: ["\u2726", "\u2727", "\u2605"],
|
|
13671
|
+
firework: ["\u2605", "\u2726", "\u25C6", "\u25CF", "\u2736", "\u2734", "\u25C7", "\u2666", "\u2022", "\u25CB"]
|
|
13672
|
+
};
|
|
13673
|
+
var FIREWORK_COLORS = [
|
|
13674
|
+
"\x1B[1;93m",
|
|
13675
|
+
"\x1B[1;92m",
|
|
13676
|
+
"\x1B[1;96m",
|
|
13677
|
+
"\x1B[1;95m",
|
|
13678
|
+
"\x1B[1;91m",
|
|
13679
|
+
"\x1B[1;97m"
|
|
13680
|
+
];
|
|
13681
|
+
function spawnParticles2(particles, x, y, count, color, chars = ["\u2726", "\u2605", "\u25C6", "\u25CF"]) {
|
|
13682
|
+
if (particles.length >= MAX_PARTICLES2) return;
|
|
13683
|
+
const actualCount = Math.min(count, MAX_PARTICLES2 - particles.length);
|
|
13684
|
+
for (let i = 0; i < actualCount; i++) {
|
|
13685
|
+
const angle = Math.PI * 2 * i / count + Math.random() * 0.5;
|
|
13686
|
+
const speed = 0.2 + Math.random() * 0.3;
|
|
13687
|
+
particles.push({
|
|
13688
|
+
x,
|
|
13689
|
+
y,
|
|
13690
|
+
char: chars[Math.floor(Math.random() * chars.length)],
|
|
13691
|
+
color,
|
|
13692
|
+
vx: Math.cos(angle) * speed,
|
|
13693
|
+
vy: Math.sin(angle) * speed * 0.5,
|
|
13694
|
+
life: 10 + Math.floor(Math.random() * 8)
|
|
13695
|
+
});
|
|
13696
|
+
}
|
|
13697
|
+
}
|
|
13698
|
+
function spawnFirework2(particles, x, y, intensity = 1) {
|
|
13699
|
+
const chars = PARTICLE_CHARS.firework;
|
|
13700
|
+
for (let i = 0; i < 12 * intensity; i++) {
|
|
13701
|
+
const angle = Math.PI * 2 * i / (12 * intensity);
|
|
13702
|
+
const speed = 0.4 + Math.random() * 0.4;
|
|
13703
|
+
const color = FIREWORK_COLORS[Math.floor(Math.random() * FIREWORK_COLORS.length)];
|
|
13704
|
+
const char = chars[Math.floor(Math.random() * chars.length)];
|
|
13705
|
+
particles.push({
|
|
13706
|
+
x,
|
|
13707
|
+
y,
|
|
13708
|
+
char,
|
|
13709
|
+
color,
|
|
13710
|
+
vx: Math.cos(angle) * speed,
|
|
13711
|
+
vy: Math.sin(angle) * speed - 0.2,
|
|
13712
|
+
life: 20 + Math.floor(Math.random() * 15)
|
|
13713
|
+
});
|
|
13714
|
+
}
|
|
13715
|
+
for (let i = 0; i < 8 * intensity; i++) {
|
|
13716
|
+
const angle = Math.PI * 2 * i / (8 * intensity) + Math.random() * 0.3;
|
|
13717
|
+
const dist = 1.5 + Math.random();
|
|
13718
|
+
particles.push({
|
|
13719
|
+
x: x + Math.cos(angle) * dist,
|
|
13720
|
+
y: y + Math.sin(angle) * dist,
|
|
13721
|
+
char: "\u2727",
|
|
13722
|
+
color: "\x1B[1;97m",
|
|
13723
|
+
vx: Math.cos(angle) * 0.15,
|
|
13724
|
+
vy: Math.sin(angle) * 0.15 - 0.1,
|
|
13725
|
+
life: 15 + Math.floor(Math.random() * 10)
|
|
13726
|
+
});
|
|
13727
|
+
}
|
|
13728
|
+
}
|
|
13729
|
+
function spawnSparkleTrail2(particles, x, y, count = 6, color = "\x1B[1;93m") {
|
|
13730
|
+
for (let i = 0; i < count; i++) {
|
|
13731
|
+
particles.push({
|
|
13732
|
+
x: x + (Math.random() - 0.5) * 4,
|
|
13733
|
+
y,
|
|
13734
|
+
char: PARTICLE_CHARS.sparkle[Math.floor(Math.random() * PARTICLE_CHARS.sparkle.length)],
|
|
13735
|
+
color,
|
|
13736
|
+
vx: (Math.random() - 0.5) * 0.2,
|
|
13737
|
+
vy: -0.3 - Math.random() * 0.3,
|
|
13738
|
+
life: 25 + Math.floor(Math.random() * 15)
|
|
13739
|
+
});
|
|
13740
|
+
}
|
|
13741
|
+
}
|
|
13742
|
+
function updateParticles2(particles, gravityMult = 1) {
|
|
13743
|
+
for (let i = particles.length - 1; i >= 0; i--) {
|
|
13744
|
+
const p = particles[i];
|
|
13745
|
+
p.x += p.vx;
|
|
13746
|
+
p.y += p.vy;
|
|
13747
|
+
p.vy += 0.02 * gravityMult;
|
|
13748
|
+
p.life--;
|
|
13749
|
+
if (p.life <= 0) particles.splice(i, 1);
|
|
13750
|
+
}
|
|
13751
|
+
}
|
|
13752
|
+
function addScorePopup(popups, x, y, text, color = "\x1B[1;33m") {
|
|
13753
|
+
popups.push({ x, y, text, frames: 18, color });
|
|
13754
|
+
}
|
|
13755
|
+
function updatePopups2(popups) {
|
|
13756
|
+
for (let i = popups.length - 1; i >= 0; i--) {
|
|
13757
|
+
const popup = popups[i];
|
|
13758
|
+
popup.y -= 0.25;
|
|
13759
|
+
popup.frames--;
|
|
13760
|
+
if (popup.frames <= 0) popups.splice(i, 1);
|
|
13761
|
+
}
|
|
13762
|
+
}
|
|
13763
|
+
function createShakeState() {
|
|
13764
|
+
return { frames: 0, intensity: 0 };
|
|
13765
|
+
}
|
|
13766
|
+
function triggerShake(state, frames, intensity) {
|
|
13767
|
+
state.frames = frames;
|
|
13768
|
+
state.intensity = intensity;
|
|
13769
|
+
}
|
|
13770
|
+
function applyShake(state) {
|
|
13771
|
+
if (state.frames > 0) {
|
|
13772
|
+
state.frames--;
|
|
13773
|
+
return {
|
|
13774
|
+
offsetX: Math.floor((Math.random() - 0.5) * state.intensity * 2),
|
|
13775
|
+
offsetY: Math.floor((Math.random() - 0.5) * state.intensity)
|
|
13776
|
+
};
|
|
13777
|
+
}
|
|
13778
|
+
return { offsetX: 0, offsetY: 0 };
|
|
13779
|
+
}
|
|
13780
|
+
function createFlashState() {
|
|
13781
|
+
return { frames: 0 };
|
|
13782
|
+
}
|
|
13783
|
+
function triggerFlash(state, frames) {
|
|
13784
|
+
state.frames = frames;
|
|
13785
|
+
}
|
|
13786
|
+
function updateFlash(state) {
|
|
13787
|
+
if (state.frames > 0) {
|
|
13788
|
+
state.frames--;
|
|
13789
|
+
return true;
|
|
13790
|
+
}
|
|
13791
|
+
return false;
|
|
13792
|
+
}
|
|
13793
|
+
function isFlashVisible(state) {
|
|
13794
|
+
return state.frames > 0 && state.frames % 4 < 2;
|
|
13795
|
+
}
|
|
13796
|
+
|
|
13663
13797
|
// src/games/index.ts
|
|
13664
13798
|
var games = [
|
|
13665
13799
|
// Ordered for first-time discovery enjoyment (most accessible first).
|
|
@@ -13693,14 +13827,21 @@ function runGame(id, terminal) {
|
|
|
13693
13827
|
return game?.run(terminal);
|
|
13694
13828
|
}
|
|
13695
13829
|
export {
|
|
13830
|
+
FIREWORK_COLORS,
|
|
13696
13831
|
GAME_EVENTS,
|
|
13832
|
+
MAX_PARTICLES2 as MAX_PARTICLES,
|
|
13697
13833
|
MODE_SELECT_ITEMS,
|
|
13834
|
+
PARTICLE_CHARS,
|
|
13698
13835
|
PAUSE_MENU_ITEMS,
|
|
13836
|
+
addScorePopup,
|
|
13837
|
+
applyShake,
|
|
13699
13838
|
checkShortcut,
|
|
13839
|
+
createFlashState,
|
|
13700
13840
|
createGameOverMenuItems,
|
|
13701
13841
|
createMenuState,
|
|
13702
13842
|
createModeSelectMenuItems,
|
|
13703
13843
|
createPauseMenuItems,
|
|
13844
|
+
createShakeState,
|
|
13704
13845
|
dispatchGameQuit,
|
|
13705
13846
|
dispatchGameSwitch,
|
|
13706
13847
|
dispatchGamesMenu,
|
|
@@ -13719,6 +13860,7 @@ export {
|
|
|
13719
13860
|
getVerticalAnchor,
|
|
13720
13861
|
handleMatrixKeypress,
|
|
13721
13862
|
handleMenuInput,
|
|
13863
|
+
isFlashVisible,
|
|
13722
13864
|
isInAlternateBuffer,
|
|
13723
13865
|
isLightTheme2 as isLightTheme,
|
|
13724
13866
|
isMatrixWaitingForKey,
|
|
@@ -13759,6 +13901,14 @@ export {
|
|
|
13759
13901
|
runWordleGame,
|
|
13760
13902
|
setTheme,
|
|
13761
13903
|
showGamesMenu,
|
|
13762
|
-
|
|
13904
|
+
spawnFirework2 as spawnFirework,
|
|
13905
|
+
spawnParticles2 as spawnParticles,
|
|
13906
|
+
spawnSparkleTrail2 as spawnSparkleTrail,
|
|
13907
|
+
startMatrixRain,
|
|
13908
|
+
triggerFlash,
|
|
13909
|
+
triggerShake,
|
|
13910
|
+
updateFlash,
|
|
13911
|
+
updateParticles2 as updateParticles,
|
|
13912
|
+
updatePopups2 as updatePopups
|
|
13763
13913
|
};
|
|
13764
13914
|
//# sourceMappingURL=index.js.map
|