群集中圆到圆碰撞的问题

时间:2019-05-30 20:37:34

标签: javascript node.js socket.io game-engine collision

我正在制作类似于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);
}

1 个答案:

答案 0 :(得分:0)

客户端可以发送输入(鼠标位置),并且所有跟踪都由服务器处理,并且服务器会回答在哪里画东西的位置。这样,您可以在检查所有单元格是否存在冲突时广播更新,并且可以定期更新(例如帧速率)。客户端的唯一任务是呈现给定的数据并告诉鼠标位置。

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

    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
}