加载相对于玩家位置的地形块

我正在制作一个基于体素的小型多人WebGL游戏,带有一个Node.JS服务器,用于处理玩家位置并向客户端发送地形块数据。 这是我目前正在发送的块的一个例子:

var viewDistance = 6; for (var x = playerPosX - viewDistance; x < playerPosX + viewDistance; x++) for (var z = playerPosZ - viewDistance; z < playerPosZ + viewDistance; z++) for (var y = playerPosY - viewDistance; y < playerPosY + viewDistance; y++) { client.send( getChunk(x, y, z) ); } 

这只是加载和发送的视图范围内的块,但是我正在寻找一种方式来优先发送最接近玩家的块。 显然,在加载玩家站在的那个之前,装载很远的块是不好的。

假设playerPosXplayerPosZplayerPosY存储玩家和client.send( getChunk(x, y, z) )将发送大块,有没有人有任何想法,我会这样做? 谢谢。

我会做这样的事情:

  var vd = 6; //view distance var v = vd*2+1; //length of cube of chunks we want to send var s = new Array(v*v*v); //used to store which chunks we have sent for(var i=0; i<s.length; ++i) { s[i] = false; } for(var i=0; i<=vd; i++){ //start at center and move out layer by layer for(var x=-i; x<=i; x++){ //get all chunks inside current layer for(var y=-i; y<=i; y++){ for(var z=-i; z<=i; z++){ if(!s[(x+vd)+(y+vd)*v+(z+vd)*v*v]){ //exclude already sent chunks client.send( getChunk(x+plX, y+plY, z+plZ)); //send chunk s[(x+vd)+(y+vd)*v+(z+vd)*v*v]=true; //mark chunk as sent } } } } } 

我可能在某个地方犯了一个错误,因为我从来没有使用过JavaScript,但是我认为这些评论应该说明我的意思。

这假设你的播放器在循环过程中没有离开当前块,如果可能的话,你需要重新启动循环或者使用其他方法来存储你已经发送给客户端的块。

在这里输入图像描述

将加载分成几部分(白色块是你正在站立的)。 上图显示了x和y轴,z轴保留了你的想象。

首先发送白色块(playerPosX,playerPosY,playerPosZ)。 之后,开始向两个方向(+ x,-x,+ y,-y,+ z,-z)的每个轴向外移动。 沿着每个彩色部分向外走(+ x,-x,+ y,-y):

 Distance 1: send 2 x 2 chunks Distance 2: send 4 x 4 chunks Distance 3: send 6 x 6 chunks 

沿着+ z部分:

 Distance 1: send 3 x 3 chunks Distance 2: send 5 x 5 chunks Distance 3: send 7 x 7 chunks 

-z部分:

 Distance 1: send 1 x 1 chunks Distance 2: send 3 x 3 chunks Distance 3: send 5 x 5 chunks 

作为(伪)代码:

 sendChunk(playerPosX, playerPosY, playerPosZ); for (var i = 1; i < distance; i++) { //Green for (var y = 0; y < i * 2; y++) { for (var z = 0; z < i * 2; z++) { sendChunck(playerPosX - i, playerPosY + (i - 1) - y, playerPosZ + (i - 1) - z); } } //Do the same for yellow, blue, red, with different axes //Do (almost) the same along +z and -z } 

您也可以使用完全相同的切片技术,从发送的每个“图层”的中心开始进一步改进解决scheme。 上面的图片可能代表一个7 x 7层被发送。

由此产生的代码不会很简洁,但是你只会一次遍历每个块,使得时间复杂度为O(n)。