Javascript collision detection system does not ignore blocked conflicts

I am having problems developing a mini-game using EaselJS with my collision detection system and I need help. The problem arises when a hero (a bitmap of a circle) collides with an object and another object stands behind the first, the hero collides with both objects, even if the second collision is blocked. Here's an explanation of the image:

The cause of the problem is very simple, even if the problem itself is not:

( ), , , . , , - .

: , , - .


javascript:

                rects.forEach(function (rect) { // Affect all rects
                    // Collision detection:
                    // (This MUST BE after every change in xvel/yvel)

                    // Next circle position calculation:
                    var nextposx = circle.x + event.delta / 1000 * xvel * 20,
                        nextposy = circle.y + event.delta / 1000 * yvel * 20;

                    // Collision between objects (Rect and Circle):
                    if (nextposy + height(circle) > rect.y &&
                        nextposx + width(circle) > rect.x &&
                        nextposx < rect.x + rect.width &&
                        nextposy < rect.y + rect.height) {
                        if (circle.y + height(circle) < rect.y) {
                            cls("top");
                        }
                        if (circle.x + width(circle) < rect.x) {
                            cls("left");
                        }
                        if (circle.x > rect.x + rect.width) {
                            cls("right");
                        }
                        if (circle.y > rect.y + rect.height) {
                            cls("bottom");
                        }
                    }

                    // Stage collision:
                    if (nextposy < 0) { // Collided with TOP of stage. Trust me.
                        cls("bottom"); // Inverted collision side is proposital!
                    }
                    if (nextposx < 0) {
                        cls("right");
                    }
                    if (nextposx + width(circle) > stage.canvas.width) {
                        cls("left");
                    }
                    if (nextposy + height(circle) > stage.canvas.height) {
                        cls("top");
                    }
                });

JSFiddle

+4
2

.

JS-: http://jsfiddle.net/Kf6cv/1/ . :

if (nextposy + height(circle) > rect.y &&
    circle.x + width(circle) > rect.x &&
    circle.x < rect.x + rect.width &&
    nextposy < rect.y + rect.height) {
    if (circle.y + height(circle) < rect.y) {
       cls("top");
    }
    if (circle.y > rect.y + rect.height) {
        cls("bottom");
    }
}

if (nextposx + width(circle) > rect.x &&
    nextposx < rect.x + rect.width &&
    circle.y + height(circle) > rect.y &&
    circle.y < rect.y + rect.height) {
    if (circle.x + width(circle) < rect.x) {
        cls("left");
    }
    if (circle.x > rect.x + rect.width) {
        cls("right");
    }
}

, , , ( ) ( ) - . / , , "" 100% . , | velX | > | velY | .

, , , , - , , .

+2

, !

forEach forEach s: , , "-" , . , ( ).

:

function colhndlr(obj1, obj2array){
    var sidecollided = false;
    // Side-to-side collision handler:
    obj2array.forEach(function(obj2){
        // Top side:
        if(obj1.ypast + obj1.height < obj2.y &&
        obj1.y + obj1.height >= obj2.y &&
        // Checks if past position X was correct:
        obj1.xpast + obj1.width >= obj2.x &&
        obj1.xpast <= obj2.x + obj2.width){
            // Collided with top
        }

        // Left side:
        if(obj2.clsdir > 2 && // Checks if object is side-collideable
        obj1.xpast + obj1.width < obj2.x &&
        obj1.x + obj1.width >= obj2.x &&
        // Checks if past position Y was correct:
        obj1.ypast + obj1.height >= obj2.y &&
        obj1.ypast <= obj2.y + obj2.height){
            // Collided with left
        }

        // Right side:
        if(obj2.clsdir > 2 && // Checks if object is side-collideable
        obj1.xpast > obj2.x + obj2.width &&
        obj1.x <= obj2.x + obj2.width &&
        // Checks if past position Y was correct:
        obj1.ypast + obj1.height >= obj2.y &&
        obj1.ypast <= obj2.y + obj2.height){
            // Collided with right
        }

        // Bottom side:
        if(obj2.clsdir == 4 && // Checks if object is bottom-collideable
        obj1.ypast > obj2.y + obj2.height &&
        obj1.y <= obj2.y + obj2.height &&
        // Checks if past position X was correct:
        obj1.xpast + obj1.width >= obj2.x &&
        obj1.xpast <= obj2.x + obj2.width){
            // Collided with bottom
        }
    });

    /* 
    Now that every side-to-side collision change was made,
    the edge-to-edge collision handler will not detect 
    blocked collisions.
    */

    if(!sidecollided){
    // Edge-to-edge collision handler:
    obj2array.forEach(function(obj2){
        if(obj2.clsdir != 1){ // If it 1 then there no need for edge collisions
            // Top left edge:
            if(obj1.ypast + obj1.height < obj2.y &&
            obj1.xpast + obj1.width < obj2.x &&
            obj1.y + obj1.height >= obj2.y &&
            obj1.x + obj1.width >= obj2.x){
            // Collided with top left edge
            }

            // Top right edge:
            if(obj1.ypast + obj1.height < obj2.y &&
            obj1.xpast > obj2.x + obj2.width &&
            obj1.y + obj1.height >= obj2.y &&
            obj1.x <= obj2.x + obj2.width){
            // Collided with top right edge
            }

            // Bottom right edge:
            if(obj2.clsdir == 4 && // Checks if object is bottom collideable
            obj1.ypast > obj2.y + obj2.height &&
            obj1.xpast > obj2.x + obj2.width &&
            obj1.y <= obj2.y + obj2.height &&
            obj1.x <= obj2.x + obj2.width){
            // Collided with bottom right edge
            }

            // Bottom left edge:
            if(obj2.clsdir == 4 && // Checks if object is bottom collideable
            obj1.ypast > obj2.y + obj2.height &&
            obj1.xpast + obj1.width < obj2.x &&
            obj1.y <= obj2.y + obj2.height &&
            obj1.x + obj1.width >= obj2.x){
            // Collided with bottom left edge
            }
        }
    });
    }
}

JSFiddle

+2

Source: https://habr.com/ru/post/1531286/


All Articles