简体   繁体   English

圆形到圆形碰撞的问题

[英]Problems with circle to circle collision in clusters

I am making a game, similar to agar.io, and am working on adding collision to my gameobjects, which all consist of circles. 我正在制作一个游戏,类似于agar.io,我正在努力为我的游戏对象添加碰撞,这些对象都是由圆圈组成的。 The collision system works pretty well sometimes, but as soon as I get more than 2 in a tight cluster things start getting very glitchy and jittery. 碰撞系统有时候运行得很好,但是当我在一个紧密的集群中得到2个以上的东西时,事情开始变得非常麻烦和紧张。 Even occasionally when only having 2 they jump arround sporadically. 甚至偶尔只有2只他们偶尔会跳起来。 I think the fact that I am trying to move these cells while checking for the collisions is part of the problem, but thats hard to test for. 我认为我在检查碰撞时试图移动这些单元的事实是问题的一部分,但这很难测试。

I am working with Sockets.io, Node.js, and a drawing library called P5.js. 我正在使用Sockets.io,Node.js和一个名为P5.js的绘图库。 The collision is all being handled server side, but the movement of the cells is handled client side. 冲突全部在服务器端处理,但是单元的移动在客户端处理。

On the server, the collision code 在服务器上,碰撞代码

socket.on('update', msgUpdate)
    function msgUpdate(data){
    var cell

    //finds the cell that we want to update
    for(var si=0; si<cells.length; si++){   
        if(socket.id + data.di == cells[si].id){
        cell = cells[si];               
        }       
    }

    //the collision system
    for(var i = cells.length-1; i>=0; i--){
        var dx = cell.x - cells[i].x;
        var dy = cell.y - cells[i].y;
        var distance = Math.sqrt(dx * dx + dy * dy);
        if(distance < cell.r + cells[i].r && cell.r > cells[i].r){
            var unitX = dx/distance;
            var unitY = dy/distance;

            cell.x = cells[i].x + (cell.r + cells[i].r + 1) * unitX;
            cell.y = cells[i].y + (cell.r + cells[i].r + 1) * unitY;
       }
    }
}

On the client 在客户端

//myCells is an array of Cell objects, all of which you control
for(var i = myCells.length-1; i>=0; i--){
    myCells[i].move();
    var data = {
        x: myCells[i].pos.x,
        y: myCells[i].pos.y,
        r: myCells[i].r,
        c: myCells[i].c,
        di: myCells[i].id
    }
    socket.emit('update', data);
}

And the client side movement script, within the Cell object 和客户端移动脚本,在Cell对象中


this.move = function(){
    for(var ii = myCells.length-1; ii>=0; ii--){
        var velocity = createVector(mouseX - width/2 + (myCells[ii].pos.x - this.pos.x), mouseY-height/2 + (myCells[ii].pos.y - this.pos.y));
    }
    var sub = this.r * 0.03;
    velocity.setMag((6 - sub));
    this.pos.add(velocity);
}

The client could send inputs(mouse position) and all the tracking is handled by the server and the server answer back the positions of where to draw things. 客户端可以发送输入(鼠标位置),所有跟踪由服务器处理,服务器回答绘制内容的位置。 That way you broadcast an update when all the cells are check for collision and it can be at periodically (like frame rate). 这样,当所有单元格检查冲突时,您可以广播更新,并且可以定期(如帧速率)。 The client only task is to render the given data and tell the position of the mouse. 客户端唯一的任务是渲染给定的数据并告诉鼠标的位置。

Also, I would recommend avoiding creating new variables in loops. 另外,我建议避免在循环中创建新变量。

    let dx;
    let dy;
    let distance;
    let i;
    let unitX;
    let unitY;
    //the collision system
    for(i = cells.length-1; i>=0; i--){
        dx = cell.x - cells[i].x
        dy = cell.y - cells[i].y;
        distance = Math.sqrt(dx * dx + dy * dy);
        if(distance < cell.r + cells[i].r && cell.r > cells[i].r){
            unitX = dx/distance;
            unitY = dy/distance;

            cell.x = cells[i].x + (cell.r + cells[i].r + 1) * unitX;
            cell.y = cells[i].y + (cell.r + cells[i].r + 1) * unitY;
       }
    }

Reusing variable help the performance of the code. 重用变量有助于代码的性能。 Garbage collection and instantiation can be costly in loops. 垃圾收集和实例化在循环中可能是昂贵的。

Another tip to accelerate the check could be to check first if comparing the x and y distance with the radius. 加速检查的另一个提示可能是首先检查是否将x和y距离与半径进行比较。 This avoids doing square root that can be also costly and not precise. 这避免了做平方根,这也可能成本高且不精确。

example if 例如,如果

c1.y=0
c1.x=0
c1.r=10

c2.y=0
c2.x=1000
c2.r=10

then they do not intersect

if(cell.r + cells[i].r < dx || cell.r + cells[i].r < dy ){
 //No intersection
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM