You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phaser 3 俯视角游戏手电筒效果:定向锥形光与阴影遮挡

Phaser 3 俯视角手电筒锥形光束与阴影实现

一、锥形光束的实现

Phaser 3 原生 Light2D 系统没有直接提供你描述的 directionalLight 锥形光束方法,但可以通过**点光源(PointLight)+ 几何遮罩(GeometryMask)**模拟出完全一致的效果,具体步骤如下:

  1. 创建基础点光源:
// x/y 为手电筒坐标,颜色白色,亮度1,光照范围200(可按需调整)
const flashlight = this.lights.addPointLight(x, y, 0xffffff, 1, 200);
  1. 绘制锥形遮罩图形:
// 自定义光束方向(例: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();
  1. 用容器承载光源并应用遮罩:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 14:40:48