| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| const ROOF_TILE = 48; |
|
|
| class RoofFadeSystem { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| constructor(scene, roofKey, worldW, worldH, visualRect, triggerRects, opts = {}) { |
| const T = opts.tileSize ?? ROOF_TILE; |
| this._fadeSpeed = opts.fadeSpeed ?? 4.8; |
| this._alpha = 1.0; |
|
|
| const toPx = ([zx, zy, zw, zh]) => ({ |
| x: zx * T, y: zy * T, |
| right: (zx + zw) * T, |
| bottom: (zy + zh) * T, |
| }); |
|
|
| |
| this._triggers = triggerRects.map(toPx); |
| this._excludes = (opts.excludeRects || []).map(toPx); |
|
|
| |
| this.roof = scene.add.image(0, 0, roofKey) |
| .setOrigin(0, 0) |
| .setDisplaySize(worldW, worldH) |
| .setDepth(opts.roofDepth ?? 8); |
|
|
| |
| const [vx, vy, vw, vh] = visualRect; |
| const clipG = scene.make.graphics({ add: false }); |
| clipG.fillStyle(0xffffff); |
| clipG.fillRect(vx * T, vy * T, vw * T, vh * T); |
| this.roof.setMask(clipG.createGeometryMask()); |
| } |
|
|
| _inRect(px, py, r) { |
| return px >= r.x && px < r.right && py >= r.y && py < r.bottom; |
| } |
|
|
| _isInside(px, py) { |
| let underRoof = false; |
| for (const t of this._triggers) { |
| if (this._inRect(px, py, t)) { underRoof = true; break; } |
| } |
| if (!underRoof) return false; |
| for (const e of this._excludes) { |
| if (this._inRect(px, py, e)) return false; |
| } |
| return true; |
| } |
|
|
| |
| |
| |
| |
| |
| update(px, py, dt) { |
| const target = this._isInside(px, py) ? 0.0 : 1.0; |
| const step = (dt / 1000) * this._fadeSpeed; |
|
|
| if (this._alpha < target) { |
| this._alpha = Math.min(this._alpha + step, target); |
| } else if (this._alpha > target) { |
| this._alpha = Math.max(this._alpha - step, target); |
| } |
|
|
| if (this._alpha < 0.004) this._alpha = 0; |
| if (this._alpha > 0.996) this._alpha = 1; |
|
|
| this.roof.setAlpha(this._alpha); |
| } |
|
|
| get isFullyOpen() { return this._alpha === 0; } |
| get isFullyClosed() { return this._alpha === 1; } |
|
|
| destroy() { this.roof?.destroy(); } |
| } |
|
|