feat: enhance Zuma menu with background image and improve UI layout

- Add background image to Zuma title screen with solid color fallback
- Add new depth layer for background rendering (D.bg)
- Style progress text with semi-transparent background rectangle
- Reposition game buttons grid lower on screen for better visual balance
- Register zuma-menu-bg asset in manifest for lazy loading
- Add Advance Wars and Zuma image assets (background, frog sprite)
This commit is contained in:
Brian Fertig 2026-07-27 21:01:48 -06:00
parent 1ad2942241
commit b3dafbbdf7
6 changed files with 19 additions and 12 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
assets/images/zuma/frog.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
assets/images/zuma/frog.psd Normal file

Binary file not shown.

View File

@ -313,6 +313,9 @@ export const MANIFEST = {
// its audio only downloads once Dot Link is actually entered. // its audio only downloads once Dot Link is actually entered.
(scene) => musicFrom(scene, 'hacker-music'), (scene) => musicFrom(scene, 'hacker-music'),
], ],
zuma: [
image('zuma-menu-bg', 'assets/images/zuma/background-menu.png'),
],
'2048': [ '2048': [
// hacker soundtrack (see services/soundtrack.js) — lazy-loaded here so // hacker soundtrack (see services/soundtrack.js) — lazy-loaded here so
// its audio only downloads once 2048 is actually entered. // its audio only downloads once 2048 is actually entered.

View File

@ -11,7 +11,7 @@ import {
const BG = 0x0d1a10; // deep jungle green const BG = 0x0d1a10; // deep jungle green
const PATH_RIM = 0x241b0e; const PATH_RIM = 0x241b0e;
const PATH_BED = 0x4a3a26; const PATH_BED = 0x4a3a26;
const D = { path: 0, hole: 2, ball: 10, icon: 11, flight: 12, laser: 13, frog: 14, fx: 20, ui: 30, overlay: 60, overlayUI: 62 }; const D = { path: 0, hole: 2, ball: 10, icon: 11, flight: 12, laser: 13, frog: 14, fx: 20, ui: 30, bg: -2, overlay: 60, overlayUI: 62 };
// glossy marble palette: red, yellow, blue, green, purple, silver // glossy marble palette: red, yellow, blue, green, purple, silver
const BALL_COLORS = [0xd9403a, 0xeec23d, 0x3f7fdb, 0x43b059, 0x9b59d0, 0xd9dde3]; const BALL_COLORS = [0xd9403a, 0xeec23d, 0x3f7fdb, 0x43b059, 0x9b59d0, 0xd9dde3];
@ -202,15 +202,16 @@ export default class ZumaGame extends Phaser.Scene {
this.overlayUp = false; this.overlayUp = false;
this.state = null; this.state = null;
this.clearLayer(); this.clearLayer();
const cx = GAME_WIDTH / 2;
const title = this.add.text(cx, 84, 'ZUMA', { // Background image (falls back to solid color if not loaded)
fontFamily: 'Righteous', fontSize: '72px', color: COLORS.goldHex, if (this.textures.exists('zuma-menu-bg')) {
}).setOrigin(0.5); this.layer.add(this.add.image(GAME_WIDTH / 2, GAME_HEIGHT / 2, 'zuma-menu-bg')
const sub = this.add.text(cx, 148, 'Shoot marbles into the rolling chain — match 3+ to pop them all before the skull feeds. Right-click or SPACE swaps.', { .setDisplaySize(GAME_WIDTH, GAME_HEIGHT).setDepth(D.bg));
fontFamily: '"Julius Sans One"', fontSize: '22px', color: COLORS.mutedHex, } else {
}).setOrigin(0.5); this.layer.add(this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, BG).setDepth(D.bg));
this.layer.add([title, sub]); }
const cx = GAME_WIDTH / 2;
if (!this.bank.length) { if (!this.bank.length) {
const msg = this.add.text(cx, 520, 'No levels found.\nRun: node server/scripts/genZuma.js', { const msg = this.add.text(cx, 520, 'No levels found.\nRun: node server/scripts/genZuma.js', {
@ -223,17 +224,20 @@ export default class ZumaGame extends Phaser.Scene {
} }
const nextLevel = Math.min(this.levelsCompleted + 1, this.bank.length); const nextLevel = Math.min(this.levelsCompleted + 1, this.bank.length);
const prog = this.add.text(cx, 192, `Completed ${this.levelsCompleted} / ${this.bank.length}`, { const bg = this.add.rectangle(cx, 442, 320, 56, 0x000000, 0.55)
.setStrokeStyle(2, 0x6b5638, 0.8)
.setOrigin(0.5);
const prog = this.add.text(cx, 442, `Completed ${this.levelsCompleted} / ${this.bank.length}`, {
fontFamily: 'Righteous', fontSize: '24px', color: COLORS.textHex, fontFamily: 'Righteous', fontSize: '24px', color: COLORS.textHex,
}).setOrigin(0.5); }).setOrigin(0.5);
this.layer.add(prog); this.layer.add([bg, prog]);
const COLS = 10; const COLS = 10;
const SIZE = 120; const SIZE = 120;
const GAP = 16; const GAP = 16;
const gridW = COLS * SIZE + (COLS - 1) * GAP; const gridW = COLS * SIZE + (COLS - 1) * GAP;
const left = cx - gridW / 2 + SIZE / 2; const left = cx - gridW / 2 + SIZE / 2;
const top = 300; const top = 550;
this.bank.forEach((l, i) => { this.bank.forEach((l, i) => {
const col = i % COLS; const col = i % COLS;