繁体   English   中英

圆形到圆形碰撞的问题

[英]Problems with circle to circle collision in clusters

我正在制作一个游戏,类似于agar.io,我正在努力为我的游戏对象添加碰撞,这些对象都是由圆圈组成的。 碰撞系统有时候运行得很好,但是当我在一个紧密的集群中得到2个以上的东西时,事情开始变得非常麻烦和紧张。 甚至偶尔只有2只他们偶尔会跳起来。 我认为我在检查碰撞时试图移动这些单元的事实是问题的一部分,但这很难测试。

我正在使用Sockets.io,Node.js和一个名为P5.js的绘图库。 冲突全部在服务器端处理,但是单元的移动在客户端处理。

在服务器上,碰撞代码

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

在客户端

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

和客户端移动脚本,在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);
}

客户端可以发送输入(鼠标位置),所有跟踪由服务器处理,服务器回答绘制内容的位置。 这样,当所有单元格检查冲突时,您可以广播更新,并且可以定期(如帧速率)。 客户端唯一的任务是渲染给定的数据并告诉鼠标的位置。

另外,我建议避免在循环中创建新变量。

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

重用变量有助于代码的性能。 垃圾收集和实例化在循环中可能是昂贵的。

加速检查的另一个提示可能是首先检查是否将x和y距离与半径进行比较。 这避免了做平方根,这也可能成本高且不精确。

例如,如果

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