Benjamin Horn
Original address: Pixel accurate collision detection with Javascript and Canvas
I'm developing a game that also uses collision detection. I usually use simple and efficient box model collision detection. The main principle of the box model is to abstract all objects into squares, and if two squares overlap, it is considered a collision. This is usually required for a simple game. But because of this model I have used many times before, I want to try some more profound and accurate methods.
I chose to see if there was a collision from the pixel level. First I want to understand what "pixels are". The transparency of the elements I tried was not 0, in other words, all visible pixels were seen as a collision point. To improve the efficiency of the algorithm, I pre-created a pixel map of a picture. In other words, an array contains all the visible pixels on the screen.
/*pseudo-code describing pixel graphs*/ varPixelmap = []; for(vary = 0; Y < Image.width; y++ ) { for(varx = 0; x < image.height; X + + ) { //gets the element of the current position varPixel = Ctx.getimagedata (x, Y, 1, 1 ); //check for opacity of not 0 if(pixel.data[3]! = 0{Pixelmap.push ({x:x, y:y}); } } } returnPixelmap;
In this way, a small picture can become very large. A picture of 40x40 will be 1600 pixels, so if I do a collision detection on a large canvas it will be very slow. I overlapped the box model before testing, and if the hit test returns true, I'll test further if there are any pixels overlapping. This means that we only need to test once.
/** * function hitbox (source, Target ) {/* */ return ! ( + source.height) < (TARGET.Y)) | | > (target.y + target.height)) | | + source.width) < Target.x) | | > (target.x + target.width)) ); }
If the Hitbox function returns True, we need to compare the pre-rendered pixel graph of two objects. Then we need to test whether each pixel of the source object overlaps with the image of the target object. This is a very time consuming and energy-intensive function.
。。。
/*pseudo-code for pixel collision detection*/ functionpixelhittest (source, target) {//all pixels of the loop source image for(vars = 0; s < source.pixelMap.length; s++ ) { varSourcepixel =Source.pixelmap[s]; //Add position offset varSourcearea ={x:sourcepixel.x+source.x, Y:sourcepixel.y+source.y, Width:1, Height:1 }; //loop all pixels of the target image for(vart = 0; T < Target.pixelMap.length; t++ ) { varTargetpixel =Target.pixelmap[t]; //Add position offset varTargetarea ={x:targetpixel.x+Target.x, Y:targetpixel.y+target.y, Width:1, Height:1 }; /*Use the Hitbox function mentioned earlier*/ if(Hitbox (Sourcearea, Targetarea)) {return true; } } } }
Not finished
Precise pixel collision detection using JavaScript and canvas