Javascript Circle to Circle Collision Detection不工作

时间:2018-06-01 01:25:51

标签: javascript node.js sockets collision-detection game-development

引言

您好,我正在制作一款类似agar.io的二维游戏,该游戏使用了碰撞检测。

它使用SAT.js来检测碰撞,并且正在做一个膨胀的工作,除了一件事。

问题

碰撞工作正常,除非你"拆分"你的单元格,在阵列中向你的玩家添加另一个单元格(或圆圈)。

因此,对于一个圆圈,碰撞工作正常,但不止一个,它不会记录碰撞,除非所有大圆圈完全以对手为中心,注册检测。

(而不是使用其中一个圆圈的中心点,它基本上使用了所有圆圈的中心点)

代码

以下是碰撞检测代码:

function check(user) {
    for(var i=0; i<user.cells.length; i++) {
        if(user.cells[i].mass > 10 && user.id !== currentPlayer.id) {
            var response = new SAT.Response();
            var collided = SAT.testCircleCircle(playerCircle,
                new C(new V(user.cells[i].x , user.cells[i].y), user.cells[i].radius),
                response);
            if (collided) {
                response.aUser = currentCell;
                response.bUser = {
                    id: user.id,
                    name: user.name,
                    x: user.cells[i].x,
                    y: user.cells[i].y,
                    num: i,
                    mass: user.cells[i].mass,
                    money: user.cells[i].money
                };
                playerCollisions.push(response);
            }
        }
    }
    return true;
}

以下是定义的变量:

for(var z=0; z<currentPlayer.cells.length; z++) {
        var currentCell = currentPlayer.cells[z];
        var playerCircle = new C(
            new V(currentCell.x, currentCell.y),
            currentCell.radius
        );

以下是您&#34;拆分&#34;你的圈子分为两个:

    function splitCell(cell) {
        if(cell.mass >= c.defaultPlayerMass*2) {
            //io.emit('playSplitSound');
            cell.mass = cell.mass/2;
            cell.money = cell.money/2;
            cell.radius = util.massToRadius(cell.mass);
            currentPlayer.cells.push({
                mass: cell.mass,
                money: cell.money,
                x: cell.x,
                y: cell.y,
                radius: cell.radius,
                speed: 25
            });
        }
    }

最后,这里是所有使用的碰撞代码,用于查看订单和其他代码:

    function check(user) {
        for(var i=0; i<user.cells.length; i++) {
            if(user.cells[i].mass > 10 && user.id !== currentPlayer.id) {
                var response = new SAT.Response();
                var collided = SAT.testCircleCircle(playerCircle,
                    new C(new V(user.cells[i].x , user.cells[i].y), user.cells[i].radius),
                    response);
                if (collided) {
                    response.aUser = currentCell;
                    response.bUser = {
                        id: user.id,
                        name: user.name,
                        x: user.cells[i].x,
                        y: user.cells[i].y,
                        num: i,
                        mass: user.cells[i].mass,
                        money: user.cells[i].money
                    };
                    playerCollisions.push(response);
                }
            }
        }
        return true;
    }

    function collisionCheck(collision) {//Here is where to fix eating bug, try to make it so if  at least half of victim is in predator, then get eaten.
        if (collision.aUser.mass > collision.bUser.mass * 1.1  && collision.aUser.radius > Math.sqrt(Math.pow(collision.aUser.x - collision.bUser.x, 2) + Math.pow(collision.aUser.y - collision.bUser.y, 2))*1.75) {
            console.log('[DEBUG] Killing user: ' + collision.bUser.id);
            console.log('[DEBUG] Collision info:');
            console.log(collision);

            var numUser = util.findIndex(users, collision.bUser.id);
            if (numUser > -1) {
                if(users[numUser].cells.length > 1) {
                    users[numUser].massTotal -= collision.bUser.mass;
                    users[numUser].moneyTotal -= collision.bUser.money;
                    users[numUser].cells.splice(collision.bUser.num, 1);
                } else {
                    users.splice(numUser, 1);
                    io.emit('playerDied', { name: collision.bUser.name });
                    sockets[collision.bUser.id].emit('RIP');
                }
            }
            currentPlayer.massTotal += collision.bUser.mass;
            collision.aUser.mass += collision.bUser.mass;
            currentPlayer.moneyTotal += collision.bUser.money;
            collision.aUser.money += collision.bUser.money;
        }
    }

    for(var z=0; z<currentPlayer.cells.length; z++) {
        var currentCell = currentPlayer.cells[z];
        var playerCircle = new C(
            new V(currentCell.x, currentCell.y),
            currentCell.radius
        );

        var foodEaten = food.map(funcFood)
            .reduce( function(a, b, c) { return b ? a.concat(c) : a; }, []);

        foodEaten.forEach(deleteFood);

        var massEaten = massFood.map(eatMass)
            .reduce(function(a, b, c) {return b ? a.concat(c) : a; }, []);

        var virusCollision = virus.map(funcFood)
           .reduce( function(a, b, c) { return b ? a.concat(c) : a; }, []);

        if(virusCollision > 0 && currentCell.mass > virus[virusCollision].mass) {
          sockets[currentPlayer.id].emit('virusSplit', z);
          virus.splice(virusCollision, 1);
        }

        var masaGanada = 0;
        for(var m=0; m<massEaten.length; m++) {
            masaGanada += massFood[massEaten[m]].masa;
            massFood[massEaten[m]] = {};
            massFood.splice(massEaten[m],1);
            for(var n=0; n<massEaten.length; n++) {
                if(massEaten[m] < massEaten[n]) {
                    massEaten[n]--;
                }
            }
        }

        if(typeof(currentCell.speed) == "undefined")
            currentCell.speed = 6.25;
        masaGanada += (foodEaten.length * c.foodMass);
        currentCell.mass += masaGanada;
        currentPlayer.massTotal += masaGanada;
        currentCell.radius = util.massToRadius(currentCell.mass);
        playerCircle.r = currentCell.radius;

        tree.clear();
        users.forEach(tree.put);
        var playerCollisions = [];

        var otherUsers =  tree.get(currentPlayer, check);

        playerCollisions.forEach(collisionCheck);
    }
}

有问题的问题和尝试:

所以我做了很多事情来尝试找到问题。

我首先使用console.log();来确保识别每个单元格的x,y和半径。他们都被认可了。

接下来,我用它来确保没有识别到​​碰撞,只是没有执行。

碰撞未被识别,因此它与check(user);函数有关。

我甚至试过制作我自己的碰撞检测,每次检查都有一个圆圈,但是对于多个圆圈也有同样的问题。

结论

我因此而痛苦地死去,真的需要帮助。

如果您需要更多代码,请在下面给我发消息,我可能会将其添加到Google驱动器中。

谢谢!

-Patrick

0 个答案:

没有答案