当前位置: 首页
前端开发
如何在JavaScript中实现基于旋转视野的FOV射线绘制详解

如何在JavaScript中实现基于旋转视野的FOV射线绘制详解

热心网友 时间:2026-07-01
转载

如果用一句话概括核心,那就是:在 RayCasting 游戏开发中,绘制动态视野边界线(FOV)最可靠的方式是在逻辑层通过数学公式将坐标“算”出来,而不是依赖 Canvas 绘图上下文的旋转操作。

在实现类似 Doom 风格的 RayCasting 游戏时,动态视野(Field of View, FOV)是一个关键的视觉元素。通常表现为从玩家视角出发、沿着角色朝向左右两侧展开的两条射线,模拟人眼或摄像机的可视锥形区域。然而,有一个常见的误区:直接调用 ctx.rotate() 虽然能快速旋转绘图坐标系,却不会更新原始几何数据。这样一来,后续的碰撞检测、光线投射或 UI 定位都会出现问题——因为它们依赖的坐标并没有真正改变。因此,坐标变换必须在逻辑层完成,不能只让渲染层“看起来正确”。

核心思路非常简洁:将立方体(例如玩家角色对应的方块)的局部顶点坐标,绕其中心点按照当前朝向角(弧度制)进行二维平面旋转变换。标准的旋转公式如下(以点 P(x,y) 绕中心 C(cx,cy) 逆时针旋转 θ 弧度为例):

function rotatePoint(point, center, angleRad) {
  const dx = point.x - center.x;
  const dy = point.y - center.y;
  return {
    x: center.x + dx * Math.cos(angleRad) - dy * Math.sin(angleRad),
    y: center.y + dx * Math.sin(angleRad) + dy * Math.cos(angleRad)
  };
}

假设玩家实体是一个宽高均为 size 的正方形,左上角位于 (this.x, this.y),那么它的四个顶点分别是:左上、右上、右下、左下。视野通常取自前向两侧的边缘,例如将右上角和左上角作为 FOV 的起始点(相当于“眼睛”位于顶部中点,视野张角由这两个点张开)。首先确定旋转中心——比如取顶部中点 cCenter = {x: this.x + size/2, y: this.y}——然后对两个关键顶点应用旋转函数:

const cCenter = { x: this.x + this.width / 2, y: this.y };
const rightTop = { x: this.x + this.width, y: this.y };
const leftTop  = { x: this.x, y: this.y };
const rotatedRight = this.rotatePoint(rightTop, cCenter, this.radians());
const rotatedLeft  = this.rotatePoint(leftTop,  cCenter, this.radians());

// 绘制 FOV 射线:从中心出发,延伸至足够远(比如 300px)
const length = 300;
const fovRightX = cCenter.x + (rotatedRight.x - cCenter.x) * (length / Math.hypot(rotatedRight.x - cCenter.x, rotatedRight.y - cCenter.y));
const fovRightY = cCenter.y + (rotatedRight.y - cCenter.y) * (length / Math.hypot(rotatedRight.x - cCenter.x, rotatedRight.y - cCenter.y));
const fovLeftX = cCenter.x + (rotatedLeft.x - cCenter.x) * (length / Math.hypot(rotatedLeft.x - cCenter.x, rotatedLeft.y - cCenter.y));
const fovLeftY = cCenter.y + (rotatedLeft.y - cCenter.y) * (length / Math.hypot(rotatedLeft.x - cCenter.x, rotatedLeft.y - cCenter.y));

// 渲染
this.desenho.beginPath();
this.desenho.strokeStyle = "#4a90e2";
this.desenho.moveTo(cCenter.x, cCenter.y);
this.desenho.lineTo(fovRightX, fovRightY);
this.desenho.moveTo(cCenter.x, cCenter.y);
this.desenho.lineTo(fovLeftX,  fovLeftY);
this.desenho.stroke();

有几个关键细节需要特别注意:

  • 角度单位this.radians() 必须返回弧度值。如果你存储的是角度,记得乘以 Math.PI / 180 进行转换。
  • 逻辑与渲染解耦:所有坐标计算应在 draw() 方法调用之前完成,确保逻辑层和渲染层各司其职,互不干扰。
  • 更真实的 FOV:如果需要固定的张角(例如 60°),可以独立定义视角半角 fovHalf = Math.PI / 6,然后以 cCenter 为原点、this.radians() 为基准方向,分别计算 ±fovHalf 方向的射线终点。这种方法不依赖模型顶点,更加灵活通用。
  • 性能优化:若对性能敏感,建议预缓存 Math.cosMath.sin 的值,避免每帧重复计算,提升渲染效率。

通过手动执行坐标旋转,你不仅获得了可预测、易调试的 FOV 几何数据,还为后续的光线投射、碰撞检测以及 HUD 对齐奠定了坚实的数据基础。归根结底,这才是 RayCasting 游戏底层可控性的关键所在。

来源:https://www.php.cn/faq/2735915.html

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
如何在JavaScript中实现基于旋转视野的FOV射线绘制详解

如何在JavaScript中实现基于旋转视野的FOV射线绘制详解

如果用一句话概括核心,那就是:在 RayCasting 游戏开发中,绘制动态视野边界线(FOV)最可靠的方式是在逻辑层通过数学公式将坐标“算”出来,而不是依赖 Canvas 绘图上下文的旋转操作。 在实现类似 Doom 风格的 RayCasting 游戏时,动态视野(Field of View, F

时间:2026-07-01 07:01
TypeScript后端数据正确映射为前端接口类型的方法

TypeScript后端数据正确映射为前端接口类型的方法

在后端数据与前端类型之间来回转换,几乎是每位 TypeScript 开发者都无法回避的常态。后端返回的 car_brand、reg_number,和前端接口中定义的 brand、govtNumber,命名风格常常对不上号。此时,如果为了省事直接用 as 类型断言“强行”指认类型,那就踩进了常见的陷阱

时间:2026-07-01 07:01
动态HTML表格按层级条件合并单元格的JavaScript实现

动态HTML表格按层级条件合并单元格的JavaScript实现

本文详细讲解一种递归式 JavaScript 合并单元格方法,用于按列优先级(如前3列)智能合并表格行:仅当前一列已合并的前提下,才允许后续列合并相同值,从而精准实现多级分组与层级表格合并效果。 在动态生成的 HTML 表格中,按业务逻辑合并重复行是常见需求。然而,简单地对单列分别遍历合并——例如先

时间:2026-07-01 07:01
Next.js 13+重定向后滚动失效解决方案

Next.js 13+重定向后滚动失效解决方案

在 Next js App Router 的日常开发中,有一个令人颇为困扰的异常现象——当服务端执行 `redirect()` 跳转后,目标页面竟然无法正常滚动。没错,页面已经渲染完成,内容也完整显示,但垂直滚动条仿佛凭空消失。这个问题在 Next js 13 5 4 版本中尤为突出。 先给出结论:

时间:2026-07-01 07:00
WebGL图像加载延迟的纹理初始化时立即显示方法

WebGL图像加载延迟的纹理初始化时立即显示方法

本文详细介绍如何利用 Promise 与 async await 重构 WebGL 纹理加载流程,彻底解决首次渲染显示蓝色占位色、需要手动交互才能刷新的问题,实现文件导入后四张纹理平面即时正确渲染。 实际上,这个坑在 WebGL 开发中相当常见——纹理异步加载的小陷阱,说起来不大,但第一次遇到确实令

时间:2026-07-01 07:00
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 日榜
  • 周榜
  • 月榜