使用SAT实现冲突(画布、javascript)

使用SAT实现冲突(画布、javascript),javascript,canvas,collision,Javascript,Canvas,Collision,所以,我有这个,我已经做了一个非常好的SAT实现,它工作没有错误(至少我没有偶然发现任何错误): 此功能可降低列车速度,并将一些速度(calcSpeedIncrement(self,other))添加到撞车的列车上。我在直线轨道上得到了很好的碰撞效果,但是如果你继续向前推,一列火车就会在另一列火车上滑动。同样“滑倒”的另一个问题是当一列火车停在转弯处时发生碰撞 有人对如何解决这些问题有什么想法吗?我不会试图重新发明轮子,转而寻求现有的解决方案。你看过非常流行的2D物理引擎吗?在JavaScrip

所以,我有这个,我已经做了一个非常好的SAT实现,它工作没有错误(至少我没有偶然发现任何错误):

此功能可降低列车速度,并将一些速度(
calcSpeedIncrement(self,other)
)添加到撞车的列车上。我在直线轨道上得到了很好的碰撞效果,但是如果你继续向前推,一列火车就会在另一列火车上滑动。同样“滑倒”的另一个问题是当一列火车停在转弯处时发生碰撞


有人对如何解决这些问题有什么想法吗?

我不会试图重新发明轮子,转而寻求现有的解决方案。你看过非常流行的2D物理引擎吗?在JavaScript中。

Eric,我开始编写此代码来学习JavaScript。这是我的第一个项目,目标是在不使用第三方解决方案的情况下从头开始编写“简单”引擎。感谢您的建议,我听说过Box2D和其他一些JavaScript物理引擎,但这不是我需要的:)
function calcCollision(self){
    var dist = self.distanceCheck();
    var possible = [], collision = [];
    var myBox, otherBox, myMin, myMax, otherMin, otherMax, myBoxRecalc = [], otherBoxRecalc = [];

    for (var i=0;i<trainCount;i++){
        if (dist[i]!="SELF"&&dist[i]<=(dTrain+10)){
            possible.push(i);
        }
    }

    if (possible.length!==0){

        myBox = self.box();

        self.hit = false;

        for (i=0;i<possible.length;i++){
            otherBox = window["train_"+possible[i]].box();

            //для self координат

            for (var j=0;j<4;j++){
                myBoxRecalc[j] = XYtoBoxCoordinates(self,myBox[j][0],myBox[j][1]);
                otherBoxRecalc[j] = XYtoBoxCoordinates(self,otherBox[j][0],otherBox[j][1]);
            }

            //для self координат, проекция на X

            myMin = myBoxRecalc[0][0];
            myMax = myBoxRecalc[0][0];

            otherMin = otherBoxRecalc[0][0];
            otherMax = otherBoxRecalc[0][0];

            for (j=0;j<4;j++){
                if (myBoxRecalc[j][0]<myMin) myMin=myBoxRecalc[j][0];
                if (myBoxRecalc[j][0]>myMax) myMax=myBoxRecalc[j][0];

                if (otherBoxRecalc[j][0]<otherMin) otherMin=otherBoxRecalc[j][0];
                if (otherBoxRecalc[j][0]>otherMax) otherMax=otherBoxRecalc[j][0];
            }

            //console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);

            if (otherMax<myMin||otherMin>myMax) break;

            //для self координат, проекция на Y

            myMin = myBoxRecalc[0][1];
            myMax = myBoxRecalc[0][1];

            otherMin = otherBoxRecalc[0][1];
            otherMax = otherBoxRecalc[0][1];

            for (j=0;j<4;j++){
                if (myBoxRecalc[j][1]<myMin) myMin=myBoxRecalc[j][1];
                if (myBoxRecalc[j][1]>myMax) myMax=myBoxRecalc[j][1];

                if (otherBoxRecalc[j][1]<otherMin) otherMin=otherBoxRecalc[j][1];
                if (otherBoxRecalc[j][1]>otherMax) otherMax=otherBoxRecalc[j][1];
            }

            //console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);

            if (otherMax<myMin||otherMin>myMax) break;

            //для other координат

            for (j=0;j<4;j++){
                myBoxRecalc[j] = XYtoBoxCoordinates(window["train_"+possible[i]],myBox[j][0],myBox[j][1]);
                otherBoxRecalc[j] = XYtoBoxCoordinates(window["train_"+possible[i]],otherBox[j][0],otherBox[j][1]);
            }

            //для other координат, проекция на X

            myMin = myBoxRecalc[0][0];
            myMax = myBoxRecalc[0][0];

            otherMin = otherBoxRecalc[0][0];
            otherMax = otherBoxRecalc[0][0];

            for (j=0;j<4;j++){
                if (myBoxRecalc[j][0]<myMin) myMin=myBoxRecalc[j][0];
                if (myBoxRecalc[j][0]>myMax) myMax=myBoxRecalc[j][0];

                if (otherBoxRecalc[j][0]<otherMin) otherMin=otherBoxRecalc[j][0];
                if (otherBoxRecalc[j][0]>otherMax) otherMax=otherBoxRecalc[j][0];
            }

            //console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);

            if (otherMax<myMin||otherMin>myMax) break;

            //для other координат, проекция на Y

            myMin = myBoxRecalc[0][1];
            myMax = myBoxRecalc[0][1];

            otherMin = otherBoxRecalc[0][1];
            otherMax = otherBoxRecalc[0][1];

            for (j=0;j<4;j++){
                if (myBoxRecalc[j][1]<myMin) myMin=myBoxRecalc[j][1];
                if (myBoxRecalc[j][1]>myMax) myMax=myBoxRecalc[j][1];

                if (otherBoxRecalc[j][1]<otherMin) otherMin=otherBoxRecalc[j][1];
                if (otherBoxRecalc[j][1]>otherMax) otherMax=otherBoxRecalc[j][1];
            }

            //console.log(myMin + " " + myMax + " " + otherMin + " " + otherMax);

            if (otherMax<myMin||otherMin>myMax) break;

            collision.push(possible[i]);

        }
    } else return false;

    if (collision.length!==0){
        self.hit = true;
        return collision;
    } else return false;
}
function moveCollided(){

    for (var i = 0; i < trainCount; i++) {
        var banged = calcCollision(window["train_"+i]);
        //console.log(banged);
        if (window["train_"+i].hit){
            window["train_"+i].speed -= (window["train_"+i].speed/3);
            for (var j = 0; j < banged.length; j++) {
                window["train_"+banged[j]].speed += calcSpeedIncrement(window["train_"+i],window["train_"+banged[j]]);
            }
        }
    }

    setTimeout(moveCollided, 15);
}