我正在创建一个基于Node.js/WebGL/画布/PIXI.js的电子游戏。
在这个游戏中,块有一个通用的大小:它们可以是圆圈、多边形或任何东西。所以,我的物理引擎需要知道物体的确切位置,墙壁是什么像素,什么像素不是。因为我认为PIXI不允许这样做,所以我创造了一个看不见的画布,在那里我把墙上的地图图像都放进去了。然后,我使用函数getImageData在(x,y)处创建一个函数"isWall“:
function isWall(x, y):
return canvas.getImageData(x, y, 1, 1).data[3] != 0;
然而,这是非常缓慢的(根据Chrome分析,它占用了游戏CPU时间的70% )。而且,由于我引入了这个函数,我有时会在没有任何其他建议的情况下得到错误"Oops,WebGL崩溃“。
是否有更好的方法来访问像素的值?我想把所有的东西都存储在一个静态的位数组中(墙有固定的大小),其中一个对应于一个墙,一个对应于一个非墙。在内存中有一个1000万个单元的数组合理吗?
发布于 2015-02-12 03:34:23
我使用位数组来存储0 \x\ 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&y准确地指定了需要测试的xRuns和yRuns数组。
它可能(或不可能)比测试“平面”模型更快,因为访问平面模型的指定元素需要开销。你必须使用这两种方法进行测试。
墙壁运行的方法可能需要更少的内存。
希望这个helps...Keep在我的脑海中--墙壁运行的替代方案--刚刚结束,可能需要调整一下;-)
发布于 2015-02-13 21:18:58
一些想法:
我知道为什么你需要10百万存储在内存中,虽然这是可行的,但你需要使用类似四叉树的东西,然后把数组分开,这样才能有效地查找像素状态。IMO您只需要存储复杂形状的“位”,并且可以通过定义每个形状的多个区域来进一步限制它。对于简单的形状,只需使用向量(矩形、半径/距离)。经常进行性能测试以找到正确的平衡。
在任何情况下-这类事情必须手工优化的非常场景,所以这只是一个一般性的看法。其他因素会影响该方法,如高速、旋转、反射等,并且很快就会变得非常广泛。希望这能提供一些投入。
https://stackoverflow.com/questions/28468202
复制相似问题