1

我想我已经接近这个了,但是在弄清楚我所缺少的具体内容时遇到了一些困难。我正在尝试在 Canvas 中进行“像素完美”的碰撞检测。该代码在 Github https://github.com/AlexChesser/jsSpritehttp://chesser.ca/jsSprite/13-more-pixel-detection.php中可用

假设我已经确定正在发生微不足道的碰撞,下一阶段是检查重叠区域的像素级别。

到目前为止,我的测试代码是:

        // Ok, compute the rectangle of overlap:            
        if (bottom1 > bottom2)  {   over_bottom = bottom2; 
        } else {                    over_bottom = bottom1; }

        if (top1 < top2)        {   over_top = top2; 
        } else {                    over_top = top1; }

        if (right1 > right2)    {   over_right = right2; 
        } else {                    over_right = right1; }

        if (left1 < left2)      {   over_left = left2; 
        } else {                    over_left = left1; }

        if (Sprite.debug == 1) {
            // again for the purposes of global debuggery I thought it'd be nice to be able to 
            // draw the area of overlap, but without ruining all other tests
            MainContext.fillStyle = "rgb(200,0,0)";
            MainContext.fillRect (over_left, over_top, over_right-over_left, over_bottom-over_top);
        }
        overlap_width = over_right-over_left;
        overlap_height = over_bottom-over_top;

        if (Sprite.Xpos > obj.Xpos) {
            // read the data start at the sprite's right side
            var sprite_data_x_start = Sprite.Xpos   +Sprite.width   -overlap_width;
            var obj_data_x_start    = obj.Xpos;
        } else {
            // read the data from the sprites left.
            var sprite_data_x_start = Sprite.Xpos;
            var obj_data_x_start    = obj.Xpos  +obj.width          -overlap_width;             
        }

        if (Sprite.Ypos > obj.Ypos) {
            // read the data start at the sprite's right side
            var sprite_data_y_start = Sprite.Ypos   +Sprite.height  -overlap_height;
            var obj_data_y_start    = obj.Ypos;
        } else {
            // read the data from the sprites left.
            var sprite_data_y_start = Sprite.Ypos;
            var obj_data_y_start    = obj.Ypos  +obj.height         -overlap_height;                
        }


        // 1. get the coordinates of the overlapped area for box object1
        // 2. get the coordinates of the overlapped area for this Sprite
        // 3. get the data for each into an array using GETIMAGEDATA
        //      eg:
        var sprite_overlap_image = Sprite.ctx.getImageData( sprite_data_x_start, 
                                                            sprite_data_y_start, 
                                                            overlap_width, 
                                                            overlap_height);
        var obj_overlap_image = obj.ctx.getImageData(       obj_data_x_start, 
                                                            obj_data_y_start, 
                                                            overlap_width, 
                                                            overlap_height);


        //soid  = sprite_overlap_image.data;
        soid = sprite_overlap_image;
        GlobalWatchSOID = sprite_overlap_image;
        GlobalWatchOOID = obj_overlap_image;            
        ooid    = obj_overlap_image;

        //MainContext.putImageData(sprite_overlap_image.data, 100, 100);
        //MainContext.putImageData(obj_overlap_image.data,  400, 400);

        for (idx in soid.data) {
            if (!isNaN(idx)) {
                if ((soid.data[idx] == 0 && ooid.data[idx] == 0)) {
                    return true;
                    //console.log(idx + ' ' + soid.data[idx] + ' omg hit! ' + ooid.data[idx]);
                }
            }
        }
        return false;           

Through inspecting the DOM in the Chrome Debugger, I know that I'm definitely able to loop through each pixel in the image, what I'm not able to figure out is why my comparison of the pixel in array1 at index and the pixel in array2 never seem to overlap.

Can anyone see the spot where I'm going wrong? Maybe there's a logical error in here somewhere, perhaps I'm not reading in the squares that I think I'm getting or something.

I'll keep hammering away and update if I find but more often than not, Stack's a lot smarter than me :)

4

1 回答 1

1

I've cracked it.

        if (Sprite.Xpos > obj.Xpos) {
            // read the data start at the sprite's right side
            //var sprite_data_x_start = Sprite.Xpos -Sprite.width   -overlap_width;
            var sprite_data_x_start = Sprite.width  -overlap_width;             
            var obj_data_x_start    = 0;
        } else {
            // read the data from the sprites left.
            var sprite_data_x_start = Sprite.Xpos;
            var obj_data_x_start    = 0         -overlap_width;             
        }

        if (Sprite.Ypos > obj.Ypos) {
            // read the data start at the sprite's right side
            var sprite_data_y_start = Sprite.height -overlap_height;
            var obj_data_y_start    = 0;
        } else {
            // read the data from the sprites left.
            var sprite_data_y_start = 0;
            var obj_data_y_start    = obj.height            -overlap_height;                
        }

I was pulling the wrong area of the individual canvas objects.

于 2011-04-29T00:50:43.037 回答