簡體   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