问题
I have a map that is a per pixel terrain. If you draw these pixels individually, it takes a lot of render time.
So my idea is to draw them in blocks of 100x100 images when the pixels are changed, and render those images.
The pixels in "chunk" is stored in a 1D array in the form index = x+y*width.
var img = game.c.createImageData(CHUNK_SIZE,CHUNK_SIZE);
for (var i=0;i<chunk.map.length;i++){
var p = chunk.map[i];
if (p){
img.data[i*4] = 255;
img.data[i*4+1] = 0;
img.data[i*4+2] = 0;
img.data[i*4+3] = 255;
}else{
img.data[i*4] = 0;
img.data[i*4+1] = 0;
img.data[i*4+2] = 0;
img.data[i*4+3] = 0;
}
}
this.render.push({x:chunk.x,y:chunk.y,img:img});
Draw:
for (var i=0;i<this.map.render.length;i++){
var img = this.map.render[i];
if (img.x*CHUNK_SIZE > this.player.x - (this.ce.width/2)){
if (img.y*CHUNK_SIZE > this.player.y -(this.ce.height/2)){
if ((img.x*CHUNK_SIZE)+CHUNK_SIZE < this.player.x + (this.ce.width/2)){
if ((img.y*CHUNK_SIZE)+CHUNK_SIZE < this.player.y + (this.ce.height/2)){
console.log("Rendering chunk...");
this.c.putImageData(img.img,(img.x*CHUNK_SIZE)-this.player.x,(img.y*CHUNK_SIZE)-this.player.y);
}
}
}
}
}
It is, however, not rendering correctly: The box has some transparent pixels, which makes the canvas transparent when there should be a sky gradient.
I want to write the image so transparent shows what was there (the sky gradient), and not make a hole in the canvas
回答1:
When you are using putImageData
you are simply replacing all pixels for that area (including the alpha channel), no mixing takes place.
The better approach would be to store your chunks as off-screen canvases (or images/sprites) and use drawImage
to draw them onto your main canvas.
Not only will this preserve existing pixels (depending on composite mode if that is changed) but it will also be faster than using putImageData
.
If you should still insist on using putImageData
you would need to first do a getImageData
for the existing content, then iterate through all pixels and mix the pixels from you chunk with the data you got from main canvas according to their alpha value and finally put the result of that back on canvas. This is a very costly operation.
来源:https://stackoverflow.com/questions/18964775/html5-rendering-pixels-to-image-on-load-for-faster-draw-times