BreadBakingBonanza/src/systems/ButtonBarrierSystem.js

114 lines
3.8 KiB
JavaScript

import TilePropertyHelper, { COLOR_TILES } from './TilePropertyHelper.js';
export default class ButtonBarrierSystem {
/**
* @param {Phaser.Scene} scene
* @param {Phaser.Tilemaps.TilemapLayer} barriersLayer
*/
constructor(scene, barriersLayer) {
this._scene = scene;
this._barriersLayer = barriersLayer;
this._buttons = []; // [{ col, row, color }]
this._barriers = []; // [{ col, row, color }]
this._activeColor = null;
}
/**
* Scan the barriers layer to build button/barrier registries and set initial
* collision state. Call once after the layer is created.
*/
init() {
const layer = this._barriersLayer;
layer.forEachTile((tile) => {
if (tile.index <= 0) return;
const props = TilePropertyHelper.getPropsByGID(tile.index);
if (props.button) {
this._buttons.push({ col: tile.x, row: tile.y, color: props.color });
if (props.pressed) {
this._activeColor = props.color;
}
} else if (props.barrier) {
this._barriers.push({ col: tile.x, row: tile.y, color: props.color });
}
});
this._rebuildCollision();
}
/**
* Press the button at the given tile coordinates.
* Updates button/barrier tile indices and rebuilds collision.
* @param {number} col Tile column
* @param {number} row Tile row
*/
pressButton(col, row) {
const entry = this._buttons.find(b => b.col === col && b.row === row);
if (!entry) return;
if (entry.color === this._activeColor) return; // Already active
this._activeColor = entry.color;
// Update all button tiles
for (const btn of this._buttons) {
const gids = COLOR_TILES[btn.color];
const newGID = btn.color === this._activeColor ? gids.btn_on : gids.btn_off;
this._barriersLayer.putTileAt(newGID, btn.col, btn.row);
}
// Update all barrier tiles
for (const bar of this._barriers) {
const gids = COLOR_TILES[bar.color];
const newGID = bar.color === this._activeColor
? gids.barrier_open
: gids.barrier_solid;
this._barriersLayer.putTileAt(newGID, bar.col, bar.row);
}
this._rebuildCollision();
}
/**
* Returns true if the given GID is an unpressed button (a valid press target).
* @param {number} gid
*/
isButtonTile(gid) {
const props = TilePropertyHelper.getPropsByGID(gid);
return !!(props.button && !props.pressed);
}
/**
* Rebuild which tiles in the barriers layer have active collision.
* Solid: all unpressed buttons + all non-active-color solid barriers.
* Passable: active-color barriers + pressed button.
*/
_rebuildCollision() {
const solidGIDs = [];
for (const [color, gids] of Object.entries(COLOR_TILES)) {
if (color !== this._activeColor) {
solidGIDs.push(gids.btn_off);
solidGIDs.push(gids.barrier_solid);
}
// Active color's btn_on and barrier_open remain passable (not added)
}
// setCollision(indices, collides, recalculate)
// Passing false to a second call clears existing, then we set only solidGIDs
this._barriersLayer.setCollision(solidGIDs, true, true);
// Explicitly remove collision from active-color tiles (in case of leftovers)
if (this._activeColor) {
const gids = COLOR_TILES[this._activeColor];
this._barriersLayer.setCollision(
[gids.btn_on, gids.barrier_open],
false,
true
);
}
}
}