玩家移动后,柏林噪声为同一点提供不同的值
perlin noise giving diffrent values for same point after player has moved
我正在使用柏林噪声为我的游戏生成地图。然后使用行进方块绘制。为 perlin 噪声函数输入的值是相对于 0,0 坐标的,然后将其转换为屏幕上可以绘制的位置。
问题是,当玩家移动时,绘制到屏幕上的图像在网格边缘略有不同,这会导致玩家移动时出现闪烁效果。
asteroids_in_range(player.x-WIDTH/2,player.x+WIDTH/2,player.y-HEIGHT/2,player.y+HEIGHT/2,16);
int get_asteroid_case(float x, float y, float box_size)
{
/*get the case for the box with the bottom left corner
at location x,y and size of box_size*/
int count = 0;
if(perlin.GetValue(x, y, 0.1) > THRESHHOLD)
{
count += 8;
}
if(perlin.GetValue(x+box_size, y, 0.1) > THRESHHOLD)
{
count += 4;
}
if(perlin.GetValue(x+box_size, y+box_size, 0.1) > THRESHHOLD)
{
count += 2;
}
if(perlin.GetValue(x, y+box_size, 0.1) > THRESHHOLD)
{
count += 1;
}
return count;
}
void asteroids_in_range(float xmin, float xmax, float ymin, float ymax, float grid_size)
{
int num;
for(float x = xmin; x <= xmax; x+=grid_size)
{
for(float y = ymin; y <= ymax; y+=grid_size)
{
num = get_asteroid_case(x, y, grid_size);
if(num != 0 && num != 15)
render_asteroids(num,x,y, 1);
}
}
}
可以看出,播放器的图像相距一个像素,生成的网格的边缘存在细微差异。
你的问题是你得到了不同的噪声值,因为你在不同的点得到了噪声。不要那样做。使其成为相同的点 - 网格上的点。
假设 grid_size 是 10(像素),WIDTH 是 100(像素),播放器位于 0,0。您在 -50、-50、-40、-50 和 -30、-50 等处得到噪声。
现在假设玩家向右移动 3 个像素。您会在 -47、-50、-37、-50 和 -27、-50 等位置获得噪声。 显然你得到了不同的噪音值,因为你要求不同的噪音值!
相反,您应该将噪声坐标四舍五入到网格 - 到 grid_size 的倍数。您的代码可以通过在网格渲染之前舍入 xmin 和 xmax 以及 ymin 和 ymax 来轻松调整 - 例如:
xmin = floor(xmin / grid_size) * grid_size;
xmax = ceil(xmax / grid_size) * grid_size;
// same for y
最小坐标向下取整,最大坐标向上取整,以确保整个屏幕仍在渲染坐标内。
我正在使用柏林噪声为我的游戏生成地图。然后使用行进方块绘制。为 perlin 噪声函数输入的值是相对于 0,0 坐标的,然后将其转换为屏幕上可以绘制的位置。
问题是,当玩家移动时,绘制到屏幕上的图像在网格边缘略有不同,这会导致玩家移动时出现闪烁效果。
asteroids_in_range(player.x-WIDTH/2,player.x+WIDTH/2,player.y-HEIGHT/2,player.y+HEIGHT/2,16);
int get_asteroid_case(float x, float y, float box_size)
{
/*get the case for the box with the bottom left corner
at location x,y and size of box_size*/
int count = 0;
if(perlin.GetValue(x, y, 0.1) > THRESHHOLD)
{
count += 8;
}
if(perlin.GetValue(x+box_size, y, 0.1) > THRESHHOLD)
{
count += 4;
}
if(perlin.GetValue(x+box_size, y+box_size, 0.1) > THRESHHOLD)
{
count += 2;
}
if(perlin.GetValue(x, y+box_size, 0.1) > THRESHHOLD)
{
count += 1;
}
return count;
}
void asteroids_in_range(float xmin, float xmax, float ymin, float ymax, float grid_size)
{
int num;
for(float x = xmin; x <= xmax; x+=grid_size)
{
for(float y = ymin; y <= ymax; y+=grid_size)
{
num = get_asteroid_case(x, y, grid_size);
if(num != 0 && num != 15)
render_asteroids(num,x,y, 1);
}
}
}
可以看出,播放器的图像相距一个像素,生成的网格的边缘存在细微差异。
你的问题是你得到了不同的噪声值,因为你在不同的点得到了噪声。不要那样做。使其成为相同的点 - 网格上的点。
假设 grid_size 是 10(像素),WIDTH 是 100(像素),播放器位于 0,0。您在 -50、-50、-40、-50 和 -30、-50 等处得到噪声。
现在假设玩家向右移动 3 个像素。您会在 -47、-50、-37、-50 和 -27、-50 等位置获得噪声。 显然你得到了不同的噪音值,因为你要求不同的噪音值!
相反,您应该将噪声坐标四舍五入到网格 - 到 grid_size 的倍数。您的代码可以通过在网格渲染之前舍入 xmin 和 xmax 以及 ymin 和 ymax 来轻松调整 - 例如:
xmin = floor(xmin / grid_size) * grid_size;
xmax = ceil(xmax / grid_size) * grid_size;
// same for y
最小坐标向下取整,最大坐标向上取整,以确保整个屏幕仍在渲染坐标内。