tune zuma: slow down ball push speed, add per-level backgrounds & lose fanfare
- Reduce pushSpeed across all 20 levels to ~60% of original values in tools/genZuma.js, making the chain advance more slowly and giving the player more reaction time. starScores() thresholds auto-adjust downward since they are derived from pushSpeed. - Add per-level background art (zuma-background-1 / -2) alternated per level via a new `background` field in each level definition; draw it in ZumaGame.drawBackground() over the solid fallback rectangle. - Register the two new background textures and sfx-zuma-lose in the asset manifest. - Add playLoseFanfare() mirroring playStartFanfare() to duck/pause music and play the lose SFX when the chain goes over the edge (onLost). - Add a black stroke to the "ZUMA!" win banner for readability. - Bump music volume to 0.5 in zuma-music.json.
This commit is contained in:
parent
0201b0de7d
commit
eabeef3165
Binary file not shown.
|
|
@ -16,5 +16,5 @@
|
||||||
"title": "Deep in the Jungle"
|
"title": "Deep in the Jungle"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"volume": 0.3
|
"volume": 0.5
|
||||||
}
|
}
|
||||||
|
|
|
||||||
182
data/zuma.json
182
data/zuma.json
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"generatedAt": "2026-07-28T21:55:21.106Z",
|
"generatedAt": "2026-07-28T23:39:54.596Z",
|
||||||
"count": 20,
|
"count": 20,
|
||||||
"levels": [
|
"levels": [
|
||||||
{
|
{
|
||||||
|
|
@ -372,13 +372,14 @@
|
||||||
"colors": 4,
|
"colors": 4,
|
||||||
"quota": 22,
|
"quota": 22,
|
||||||
"introBalls": 7,
|
"introBalls": 7,
|
||||||
"pushSpeed": 100,
|
"pushSpeed": 60,
|
||||||
"powerUpRate": 0.07,
|
"powerUpRate": 0.07,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 8919,
|
"seed": 8919,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
750,
|
660,
|
||||||
1130,
|
990,
|
||||||
1500
|
1320
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -527,13 +528,14 @@
|
||||||
"colors": 4,
|
"colors": 4,
|
||||||
"quota": 26,
|
"quota": 26,
|
||||||
"introBalls": 8,
|
"introBalls": 8,
|
||||||
"pushSpeed": 128,
|
"pushSpeed": 76,
|
||||||
"powerUpRate": 0.07,
|
"powerUpRate": 0.07,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 16838,
|
"seed": 16838,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
960,
|
820,
|
||||||
1430,
|
1230,
|
||||||
1910
|
1640
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -922,13 +924,14 @@
|
||||||
"colors": 4,
|
"colors": 4,
|
||||||
"quota": 30,
|
"quota": 30,
|
||||||
"introBalls": 9,
|
"introBalls": 9,
|
||||||
"pushSpeed": 140,
|
"pushSpeed": 84,
|
||||||
"powerUpRate": 0.065,
|
"powerUpRate": 0.065,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 24757,
|
"seed": 24757,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1140,
|
970,
|
||||||
1710,
|
1460,
|
||||||
2280
|
1940
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1281,13 +1284,14 @@
|
||||||
"colors": 4,
|
"colors": 4,
|
||||||
"quota": 32,
|
"quota": 32,
|
||||||
"introBalls": 10,
|
"introBalls": 10,
|
||||||
"pushSpeed": 140,
|
"pushSpeed": 84,
|
||||||
"powerUpRate": 0.065,
|
"powerUpRate": 0.065,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 32676,
|
"seed": 32676,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1220,
|
1040,
|
||||||
1820,
|
1550,
|
||||||
2430
|
2070
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1497,13 +1501,14 @@
|
||||||
"colors": 4,
|
"colors": 4,
|
||||||
"quota": 38,
|
"quota": 38,
|
||||||
"introBalls": 11,
|
"introBalls": 11,
|
||||||
"pushSpeed": 148,
|
"pushSpeed": 88,
|
||||||
"powerUpRate": 0.06,
|
"powerUpRate": 0.06,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 40595,
|
"seed": 40595,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1480,
|
1250,
|
||||||
2210,
|
1870,
|
||||||
2950
|
2490
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -1724,13 +1729,14 @@
|
||||||
"colors": 4,
|
"colors": 4,
|
||||||
"quota": 34,
|
"quota": 34,
|
||||||
"introBalls": 10,
|
"introBalls": 10,
|
||||||
"pushSpeed": 148,
|
"pushSpeed": 88,
|
||||||
"powerUpRate": 0.06,
|
"powerUpRate": 0.06,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 48514,
|
"seed": 48514,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1320,
|
1120,
|
||||||
1980,
|
1670,
|
||||||
2640
|
2230
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -2103,13 +2109,14 @@
|
||||||
"colors": 4,
|
"colors": 4,
|
||||||
"quota": 26,
|
"quota": 26,
|
||||||
"introBalls": 8,
|
"introBalls": 8,
|
||||||
"pushSpeed": 180,
|
"pushSpeed": 108,
|
||||||
"powerUpRate": 0.06,
|
"powerUpRate": 0.06,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 56433,
|
"seed": 56433,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1090,
|
910,
|
||||||
1640,
|
1360,
|
||||||
2180
|
1810
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -2263,13 +2270,14 @@
|
||||||
"colors": 5,
|
"colors": 5,
|
||||||
"quota": 30,
|
"quota": 30,
|
||||||
"introBalls": 9,
|
"introBalls": 9,
|
||||||
"pushSpeed": 160,
|
"pushSpeed": 96,
|
||||||
"powerUpRate": 0.055,
|
"powerUpRate": 0.055,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 64352,
|
"seed": 64352,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1200,
|
1010,
|
||||||
1800,
|
1520,
|
||||||
2400
|
2020
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -2622,13 +2630,14 @@
|
||||||
"colors": 5,
|
"colors": 5,
|
||||||
"quota": 36,
|
"quota": 36,
|
||||||
"introBalls": 11,
|
"introBalls": 11,
|
||||||
"pushSpeed": 160,
|
"pushSpeed": 96,
|
||||||
"powerUpRate": 0.055,
|
"powerUpRate": 0.055,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 72271,
|
"seed": 72271,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1440,
|
1210,
|
||||||
2160,
|
1820,
|
||||||
2880
|
2420
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -3022,13 +3031,14 @@
|
||||||
"colors": 5,
|
"colors": 5,
|
||||||
"quota": 34,
|
"quota": 34,
|
||||||
"introBalls": 10,
|
"introBalls": 10,
|
||||||
"pushSpeed": 172,
|
"pushSpeed": 104,
|
||||||
"powerUpRate": 0.055,
|
"powerUpRate": 0.055,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 80190,
|
"seed": 80190,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1400,
|
1170,
|
||||||
2100,
|
1760,
|
||||||
2800
|
2340
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -3238,13 +3248,14 @@
|
||||||
"colors": 5,
|
"colors": 5,
|
||||||
"quota": 42,
|
"quota": 42,
|
||||||
"introBalls": 12,
|
"introBalls": 12,
|
||||||
"pushSpeed": 172,
|
"pushSpeed": 104,
|
||||||
"powerUpRate": 0.05,
|
"powerUpRate": 0.05,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 88109,
|
"seed": 88109,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1730,
|
1450,
|
||||||
2600,
|
2170,
|
||||||
3460
|
2890
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -3465,13 +3476,14 @@
|
||||||
"colors": 5,
|
"colors": 5,
|
||||||
"quota": 38,
|
"quota": 38,
|
||||||
"introBalls": 11,
|
"introBalls": 11,
|
||||||
"pushSpeed": 180,
|
"pushSpeed": 108,
|
||||||
"powerUpRate": 0.05,
|
"powerUpRate": 0.05,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 96028,
|
"seed": 96028,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1600,
|
1320,
|
||||||
2390,
|
1980,
|
||||||
3190
|
2640
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -3824,13 +3836,14 @@
|
||||||
"colors": 5,
|
"colors": 5,
|
||||||
"quota": 34,
|
"quota": 34,
|
||||||
"introBalls": 10,
|
"introBalls": 10,
|
||||||
"pushSpeed": 192,
|
"pushSpeed": 116,
|
||||||
"powerUpRate": 0.05,
|
"powerUpRate": 0.05,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 103947,
|
"seed": 103947,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1470,
|
1210,
|
||||||
2210,
|
1820,
|
||||||
2940
|
2420
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -4044,13 +4057,14 @@
|
||||||
"colors": 5,
|
"colors": 5,
|
||||||
"quota": 46,
|
"quota": 46,
|
||||||
"introBalls": 13,
|
"introBalls": 13,
|
||||||
"pushSpeed": 192,
|
"pushSpeed": 116,
|
||||||
"powerUpRate": 0.05,
|
"powerUpRate": 0.05,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 111866,
|
"seed": 111866,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1990,
|
1640,
|
||||||
2980,
|
2460,
|
||||||
3970
|
3280
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -4199,13 +4213,14 @@
|
||||||
"colors": 6,
|
"colors": 6,
|
||||||
"quota": 32,
|
"quota": 32,
|
||||||
"introBalls": 9,
|
"introBalls": 9,
|
||||||
"pushSpeed": 204,
|
"pushSpeed": 124,
|
||||||
"powerUpRate": 0.05,
|
"powerUpRate": 0.05,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 119785,
|
"seed": 119785,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1420,
|
1170,
|
||||||
2130,
|
1750,
|
||||||
2840
|
2330
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -4599,13 +4614,14 @@
|
||||||
"colors": 6,
|
"colors": 6,
|
||||||
"quota": 38,
|
"quota": 38,
|
||||||
"introBalls": 11,
|
"introBalls": 11,
|
||||||
"pushSpeed": 212,
|
"pushSpeed": 128,
|
||||||
"powerUpRate": 0.05,
|
"powerUpRate": 0.05,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 127704,
|
"seed": 127704,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1720,
|
1400,
|
||||||
2580,
|
2100,
|
||||||
3440
|
2800
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -4958,13 +4974,14 @@
|
||||||
"colors": 6,
|
"colors": 6,
|
||||||
"quota": 34,
|
"quota": 34,
|
||||||
"introBalls": 10,
|
"introBalls": 10,
|
||||||
"pushSpeed": 200,
|
"pushSpeed": 120,
|
||||||
"powerUpRate": 0.045,
|
"powerUpRate": 0.045,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 135623,
|
"seed": 135623,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1500,
|
1230,
|
||||||
2240,
|
1840,
|
||||||
2990
|
2450
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -5185,13 +5202,14 @@
|
||||||
"colors": 6,
|
"colors": 6,
|
||||||
"quota": 40,
|
"quota": 40,
|
||||||
"introBalls": 11,
|
"introBalls": 11,
|
||||||
"pushSpeed": 200,
|
"pushSpeed": 120,
|
||||||
"powerUpRate": 0.045,
|
"powerUpRate": 0.045,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 143542,
|
"seed": 143542,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
1760,
|
1440,
|
||||||
2640,
|
2160,
|
||||||
3520
|
2880
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -5396,13 +5414,14 @@
|
||||||
"colors": 6,
|
"colors": 6,
|
||||||
"quota": 50,
|
"quota": 50,
|
||||||
"introBalls": 14,
|
"introBalls": 14,
|
||||||
"pushSpeed": 244,
|
"pushSpeed": 148,
|
||||||
"powerUpRate": 0.045,
|
"powerUpRate": 0.045,
|
||||||
|
"background": "zuma-background-1",
|
||||||
"seed": 151461,
|
"seed": 151461,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
2420,
|
1940,
|
||||||
3630,
|
2910,
|
||||||
4840
|
3880
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -5607,13 +5626,14 @@
|
||||||
"colors": 6,
|
"colors": 6,
|
||||||
"quota": 52,
|
"quota": 52,
|
||||||
"introBalls": 14,
|
"introBalls": 14,
|
||||||
"pushSpeed": 256,
|
"pushSpeed": 152,
|
||||||
"powerUpRate": 0.045,
|
"powerUpRate": 0.045,
|
||||||
|
"background": "zuma-background-2",
|
||||||
"seed": 159380,
|
"seed": 159380,
|
||||||
"starScores": [
|
"starScores": [
|
||||||
2580,
|
2040,
|
||||||
3870,
|
3060,
|
||||||
5160
|
4080
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -315,6 +315,10 @@ export const MANIFEST = {
|
||||||
],
|
],
|
||||||
zuma: [
|
zuma: [
|
||||||
image('zuma-menu-bg', 'assets/images/zuma/background-menu.png'),
|
image('zuma-menu-bg', 'assets/images/zuma/background-menu.png'),
|
||||||
|
// In-level backgrounds, alternated per level by ZumaLogic's `background`
|
||||||
|
// field (see tools/genZuma.js) — more can be dropped in later.
|
||||||
|
image('zuma-background-1', 'assets/images/zuma/background-01.png'),
|
||||||
|
image('zuma-background-2', 'assets/images/zuma/background-02.png'),
|
||||||
// frame 0 = the whole stone frog, frame 1 = the same disc with the mouth
|
// frame 0 = the whole stone frog, frame 1 = the same disc with the mouth
|
||||||
// slot cut out; the ready marble is drawn between them.
|
// slot cut out; the ready marble is drawn between them.
|
||||||
sheet('zuma-frog', 'assets/images/zuma/frog.png', 200, 200),
|
sheet('zuma-frog', 'assets/images/zuma/frog.png', 200, 200),
|
||||||
|
|
@ -328,6 +332,7 @@ export const MANIFEST = {
|
||||||
{ type: 'audio', key: 'sfx-zuma-start', path: 'assets/fx/zuma-start.mp3' },
|
{ type: 'audio', key: 'sfx-zuma-start', path: 'assets/fx/zuma-start.mp3' },
|
||||||
{ type: 'audio', key: 'sfx-zuma-explode', path: 'assets/fx/zuma-explode.mp3' },
|
{ type: 'audio', key: 'sfx-zuma-explode', path: 'assets/fx/zuma-explode.mp3' },
|
||||||
{ type: 'audio', key: 'sfx-zuma-win', path: 'assets/fx/zuma-win.mp3' },
|
{ type: 'audio', key: 'sfx-zuma-win', path: 'assets/fx/zuma-win.mp3' },
|
||||||
|
{ type: 'audio', key: 'sfx-zuma-lose', path: 'assets/fx/zuma-lose.mp3' },
|
||||||
],
|
],
|
||||||
'2048': [
|
'2048': [
|
||||||
// hacker soundtrack (see services/soundtrack.js) — lazy-loaded here so
|
// hacker soundtrack (see services/soundtrack.js) — lazy-loaded here so
|
||||||
|
|
|
||||||
|
|
@ -561,6 +561,7 @@ export default class ZumaGame extends Phaser.Scene {
|
||||||
this.aimAngle = -Math.PI / 2;
|
this.aimAngle = -Math.PI / 2;
|
||||||
|
|
||||||
this.clearLayer();
|
this.clearLayer();
|
||||||
|
this.drawBackground();
|
||||||
this.drawPath();
|
this.drawPath();
|
||||||
this.drawPortals();
|
this.drawPortals();
|
||||||
this.drawPit();
|
this.drawPit();
|
||||||
|
|
@ -587,6 +588,26 @@ export default class ZumaGame extends Phaser.Scene {
|
||||||
sfx.play();
|
sfx.play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Same duck/play/resume trick as playStartFanfare(), for the chain going
|
||||||
|
// over the edge instead of clearing the level.
|
||||||
|
playLoseFanfare() {
|
||||||
|
this.music?.pause();
|
||||||
|
const sfx = this.sound.add('sfx-zuma-lose');
|
||||||
|
sfx.once(Phaser.Sound.Events.COMPLETE, () => this.music?.resume());
|
||||||
|
sfx.play();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per-level art (def.background, see tools/genZuma.js) over the solid BG
|
||||||
|
// rectangle laid down once in create() — that rectangle is the fallback for
|
||||||
|
// any level whose background key isn't painted yet.
|
||||||
|
drawBackground() {
|
||||||
|
const key = this.levelDef.background;
|
||||||
|
if (!key || !this.textures.exists(key)) return;
|
||||||
|
const img = this.add.image(GAME_WIDTH / 2, GAME_HEIGHT / 2, key)
|
||||||
|
.setDisplaySize(GAME_WIDTH, GAME_HEIGHT).setDepth(D.bg);
|
||||||
|
this.layer.add(img);
|
||||||
|
}
|
||||||
|
|
||||||
drawPath() {
|
drawPath() {
|
||||||
const path = this.state.path;
|
const path = this.state.path;
|
||||||
const tunnels = this.state.tunnels;
|
const tunnels = this.state.tunnels;
|
||||||
|
|
@ -1050,7 +1071,7 @@ export default class ZumaGame extends Phaser.Scene {
|
||||||
|
|
||||||
onLost() {
|
onLost() {
|
||||||
this.overlayUp = true;
|
this.overlayUp = true;
|
||||||
playSound(this, SFX.CASINO_LOSE);
|
this.playLoseFanfare();
|
||||||
this.laserGfx?.clear();
|
this.laserGfx?.clear();
|
||||||
|
|
||||||
if (!this.testLevel) {
|
if (!this.testLevel) {
|
||||||
|
|
@ -1160,6 +1181,7 @@ export default class ZumaGame extends Phaser.Scene {
|
||||||
const cx = GAME_WIDTH / 2, cy = GAME_HEIGHT / 2;
|
const cx = GAME_WIDTH / 2, cy = GAME_HEIGHT / 2;
|
||||||
const banner = this.add.text(cx, cy - 60, 'ZUMA!', {
|
const banner = this.add.text(cx, cy - 60, 'ZUMA!', {
|
||||||
fontFamily: 'Righteous', fontSize: '140px', color: COLORS.goldHex,
|
fontFamily: 'Righteous', fontSize: '140px', color: COLORS.goldHex,
|
||||||
|
stroke: '#000000', strokeThickness: 8,
|
||||||
}).setOrigin(0.5).setScale(0.2).setDepth(D.fx);
|
}).setOrigin(0.5).setScale(0.2).setDepth(D.fx);
|
||||||
this.layer.add(banner);
|
this.layer.add(banner);
|
||||||
this.tweens.add({ targets: banner, scale: 1, duration: 450, ease: 'Back.easeOut' });
|
this.tweens.add({ targets: banner, scale: 1, duration: 450, ease: 'Back.easeOut' });
|
||||||
|
|
|
||||||
|
|
@ -178,28 +178,31 @@ const SHAPES = { sCurve, horseshoe, spiral, zigzag, doubleLoop, figureEight };
|
||||||
// never on zigzag (already only ~57% shootable), and never long enough that the
|
// never on zigzag (already only ~57% shootable), and never long enough that the
|
||||||
// frog runs out of targets while it waits for the chain to surface.
|
// frog runs out of targets while it waits for the chain to surface.
|
||||||
|
|
||||||
|
// pushSpeed values are ~60% of their original tuning (a 2026-07-28 across-the-
|
||||||
|
// board slowdown) — starScores() derives its thresholds from pushSpeed, so
|
||||||
|
// star bands shifted down with it automatically on regen.
|
||||||
const TABLE = [
|
const TABLE = [
|
||||||
// level, name, shape, colors, quota, intro, push, powerUpRate, tunnels
|
// level, name, shape, colors, quota, intro, push, powerUpRate, tunnels
|
||||||
[1, 'Riverbend', 'sCurve', 4, 22, 7, 100, 0.07],
|
[1, 'Riverbend', 'sCurve', 4, 22, 7, 60, 0.07],
|
||||||
[2, 'Temple Gate', 'horseshoe', 4, 26, 8, 128, 0.07],
|
[2, 'Temple Gate', 'horseshoe', 4, 26, 8, 76, 0.07],
|
||||||
[3, 'Twin Pools', 'doubleLoop', 4, 30, 9, 140, 0.065],
|
[3, 'Twin Pools', 'doubleLoop', 4, 30, 9, 84, 0.065],
|
||||||
[4, 'Switchbacks', 'zigzag', 4, 32, 10, 140, 0.065],
|
[4, 'Switchbacks', 'zigzag', 4, 32, 10, 84, 0.065],
|
||||||
[5, 'Serpent Coil', 'spiral', 4, 38, 11, 148, 0.06, [[0.36, 0.45]]],
|
[5, 'Serpent Coil', 'spiral', 4, 38, 11, 88, 0.06, [[0.36, 0.45]]],
|
||||||
[6, 'Crossroads', 'figureEight', 4, 34, 10, 148, 0.06],
|
[6, 'Crossroads', 'figureEight', 4, 34, 10, 88, 0.06],
|
||||||
[7, 'Rapids', 'sCurve', 4, 26, 8, 180, 0.06],
|
[7, 'Rapids', 'sCurve', 4, 26, 8, 108, 0.06],
|
||||||
[8, 'Sun Court', 'horseshoe', 5, 30, 9, 160, 0.055, [[0.34, 0.44]]],
|
[8, 'Sun Court', 'horseshoe', 5, 30, 9, 96, 0.055, [[0.34, 0.44]]],
|
||||||
[9, 'Thunder Steps', 'zigzag', 5, 36, 11, 160, 0.055],
|
[9, 'Thunder Steps', 'zigzag', 5, 36, 11, 96, 0.055],
|
||||||
[10, 'Twin Serpents', 'doubleLoop', 5, 34, 10, 172, 0.055, [[0.40, 0.50]]],
|
[10, 'Twin Serpents', 'doubleLoop', 5, 34, 10, 104, 0.055, [[0.40, 0.50]]],
|
||||||
[11, 'Deep Coil', 'spiral', 5, 42, 12, 172, 0.05, [[0.30, 0.40]]],
|
[11, 'Deep Coil', 'spiral', 5, 42, 12, 104, 0.05, [[0.30, 0.40]]],
|
||||||
[12, 'Tangled Path', 'figureEight', 5, 38, 11, 180, 0.05],
|
[12, 'Tangled Path', 'figureEight', 5, 38, 11, 108, 0.05],
|
||||||
[13, 'Lightning Run', 'zigzag', 5, 34, 10, 192, 0.05],
|
[13, 'Lightning Run', 'zigzag', 5, 34, 10, 116, 0.05],
|
||||||
[14, 'Whirlpool', 'spiral', 5, 46, 13, 192, 0.05, [[0.26, 0.36], [0.60, 0.70]]],
|
[14, 'Whirlpool', 'spiral', 5, 46, 13, 116, 0.05, [[0.26, 0.36], [0.60, 0.70]]],
|
||||||
[15, 'Obsidian Gate', 'horseshoe', 6, 32, 9, 204, 0.05],
|
[15, 'Obsidian Gate', 'horseshoe', 6, 32, 9, 124, 0.05],
|
||||||
[16, 'Twin Tempests', 'doubleLoop', 6, 38, 11, 212, 0.05, [[0.38, 0.46]]],
|
[16, 'Twin Tempests', 'doubleLoop', 6, 38, 11, 128, 0.05, [[0.38, 0.46]]],
|
||||||
[17, 'Stormsteps', 'zigzag', 6, 34, 10, 200, 0.045],
|
[17, 'Stormsteps', 'zigzag', 6, 34, 10, 120, 0.045],
|
||||||
[18, 'Maelstrom Cross', 'figureEight', 6, 40, 11, 200, 0.045],
|
[18, 'Maelstrom Cross', 'figureEight', 6, 40, 11, 120, 0.045],
|
||||||
[19, 'Abyss Coil', 'spiral', 6, 50, 14, 244, 0.045],
|
[19, 'Abyss Coil', 'spiral', 6, 50, 14, 148, 0.045],
|
||||||
[20, 'The Final Coil', 'spiral', 6, 52, 14, 256, 0.045],
|
[20, 'The Final Coil', 'spiral', 6, 52, 14, 152, 0.045],
|
||||||
];
|
];
|
||||||
|
|
||||||
// Calibrated against the headless aimbot in verifyZuma.js, which takes the best
|
// Calibrated against the headless aimbot in verifyZuma.js, which takes the best
|
||||||
|
|
@ -214,6 +217,10 @@ function starScores(quota, pushSpeed) {
|
||||||
|
|
||||||
// ── Build & write ────────────────────────────────────────────────────────────
|
// ── Build & write ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
// In-level background art (see data/assetManifest.js), alternated one per
|
||||||
|
// level while there are only two — drop more keys in here as they're painted.
|
||||||
|
const BACKGROUNDS = ['zuma-background-1', 'zuma-background-2'];
|
||||||
|
|
||||||
const levels = [];
|
const levels = [];
|
||||||
let bad = 0;
|
let bad = 0;
|
||||||
for (const [level, name, shape, colors, quota, introBalls, pushSpeed, powerUpRate, tunFrac] of TABLE) {
|
for (const [level, name, shape, colors, quota, introBalls, pushSpeed, powerUpRate, tunFrac] of TABLE) {
|
||||||
|
|
@ -222,6 +229,7 @@ for (const [level, name, shape, colors, quota, introBalls, pushSpeed, powerUpRat
|
||||||
const tunnels = (tunFrac ?? []).map(([a, b]) => [Math.round(len * a), Math.round(len * b)]);
|
const tunnels = (tunFrac ?? []).map(([a, b]) => [Math.round(len * a), Math.round(len * b)]);
|
||||||
const def = {
|
const def = {
|
||||||
level, name, shape, points, frog, tunnels, colors, quota, introBalls, pushSpeed, powerUpRate,
|
level, name, shape, points, frog, tunnels, colors, quota, introBalls, pushSpeed, powerUpRate,
|
||||||
|
background: BACKGROUNDS[(level - 1) % BACKGROUNDS.length],
|
||||||
seed: 1000 + level * 7919,
|
seed: 1000 + level * 7919,
|
||||||
starScores: starScores(quota, pushSpeed),
|
starScores: starScores(quota, pushSpeed),
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue