Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
478 views
in Technique[技术] by (71.8m points)

javascript - HTML5, rendering pixels to image on load for faster draw times

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When you are using putImageDatayou 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...