occluder.js
1.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// occluder.js — 遮挡片:背景像素按多边形裁出 + zIndex=baseY(移植自 pixi-stage.js addOccluder)。
//
// 不需额外素材,复用背景像素:把背景图按多边形裁出一块,放进人物 Y 排序层。
// 人物脚下 worldY < baseY(在它后面/更远)→ 被遮挡;> baseY(更近)→ 盖住它。
import { depthZIndex } from './geom.js'
/**
* 遮挡判定(纯函数,测试用):人物脚下 worldY 是否被 baseY 的遮挡片遮住。
* @param {number} actorWorldY
* @param {number} occluderBaseY
* @returns {boolean} true=被遮(actor 在遮挡片后面)
*/
export function isOccluded(actorWorldY, occluderBaseY) {
return depthZIndex(actorWorldY) < depthZIndex(occluderBaseY)
}
/**
* 用背景纹理按多边形裁出一块遮挡片,挂到 actorsLayer,zIndex=baseY。
* @param {Object} deps
* @param {*} deps.PIXI
* @param {*} deps.bgTexture 背景纹理(已就绪)
* @param {*} deps.actorsLayer Y 排序层容器
* @param {number} deps.worldW
* @param {number} deps.worldH
* @param {{polygon:number[][], baseY:number}} def polygon=[[x,y],...](世界坐标)
* @returns {*|null} 遮挡片容器;条件不满足返回 null
*/
export function createOccluder({ PIXI, bgTexture, actorsLayer, worldW, worldH }, def) {
const { polygon, baseY } = def || {}
if (!bgTexture || !polygon || polygon.length < 3) return null
const sprite = new PIXI.Sprite(bgTexture)
sprite.width = worldW
sprite.height = worldH
const mask = new PIXI.Graphics()
mask.poly(polygon.flat()).fill(0xffffff)
const cont = new PIXI.Container()
cont.addChild(sprite, mask)
sprite.mask = mask
cont.zIndex = depthZIndex(baseY) // 与人物 worldY 同一排序尺度
actorsLayer.addChild(cont)
return cont
}