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