Phaser 3 俯视角游戏手电筒效果:定向锥形光与阴影遮挡
Phaser 3 俯视角手电筒锥形光束与阴影实现
一、锥形光束的实现
Phaser 3 原生 Light2D 系统没有直接提供你描述的 directionalLight 锥形光束方法,但可以通过**点光源(PointLight)+ 几何遮罩(GeometryMask)**模拟出完全一致的效果,具体步骤如下:
- 创建基础点光源:
// x/y 为手电筒坐标,颜色白色,亮度1,光照范围200(可按需调整) const flashlight = this.lights.addPointLight(x, y, 0xffffff, 1, 200);
- 绘制锥形遮罩图形:
// 自定义光束方向(例:90度向下)和宽度(例:60度) const direction = 90; const beamWidth = 60; const beamShape = this.make.graphics({ add: false }); beamShape.fillStyle(0xffffff); beamShape.beginPath(); beamShape.moveTo(0, 0); // 遮罩原点与手电筒位置对齐 // 计算锥形的两个边缘角度 const angleRad = Phaser.Math.DegToRad(direction); const halfBeamRad = Phaser.Math.DegToRad(beamWidth / 2); // 绘制锥形的两个端点(长度200可按需调整) beamShape.lineTo( Math.cos(angleRad - halfBeamRad) * 200, Math.sin(angleRad - halfBeamRad) * 200 ); beamShape.lineTo( Math.cos(angleRad + halfBeamRad) * 200, Math.sin(angleRad + halfBeamRad) * 200 ); beamShape.closePath(); beamShape.fillPath();
- 用容器承载光源并应用遮罩:
const flashlightContainer = this.add.container(x, y); flashlightContainer.add(flashlight); // 仅显示遮罩范围内的光照,实现锥形光束效果 flashlightContainer.setMask(new Phaser.Display.Masks.GeometryMask(this, beamShape)); // 后续移动手电筒时,直接更新容器坐标即可 // flashlightContainer.setPosition(newX, newY);
二、物体遮挡与阴影实现
Phaser 3 原生 Light2D 不支持实时阴影投射,你可以通过以下两种方式实现:
1. 自定义光线投射实现
通过射线检测模拟光束的碰撞遮挡:
- 从手电筒位置向锥形范围内发射多条射线,检测与场景中碰撞体(如静态物理对象)的交点
- 根据这些交点绘制阴影多边形,覆盖在光照图层上,模拟被遮挡区域
核心思路代码:
// 假设场景中有物理碰撞组 obstacles const raysCount = 20; // 射线数量越多,阴影边缘越平滑 const angleStep = beamWidth / raysCount; const shadowShape = this.make.graphics({ add: false }); for (let i = 0; i <= raysCount; i++) { const rayAngle = direction - beamWidth/2 + angleStep * i; const ray = this.physics.add.raycaster(x, y).rayAngle(Phaser.Math.DegToRad(rayAngle), 200); const hits = ray.cast(obstacles); let hitX, hitY; if (hits.length > 0) { hitX = hits[0].point.x; hitY = hits[0].point.y; } else { hitX = x + Math.cos(Phaser.Math.DegToRad(rayAngle)) * 200; hitY = y + Math.sin(Phaser.Math.DegToRad(rayAngle)) * 200; } i === 0 ? shadowShape.moveTo(hitX, hitY) : shadowShape.lineTo(hitX, hitY); } // 闭合阴影多边形并填充半透明黑色 shadowShape.lineTo(x, y); shadowShape.closePath(); shadowShape.fillStyle(0x000000, 0.8); shadowShape.fillPath(); // 将阴影添加到场景,置于光照图层下方 this.add.existing(shadowShape);
2. 使用第三方插件
可以使用 Phaser 3 Raycaster Plugin,它封装了成熟的射线检测逻辑,能更便捷地实现光线遮挡和阴影生成,无需手动处理大量射线细节。
内容的提问来源于stack exchange,提问作者MrToenails
相关产品推荐
相关产品推荐

