feat(advancewars): show terrain backdrop in capture cut-in instead of plain rectangle

Replace the solid-color ground rectangle in the capture animation with a
proper terrain backdrop matching the ground the building sits on (plain,
shoal, etc.). Extract battleBgFrame, ensureBattleBgSheet, and add a new
groundBgFrame helper that maps building types to their underlying terrain,
avoiding duplicate building rendering since the building is already the
main squishing prop.
This commit is contained in:
Brian Fertig 2026-07-19 16:31:33 -06:00
parent a02e5a1913
commit 427aacae6f
2 changed files with 26 additions and 5 deletions

View File

@ -31,15 +31,28 @@ const BG_SHEET_KEY = 'advancewars-battlebg';
// matter for a static background behind a fighter. // matter for a static background behind a fighter.
const TERRAIN_TO_BG = { bridgeh: 'bridge', bridgev: 'bridge' }; const TERRAIN_TO_BG = { bridgeh: 'bridge', bridgev: 'bridge' };
function battleBgFrame(terrainId) { export function battleBgFrame(terrainId) {
const key = TERRAIN_TO_BG[terrainId] ?? terrainId; const key = TERRAIN_TO_BG[terrainId] ?? terrainId;
const i = BATTLE_BG_KEYS.indexOf(key); const i = BATTLE_BG_KEYS.indexOf(key);
return i < 0 ? BATTLE_BG_KEYS.indexOf('plain') : i; return i < 0 ? BATTLE_BG_KEYS.indexOf('plain') : i;
} }
// The engine has no separate "terrain underneath the building" value (a
// tile only ever has one terrain id), so this is an editorial pick of what
// a given building would plausibly sit on, used where a scene wants the
// bare ground rather than the building's own backdrop (e.g. the capture
// cut-in, which already shows the building itself as its squishing prop).
const BUILDING_GROUND_TERRAIN = {
city: 'plain', base: 'plain', airport: 'plain', hq: 'plain', port: 'shoal',
};
export function groundBgFrame(terrainId) {
return battleBgFrame(BUILDING_GROUND_TERRAIN[terrainId] ?? terrainId);
}
// Painted sheet if loaded, else a generated stand-in with the same frame // Painted sheet if loaded, else a generated stand-in with the same frame
// map — mirrors the pattern in AdvanceWarsMapView.js's ensureSheets(). // map — mirrors the pattern in AdvanceWarsMapView.js's ensureSheets().
function ensureBattleBgSheet(scene) { export function ensureBattleBgSheet(scene) {
if (scene.textures.exists(BG_SHEET_KEY)) return BG_SHEET_KEY; if (scene.textures.exists(BG_SHEET_KEY)) return BG_SHEET_KEY;
const procKey = `${BG_SHEET_KEY}-proc`; const procKey = `${BG_SHEET_KEY}-proc`;
if (!scene.textures.exists(procKey)) paintProceduralBattleBg(scene, procKey); if (!scene.textures.exists(procKey)) paintProceduralBattleBg(scene, procKey);

View File

@ -8,6 +8,7 @@ import { GAME_WIDTH, GAME_HEIGHT } from '../../config.js';
import * as Logic from './AdvanceWarsLogic.js'; import * as Logic from './AdvanceWarsLogic.js';
import { armyColorInt } from './AdvanceWarsMapView.js'; import { armyColorInt } from './AdvanceWarsMapView.js';
import { FONT } from './AdvanceWarsUI.js'; import { FONT } from './AdvanceWarsUI.js';
import { ensureBattleBgSheet, groundBgFrame } from './AdvanceWarsBattleAnim.js';
const W = 380; const W = 380;
const H = 500; const H = 500;
@ -41,10 +42,17 @@ export function playCaptureAnim(scene, rules, view, capturing, captured, onDone)
.setStrokeStyle(3, 0x3a4260).setDepth(50); .setStrokeStyle(3, 0x3a4260).setDepth(50);
objs.push(dim, panel); objs.push(dim, panel);
// backdrop is the terrain the building itself sits on (plain/shoal/etc),
// not the building's own battle background — the building is already the
// scene's main squishing prop, so showing its backdrop too would just be
// a duplicate building rendered twice.
const bgSheet = ensureBattleBgSheet(scene);
const backdrop = scene.add.image(cx, cy, bgSheet, groundBgFrame(t.id))
.setDisplaySize(W - 6, H - 6).setDepth(50.3);
objs.push(backdrop);
const groundCenterY = cy + H / 2 - 50; const groundCenterY = cy + H / 2 - 50;
const ground = scene.add.rectangle(cx, groundCenterY, W - 60, 80, 0x27324a, 1).setDepth(50); const groundY = groundCenterY - 40; // where the building's base sits
objs.push(ground);
const groundY = groundCenterY - 40; // top edge of the ground strip
const label = scene.add.text(cx, cy - H / 2 + 30, (t.name ?? 'Property').toUpperCase(), const label = scene.add.text(cx, cy - H / 2 + 30, (t.name ?? 'Property').toUpperCase(),
{ fontFamily: FONT, fontSize: '26px', color: '#ffffff' }).setOrigin(0.5, 0.5).setDepth(51); { fontFamily: FONT, fontSize: '26px', color: '#ffffff' }).setOrigin(0.5, 0.5).setDepth(51);