javascript - JS Canvas 获取像素值非常频繁

标签 javascript canvas webgl pixi.js

我正在创建一个基于 Node.js/WebGL/Canvas/PIXI.js 的视频游戏。

在此游戏中, block 具有通用尺寸:它们可以是圆形、多边形或任何形状。因此,我的物理引擎需要知道物体到底在哪里,哪些像素是墙壁,哪些像素不是。因为我认为 PIXI 不允许这样做,所以我创建了一个不可见的 Canvas ,将 map 的所有墙壁图像放置在其中。然后,我使用函数 getImageData 在 (x, y) 处创建函数“isWall”:

function isWall(x, y):
    return canvas.getImageData(x, y, 1, 1).data[3] != 0;

但是,这非常慢(根据 Chrome 分析,它占用了游戏 70% 的 CPU 时间)。另外,由于我引入了此功能,有时我会收到错误“哎呀,WebGL 崩溃了”,而没有任何其他建议。

有没有更好的方法来访问像素的值?我考虑过将所有内容存储在静态位数组中(墙壁具有固定大小),其中 1 对应于墙壁,0 对应于非墙壁。内存中存在 1000 万个单元的数组是否合理?

最佳答案

一些想法:

  • 第一次检查:对所有对象使用碰撞区域。甚至可以根据形状(即复杂形状)为每一侧定义区域。仅检查相交区域内的碰撞。
  • 对 HitTest 位图使用一半分辨率(如果您的场景允许,甚至可以使用 25%)。当物体移动时,我们的大脑无法检测到像素精确的碰撞,因此可以利用这一点。
  • 对于复杂形状,存储其整个位图(基于其区域),但将其转换为单值类型数组,例如 Uint8Array高值和低值(重复使用它而不是通过上下文获取一和一像素)。减去对象的位置并将结果用作形状区域的增量,然后对“位图”进行 HitTest 。如果形状旋转,则相应地变换传入的检查点(这里可能有一个最佳点,其中更新位图比变换一堆点等更快。您需要测试您的场景)。
  • 对于接近正方形的物体,请做出折衷并使用简单的矩形检查
  • 对于圆形和椭圆形,使用非平方值来检查半径距离。
  • 在某些情况下,您也许可以使用在游戏开始之前以及在了解所有物体位置、方向和速度时计算的碰撞预测(计算完整的运动路径,找到这些路径的交点,计算到这些交叉路口的时间/距离)。如果您的对象由于其路径中的其他事件而改变方向等,这当然不会很好地工作(或者尝试看看重新计算是否有益)。

我确信为什么你需要 10m 存储在内存中,虽然这是可行的 - 但你需要使用四叉树之类的东西并将数组分开,这样查找像素状态就变得高效。在我看来,您只需要存储复杂形状的“位”,并且可以通过为每个形状定义多个区域来进一步限制它。对于更简单的形状,只需使用矢量(矩形、半径/距离)。经常进行性能测试以找到适当的平衡。

无论如何 - 此类事情必须针对特定场景进行手动优化,因此这只是一般情况。其他因素也会影响该方法,例如高速、旋转、反射等,并且它很快就会变得非常广泛。希望这能提供一些意见。

关于javascript - JS Canvas 获取像素值非常频繁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28468202/

相关文章:

javascript - 包含 foreignObject 的可滚动 SVG 中的错误

jquery - 如何使用 Jquery 导入 Canvas.js?

javascript - 使用lookAt在WebGL中创建旋转相机

algorithm - 无遮挡查询深度剥离

javascript - 无法删除克隆的元素

javascript - 无法在 JS 中字符串化对象数组

javascript - 在 Angularjs 中,嵌套在指令中的 Controller 可以设置指令的 ng-model 吗?

html - 在表格单元格中,居中 Canvas 元素而不是其兄弟元素

javascript - 在 HTML5 Canvas 上绘制矩形

three.js - 调整渲染器大小时 Threejs 渲染区域缩小到 25%