feat: add Chinese soundtrack to Mahjong and Mahjong Match games
- Register 'chinese' music override for mahjong and mahjongmatch in soundtrack config - Preload chinese-music.json in PreloadScene - Lazy-load Chinese music assets via asset manifest for both games - Update game scenes to use getGameSoundtrack() with volume support - Update mahjong match background images (01, 02)
This commit is contained in:
parent
386ad3efb7
commit
cfbf1032bf
Binary file not shown.
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 2.7 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 3.0 MiB |
|
|
@ -131,13 +131,21 @@ export const MANIFEST = {
|
||||||
sheet('jello-items', 'assets/images/jello-items.png', 132, 132),
|
sheet('jello-items', 'assets/images/jello-items.png', 132, 132),
|
||||||
image('bg-puddingmonsters-menu', 'assets/images/background-jello.png'),
|
image('bg-puddingmonsters-menu', 'assets/images/background-jello.png'),
|
||||||
],
|
],
|
||||||
mahjong: MAHJONG_TILES,
|
mahjong: [
|
||||||
|
...MAHJONG_TILES,
|
||||||
|
// chinese soundtrack (see services/soundtrack.js) — lazy-loaded here so
|
||||||
|
// its audio only downloads once Mahjong is actually entered.
|
||||||
|
(scene) => musicFrom(scene, 'chinese-music'),
|
||||||
|
],
|
||||||
mahjongmatch: [
|
mahjongmatch: [
|
||||||
...MAHJONG_TILES,
|
...MAHJONG_TILES,
|
||||||
// Carries its own title, so the layout-select screen draws no heading.
|
// Carries its own title, so the layout-select screen draws no heading.
|
||||||
image('bg-mahjongmatch-menu', 'assets/images/background-mahjongmatch.png'),
|
image('bg-mahjongmatch-menu', 'assets/images/background-mahjongmatch.png'),
|
||||||
// In-play backdrops — one is picked at random per game.
|
// In-play backdrops — one is picked at random per game.
|
||||||
...['01', '02', '03'].map((n) => image(`bg-mm-${n}`, `assets/images/background-mm-${n}.png`)),
|
...['01', '02', '03'].map((n) => image(`bg-mm-${n}`, `assets/images/background-mm-${n}.png`)),
|
||||||
|
// chinese soundtrack (see services/soundtrack.js) — lazy-loaded here so
|
||||||
|
// its audio only downloads once Mahjong Match is actually entered.
|
||||||
|
(scene) => musicFrom(scene, 'chinese-music'),
|
||||||
],
|
],
|
||||||
spireclimb: [
|
spireclimb: [
|
||||||
image('spireclimb-act1', 'assets/images/spireclimb-act1.png'),
|
image('spireclimb-act1', 'assets/images/spireclimb-act1.png'),
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import { api } from '../../services/api.js';
|
||||||
import { createOpponentPortrait, createPlayerPortrait } from '../../ui/Portrait.js';
|
import { createOpponentPortrait, createPlayerPortrait } from '../../ui/Portrait.js';
|
||||||
import { playSound, SFX } from '../../ui/Sounds.js';
|
import { playSound, SFX } from '../../ui/Sounds.js';
|
||||||
import { MusicPlayer } from '../../ui/MusicPlayer.js';
|
import { MusicPlayer } from '../../ui/MusicPlayer.js';
|
||||||
|
import { getGameSoundtrack } from '../../services/soundtrack.js';
|
||||||
import {
|
import {
|
||||||
TILES, SUIT_NAMES, WIND_NAMES, rankOf, isSuited,
|
TILES, SUIT_NAMES, WIND_NAMES, rankOf, isSuited,
|
||||||
FAAN_TABLE, MIN_FAAN, PLAYER_COLOR_HEX,
|
FAAN_TABLE, MIN_FAAN, PLAYER_COLOR_HEX,
|
||||||
|
|
@ -76,7 +77,10 @@ export default class MahjongGame extends Phaser.Scene {
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
try { new MusicPlayer(this, this.cache.json.get('music')?.tracks ?? []); } catch { /* optional */ }
|
try {
|
||||||
|
const { tracks, volume } = getGameSoundtrack(this);
|
||||||
|
if (tracks.length) new MusicPlayer(this, tracks, volume);
|
||||||
|
} catch { /* optional */ }
|
||||||
this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, FELT).setDepth(DEPTH.bg);
|
this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, FELT).setDepth(DEPTH.bg);
|
||||||
|
|
||||||
const names = [auth.user?.username ?? 'You'];
|
const names = [auth.user?.username ?? 'You'];
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import * as Phaser from 'phaser';
|
||||||
import { GAME_WIDTH, GAME_HEIGHT, COLORS } from '../../config.js';
|
import { GAME_WIDTH, GAME_HEIGHT, COLORS } from '../../config.js';
|
||||||
import { Button } from '../../ui/Button.js';
|
import { Button } from '../../ui/Button.js';
|
||||||
import { MusicPlayer } from '../../ui/MusicPlayer.js';
|
import { MusicPlayer } from '../../ui/MusicPlayer.js';
|
||||||
|
import { getGameSoundtrack } from '../../services/soundtrack.js';
|
||||||
import { playSound, playSoundEx, SFX } from '../../ui/Sounds.js';
|
import { playSound, playSoundEx, SFX } from '../../ui/Sounds.js';
|
||||||
import { api } from '../../services/api.js';
|
import { api } from '../../services/api.js';
|
||||||
import {
|
import {
|
||||||
|
|
@ -81,8 +82,8 @@ export default class MahjongMatchGame extends Phaser.Scene {
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
try {
|
try {
|
||||||
const music = this.cache.json.get('music');
|
const { tracks, volume } = getGameSoundtrack(this);
|
||||||
if (music?.tracks) new MusicPlayer(this, music.tracks);
|
if (tracks.length) new MusicPlayer(this, tracks, volume);
|
||||||
} catch (_) { /* optional */ }
|
} catch (_) { /* optional */ }
|
||||||
|
|
||||||
this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, FELT).setDepth(D.bg);
|
this.add.rectangle(GAME_WIDTH / 2, GAME_HEIGHT / 2, GAME_WIDTH, GAME_HEIGHT, FELT).setDepth(D.bg);
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ export default class PreloadScene extends Phaser.Scene {
|
||||||
this.load.json('arcadedark-music', 'data/arcadedark-music.json');
|
this.load.json('arcadedark-music', 'data/arcadedark-music.json');
|
||||||
this.load.json('hacker-music', 'data/hacker-music.json');
|
this.load.json('hacker-music', 'data/hacker-music.json');
|
||||||
this.load.json('adventure-music', 'data/adventure-music.json');
|
this.load.json('adventure-music', 'data/adventure-music.json');
|
||||||
|
this.load.json('chinese-music', 'data/chinese-music.json');
|
||||||
this.load.json('advancewars-artwork', 'data/advancewars-artwork.json');
|
this.load.json('advancewars-artwork', 'data/advancewars-artwork.json');
|
||||||
this.load.json('tetrisattack-artwork', 'data/tetrisattack-artwork.json');
|
this.load.json('tetrisattack-artwork', 'data/tetrisattack-artwork.json');
|
||||||
this.load.json('totalannihilation-artwork', 'data/totalannihilation-artwork.json');
|
this.load.json('totalannihilation-artwork', 'data/totalannihilation-artwork.json');
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@ export const GAME_SOUNDTRACK_OVERRIDES = {
|
||||||
dotlink: 'hacker',
|
dotlink: 'hacker',
|
||||||
'2048': 'hacker',
|
'2048': 'hacker',
|
||||||
swdbg: 'adventure',
|
swdbg: 'adventure',
|
||||||
spireclimb: 'adventure'
|
spireclimb: 'adventure',
|
||||||
|
mahjong: 'chinese',
|
||||||
|
mahjongmatch: 'chinese',
|
||||||
};
|
};
|
||||||
|
|
||||||
// Resolve the track list (and optional volume override) a game scene's
|
// Resolve the track list (and optional volume override) a game scene's
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue