本篇内容是生成起伏的地表和生物群系,这部分应该是MC中的世界看上去变化多端的重点了
先回顾一下provideChunk:
public Chunk provideChunk(int x, int z)
{
this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
ChunkPrimer chunkprimer = new ChunkPrimer();
// 生成基本地形(没有洞穴等建筑)
this.setBlocksInChunk(x, z, chunkprimer);
// 生成16*16的生物群系数组
this.biomesForGeneration = this.worldObj.getWorldChunkManager().loadBlockGeneratorData(this.biomesForGeneration, x * 16, z * 16, 16, 16);
// 把石头替换成生物群系相应的方块
this.replaceBlocksForBiome(x, z, chunkprimer, this.biomesForGeneration);
// ...
}
生成基本地形
MC不是直接生成一个高度图,而是生成一个三维的“密度数组”,不知道为什么这样做。我猜是为了生成石窟这种地形,但是这样也有可能生成浮空岛
// 生成只有石头、水、空气的基本地形
public void setBlocksInChunk(int xChunk, int zChunk, ChunkPrimer chunkprimer)
{
// 生成10*10的生物群系数组
this.biomesForGeneration = this.worldObj.getWorldChunkManager().getBiomesForGeneration(this.biomesForGeneration, xChunk * 4 - 2, zChunk * 4 - 2, 10, 10);
// 生成field_147434_q这个数组,我认为它代表密度
// 尺寸5*5*33,索引高位是x,中位是z,低位是y
this.func_147423_a(xChunk * 4, 0, zChunk * 4);
// xyzHigh作为field_147434_q索引,要和xyzLow组合才是方块坐标
for (int xHigh = 0; xHigh < 4; ++xHigh)
{
int xIndex = xHigh * 5;
int xIndex_1 = (xHigh + 1) * 5;
for (int zHigh = 0; zHigh < 4; ++zHigh)
{
int xzIndex = (xIndex + zHigh) * 33;
int xz_1Index = (xIndex + zHigh + 1) * 33;
int x_1zIndex = (xIndex_1 + zHigh) * 33;
int x_1z_1Index = (xIndex_1 + zHigh + 1) * 33;
for (int yHigh = 0; yHigh < 32; ++yHigh)
{
// 这些线性插值后得到的density3才是每个方块的密度
double density = this.field_147434_q[xzIndex + yHigh];
double densityZ1 = this.field_147434_q[xz_1Index + yHigh];
double densityX1 = this.field_147434_q[x_1zIndex + yHigh];
double densityX1Z1 = this.field_147434_q[x_1z_1Index + yHigh];
// 步长,后同
double densityStep = (this.field_147434_q[xzIndex + yHigh + 1] - density) / 8;
double densityZ1Step = (this.field_147434_q[xz_1Index + yHigh + 1] - densityZ1) / 8;
double densityX1Step = (this.field_147434_q[x_1zIndex + yHigh + 1] - densityX1) / 8;
double densityX1Z1Step = (this.field_147434_q[x_1z_1Index + yHigh + 1] - densityX1Z1) / 8;
for (int yLow = 0; yLow < 8; ++yLow)
{
double density2 = density;
double density2Z1 = densityZ1;
double density2Step = (densityX1 - density) / 4;
double density2Z1Step = (densityX1Z1 - densityZ1) / 4;
for (int xLow = 0; xLow < 4; ++xLow)
{
double density3 = density2;
double density3Step = (density2Z1 - density2) / 4;
for (int zLow = 0; zLow < 4; ++zLow)
{
if (density3 > 0.0D) // 密度>0认为是固体
{
// 设置为石头
chunkprimer.setBlockState(xHigh * 4 + xLow, yHigh * 8 + yLow, zHigh * 4 + zLow, Blocks.stone.getDefaultState());
}
else if (yHigh * 8 + yLow < this.settings.seaLevel) // 密度<0且在海平面以下认为是液体
{
// 设置为默认液体(水或岩浆)
chunkprimer.setBlockState(xHigh * 4 + xLow, yHigh * 8 + yLow, zHigh * 4 + zLow, this.field_177476_s.getDefaultState());
}
// 否则是空气
density3 += density3Step;