У меня есть бесконечный генератор карт. Хорошо работает с положительными координатами. Генерация положительных координат 1
Но по отрицательным координатам у меня есть эта тра sh: Прерванная генерация отрицательных координат 2
void generateChunk(int x0, int y0) {
Chunk chunk = new Chunk(x0, y0);
for(int yTile = 0; yTile < Chunk.CHUNK_SIZE; yTile++) {
for(int xTile = 0; xTile < Chunk.CHUNK_SIZE; xTile++) {
int pX = chunk.x0 + xTile;
int pY = chunk.y0 + yTile;
double perlinNoiseHeight = floorPerlinNoise.getHeight(pX, pY);;
if(perlinNoiseHeight > BEACH_AREA) {
chunk.setFloor(GrassTile.ID, xTile, yTile);
} else if(perlinNoiseHeight > 0) {
chunk.setFloor(SandTile.ID, xTile, yTile);
} else {
chunk.setFloor(WaterTile.ID, xTile, yTile);
}
}
}
saveChunk(chunk);
}
Класс шума Perlin:
package org.ixnomad.game.level.generation;
public class PerlinNoise {
private double persistence, frequency, amplitude;
private int octaves;
private long seed;
public PerlinNoise(double persistence, double frequency, double amplitude, int octaves, long seed) {
this.persistence = persistence;
this.amplitude = amplitude;
this.frequency = frequency;
this.octaves = octaves;
this.seed = seed;
}
public double getHeight(double x, double y) {
return amplitude * total(x, y) + 0.4;
}
private double total(double i, double j) {
double total = 0.0d;
double _ampl = 1;
double _freq = frequency;
for(int k = 0; k < octaves; k++) {
total += getValue(j * _freq + seed, i * _freq + seed) * _ampl;
_ampl *= persistence;
_freq *= 2;
}
return total;
}
private double getValue(double x, double y) {
int xInt = (int) x;
int yInt = (int) y;
double xFrac = x - xInt;
double yFrac = y - yInt;
double n01 = noise(xInt-1, yInt-1);
double n02 = noise(xInt+1, yInt-1);
double n03 = noise(xInt-1, yInt+1);
double n04 = noise(xInt+1, yInt+1);
double n05 = noise(xInt-1, yInt );
double n06 = noise(xInt+1, yInt );
double n07 = noise(xInt , yInt-1);
double n08 = noise(xInt , yInt+1);
double n09 = noise(xInt , yInt );
double n12 = noise(xInt+2, yInt-1);
double n14 = noise(xInt+2, yInt+1);
double n16 = noise(xInt+2, yInt );
double n23 = noise(xInt-1, yInt+2);
double n24 = noise(xInt+1, yInt+2);
double n28 = noise(xInt , yInt+2);
double n34 = noise(xInt+2, yInt+2);
double x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09);
double x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06);
double x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08);
double x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04);
double v1 = interpolate(x0y0, x1y0, xFrac);
double v2 = interpolate(x0y1, x1y1, xFrac);
return interpolate(v1, v2, yFrac);
}
private double interpolate(double x, double y, double frac) {
double negFrac = 1.0 - frac;
double negFraqSqr = negFrac * negFrac;
double fac1 = 3.0 * negFraqSqr - 2.0 * negFraqSqr * negFrac;
double fracSqr = frac * frac;
double fac2 = 3.0 * fracSqr - 2.0 * fracSqr * frac;
return x * fac1 + y * fac2;
}
private double noise(int x, int y) {
int n = x + y * 57;
n = (n << 13) ^ n;
int t = (n * (n * n * 15713 + 789221) + 1376312589) & 0x7fffffff;
return 1.0d - (double) (t * 0.931322574615478515625e-9);
}
}
Я пытался решить эту проблему целый день, но я не знаю, что я делаю не так. Я думал, что проблема в битовом сдвиге (private double noise(double x, double y)
), но проблема не зависит от этого. Я пытался использовать этот алгоритм Перлина: https://mrl.nyu.edu/~perlin/noise/ Но эффект тот же.