有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

内存巨大的Java数组,用于平铺游戏

我正在尝试编写多人平铺java游戏。(只是为了好玩)

使用柏林噪波创建的世界地图。所以我很感兴趣,我如何才能创建真正大的地图

例如,要生成带有柏林噪声的8000x8000映射,需要大约4096Mb的RAM

映射表示为[8000][8000]数组,但在生成之后,我将其存储在数据库中,但我想在其中创建大约25000x25000个图块。 我可以把地图生成过程分成更小的部分吗? 问题是,我应该对整个地图使用柏林噪声,否则地图看起来就像是几个块,或者如果您了解动态地图生成,请告诉我。 我对它在Minecraft中的工作方式感到震惊(我指的是新生成的块以某种方式与prevous关联)

这是我的密码:

public static float[][] generateWhiteNoise(int width, int height)
   {
       Random random = new Random(); //Seed to 0 for testing
       float[][] noise = new float[width][height];

       for (int i = 0; i < width; i++)
       {
           for (int j = 0; j < height; j++)
           {
               noise[i][j] = (float)random.nextDouble() % 1;
           }
       }
       return noise;
   }



static float Interpolate(float x0, float x1, float alpha)
   {
       return x0 * (1 - alpha) + alpha * x1;
   }

static float[][] generateSmoothNoise(float[][] baseNoise, int octave)
   {
       int width = baseNoise.length;
       int height = baseNoise[0].length;

       float[][] smoothNoise = new float[width][height];

       int samplePeriod = 1 << octave; // calculates 2 ^ k
       float sampleFrequency = 1.0f / samplePeriod;

       for (int i = 0; i < width; i++)
       {
           //calculate the horizontal sampling indices
           int sample_i0 = (i / samplePeriod) * samplePeriod;
           int sample_i1 = (sample_i0 + samplePeriod) % width; //wrap around
           float horizontal_blend = (i - sample_i0) * sampleFrequency;

           for (int j = 0; j < height; j++)
           {
               //calculate the vertical sampling indices
               int sample_j0 = (j / samplePeriod) * samplePeriod;
               int sample_j1 = (sample_j0 + samplePeriod) % height; //wrap around
               float vertical_blend = (j - sample_j0) * sampleFrequency;

               //blend the top two corners
               float top = Interpolate(baseNoise[sample_i0][sample_j0],
                  baseNoise[sample_i1][sample_j0], horizontal_blend);

               //blend the bottom two corners
               float bottom = Interpolate(baseNoise[sample_i0][sample_j1],
                  baseNoise[sample_i1][sample_j1], horizontal_blend);

               //final blend
               smoothNoise[i][j] = Interpolate(top, bottom, vertical_blend);
           }
       }
       return smoothNoise;
   }

static float[][] generatePerlinNoise(float[][] baseNoise, int octaveCount)
   {
       int width = baseNoise.length;
       int height = baseNoise[0].length;

       float[][][] smoothNoise = new float[octaveCount][][]; //an array of 2D arrays containing

       float persistance = 0.5f;

       //generate smooth noise
       for (int i = 0; i < octaveCount; i++)
       {
           smoothNoise[i] = generateSmoothNoise(baseNoise, i);
       }

       float[][] perlinNoise = new float[width][height];
       float amplitude = 1.0f;
       float totalAmplitude = 0.0f;

       //blend noise together
       for (int octave = octaveCount - 1; octave >= 0; octave--)
       {
           amplitude *= persistance;
           totalAmplitude += amplitude;

           for (int i = 0; i < width; i++)
           {
               for (int j = 0; j < height; j++)
               {
                   perlinNoise[i][j] += smoothNoise[octave][i][j] * amplitude;
               }
           }
       }

       //normalisation
       for (int i = 0; i < width; i++)
       {
           for (int j = 0; j < height; j++)
           {
               perlinNoise[i][j] /= totalAmplitude;
           }
       }
       return perlinNoise;
   }

共 (2) 个答案

  1. # 1 楼答案

    现在,您可能正在使用java生成噪音。util。随机的您需要将其替换为mixing function。柏林噪声发生器应该是无状态函数。大概是这样的:

    int noise(int x, int y) {
        return (x*31)^(y*41); // mix x and y pseudorandomly
    }
    
    double smoothNoise(double x, double y) {
        return noise(floor(x),floor(y)) * fract(x) + ... // interpolate
    }
    
    double perlinNoise(double x, double y) {
       return smoothNoise(x,y)*0.5 +
              smoothNoise(x/2,y/2)*0.25 + ... // add octaves
    }
    

    这样,您可以随时调用perlinNoise,它将始终返回相同的结果。这将允许您以块的形式生成地图,而无需可见接缝

  2. # 2 楼答案

    我看到两种选择:

    1. 使用实现硬盘备份映射的工具(或者自己动手,因为这很简单)
    2. 使用成熟的数据库动态保存生成地图的块,可能使用代理模式(因为您使用的是柏林噪声,所以需要访问地图的各个部分)

    我的选票被存入数据库