我正在创建一个基于Node.js / WebGL / Canvas / PIXI.js的视频游戏。
在这个游戏中,块具有通用尺寸:它们可以是圆形,多边形或一切。因此,我的物理引擎需要知道事物的确切位置,墙壁是什么像素,哪些像素不是。因为我认为PIXI不允许这样做,所以我创建了一个看不见的画布,在那里我放置了地图的所有墙壁图像。然后,我使用函数getImageData创建一个函数" isWall" at(x,y):
function isWall(x, y):
return canvas.getImageData(x, y, 1, 1).data[3] != 0;
然而,这非常慢(根据Chrome分析,它占用了游戏CPU时间的70%)。此外,由于我介绍了这个功能,我有时会得到错误"糟糕,WebGL崩溃"没有任何额外的建议。
有没有更好的方法来访问像素的值?我想把所有东西都存放在一个静态位数组中(墙壁有一个固定的大小),1对应一个墙,0对应一个非墙。在内存中有一个1000万个单元阵列是否合理?
答案 0 :(得分:2)
一些想法:
我确定为什么你需要10m存储在内存中,但它可行但是你需要使用类似四叉树的东西并将阵列分开,所以看起来效率很高像素状态。 IMO你只需要存储"比特"对于复杂的形状,您可以通过为每个形状定义多个区域来进一步限制它。对于更简单的形状,只需使用矢量(矩形,半径/距离)。经常进行性能测试以找到合适的平衡点。
在任何情况下 - 这些事情必须针对场景进行手动优化,因此这只是一个普遍的看法。其他因素会影响高速度,旋转,反射等方法,并且很快会变得非常宽泛。希望这会给出一些意见。
答案 1 :(得分:1)
我使用位数组来存储 0 || 1 信息,它运作良好。
信息存储紧凑,获取/设置非常快。
这是我使用的位库:
https://github.com/drslump/Bits-js/blob/master/lib/Bits.js
我没有尝试使用10m位,因此您必须在自己的数据集上进行尝试。
您提出的解决方案非常“平坦”,这意味着每个像素必须具有相应的位。这导致需要大量内存 - 即使信息存储为位。
替代测试数据范围,而不是测试每个像素:
如果墙像素数小于像素总数,您可以尝试将每个墙存储为一系列“运行”。例如,墙运行可能存储在这样的对象中(警告:未经测试的代码!):
// an object containing all horizontal wall runs
var xRuns={}
// an object containing all vertical wall runs
var yRuns={}
// define a wall that runs on y=50 from x=100 to x=185
// and then runs on x=185 from y=50 to y=225
var y=50;
var x=185;
if(!xRuns[y]){ xRuns[y]=[]; }
xRuns[y].push({start:100,end:185});
if(!yRuns[x]){ yRuns[x]=[]; }
yRuns[x].push({start:50,end:225});
然后你可以像这样快速测试墙上的[x,y](警告未经测试的代码!):
function isWall(x,y){
if(xRuns[y]){
var a=xRuns[y];
var i=a.length;
do while(i--){
var run=a[i];
if(x>=run.start && x<=run.end){return(true);}
}
}
if(yRuns[x]){
var a=yRuns[x];
var i=a.length;
do while(i--){
var run=a[i];
if(y>=run.start && y<=run.end){return(true);}
}
}
return(false);
}
这应该只需要很少的测试,因为x&amp; y确切地指定需要测试哪个xRuns和yRuns数组。
它可能(或可能不)比测试“平面”模型更快,因为有平面模型的指定元素的开销。你必须使用这两种方法进行性能测试。
壁挂式方法可能需要更少的内存。
希望这会有所帮助......请记住,墙上运行的选择只是我的头脑,可能需要调整; - )