43 lines
1.9 KiB
JavaScript
43 lines
1.9 KiB
JavaScript
import { config } from '../config/Config.js';
|
||
import { ensureUiCameras, assignWorld, assignUi } from '../visuals/UiCameras.js';
|
||
|
||
export { ensureUiCameras, assignWorld, assignUi };
|
||
|
||
/**
|
||
* The combat CAMERA KICK — a subtle world-camera shake on the big beats:
|
||
* you taking a hit, a hostile going down, the shield collapse.
|
||
*
|
||
* It fires on the WORLD camera only. The UI pass (js/visuals/UiCameras.js
|
||
* → `fx-ui`) renders the bar, feed, and gauge flashes on its own fixed
|
||
* pass, so the HUD stays perfectly still while the world kicks — that's
|
||
* the whole point of the split. Call `ensureUiCameras(scene)` at scene
|
||
* setup (both combat contexts do) so the split exists when the shake
|
||
* lands; without a split (a scene without cameras, the headless tests)
|
||
* this is a guarded no-op.
|
||
*
|
||
* Tuning: data/combat.json → combat.fx.shake — `hit` / `kill` / `break`
|
||
* are the Phaser shake intensities (a small FRACTION of the viewport,
|
||
* the same idiom as the tether contact's 0.003–0.007 in GameScene), and
|
||
* `ms` is the duration.
|
||
*/
|
||
|
||
/**
|
||
* @param {object} scene the combat scene
|
||
* @param {string} kind 'hit' | 'kill' | 'break' — the fx.shake.* intensity
|
||
* to use (the beat's weight: a player hit < an enemy kill < the
|
||
* shield-collapse)
|
||
*/
|
||
export function combatShake(scene, kind = 'hit') {
|
||
const cam = scene?.cameras?.main;
|
||
if (!cam || typeof cam.shake !== 'function') return;
|
||
const fallback = { hit: 0.0045, kill: 0.007, break: 0.011 }[kind] ?? 0.005;
|
||
const intensity = Number(config.get(`combat.fx.shake.${kind}`, fallback));
|
||
if (!Number.isFinite(intensity) || intensity <= 0) return;
|
||
const ms = Math.max(60, Number(config.get('combat.fx.shake.ms', 230)) || 230);
|
||
// The UI split (once) so the kick hits the WORLD pass only — the bar,
|
||
// feed, and gauge flashes render on the untouched `fx-ui` pass and stay
|
||
// perfectly still. (Idempotent; null-safe for camera-less scenes.)
|
||
ensureUiCameras(scene);
|
||
cam.shake(ms, intensity);
|
||
}
|