Беда с идеальными пиксельными столкновениями с холстом в html5 - PullRequest
1 голос
/ 22 апреля 2011

Я думаю, что я близок к этому, но мне трудно определиться, что именно мне не хватает. Я пытаюсь сделать «идеальное по пикселям» обнаружение столкновений в Canvas. Код доступен в Github https://github.com/AlexChesser/jsSprite и http://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;           

Изучая DOM в Chrome Debugger, я знаю, что определенно могу циклически проходить через каждый пиксель в изображении, но я не могу понять, почему мое сравнение пикселя в array1 в index и кажется, что пиксель в массиве 2 никогда не перекрывается.

Может кто-нибудь увидеть место, где я иду не так? Может быть, где-то здесь есть логическая ошибка, возможно, я не читаю в квадратах, которые, как мне кажется, я получаю, или что-то в этом роде.

Я буду продолжать работать и обновляться, если найду, но чаще всего, стек намного умнее меня:)

1 Ответ

1 голос
/ 29 апреля 2011

Я взломал его.

        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;                
        }

Я потянул неправильную область отдельных объектов холста.

...