From a3864ac2630d6306d9104fffc9b7f8a037167b59 Mon Sep 17 00:00:00 2001 From: WangTingZheng <2251985371@qq.com> Date: Mon, 20 Jul 2020 00:48:32 +0800 Subject: [PATCH] add comment in extendedBlockStorge ChunkPrimer --- .../minecraft/world/chunk/ChunkPrimer.java | 12 +++ .../chunk/storage/ExtendedBlockStorage.java | 77 ++++++++++++------- 2 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/minecraft/net/minecraft/world/chunk/ChunkPrimer.java b/src/minecraft/net/minecraft/world/chunk/ChunkPrimer.java index 5e9f2d6f..df93af03 100644 --- a/src/minecraft/net/minecraft/world/chunk/ChunkPrimer.java +++ b/src/minecraft/net/minecraft/world/chunk/ChunkPrimer.java @@ -7,6 +7,7 @@ import net.minecraft.init.Blocks; public class ChunkPrimer { private static final IBlockState DEFAULT_STATE = Blocks.AIR.getDefaultState(); + //很可能是存储一个chunk中方块的id的,minecraft中一个section由16*16*16格的方块组成,16个section垂直排列,组成一个chunk,也就是一个chunk有16的四次方个方块,也就是65536 private final char[] data = new char[65536]; public IBlockState getBlockState(int x, int y, int z) @@ -20,6 +21,17 @@ public class ChunkPrimer this.data[getBlockIndex(x, y, z)] = (char)Block.BLOCK_STATE_IDS.get(state); } + /** + * a< 把数字转换为二进制后左移b位,相当于a*2^b a|b -> 把a和化为二进制后按位取或 + * 根据方块的坐标,获得方块在一个chunk中的id???这个坐标不是全局坐标,而是一个chunk内的局部坐标 + * 我们知道,按位取或的结果最大值,是由每一位中最长的哪一位决定的,这里的x,y都是1->16的,而z是1->16*16,然后x<<12表示的是x*4096,所以最大值是65536,而y的最大值是256 + * 所以这个函数的返回值的最大值是65536,也就是最后一个方块 + * 所以这个函数的作用是,输入一个chunk内的相对坐标,返回一个chunk内1-65536的唯一id + * @param x 一个方块在某一个区块内的x坐标,范围是1-16 + * @param y 一个方块在某一个区块内的y坐标,范围是1-16 + * @param z 一个方块在某一个区块内的z坐标,也就是纵向的坐标,范围是1-256 + * @return 这个方块在这个chunk内的一个唯一id + */ private static int getBlockIndex(int x, int y, int z) { return x << 12 | z << 8 | y; diff --git a/src/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java b/src/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java index 8c486a44..f44c2525 100644 --- a/src/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java +++ b/src/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java @@ -7,33 +7,45 @@ import net.minecraft.src.Reflector; import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.NibbleArray; +/** + * 描述一个section的类 + * 一个section由16*16*16个block组成 + */ public class ExtendedBlockStorage { /** * Contains the bottom-most Y block represented by this ExtendedBlockStorage. Typically a multiple of 16. + * 存储着这个能代表这个section的最底层y轴的方块,通常是16的倍数 */ private final int yBase; /** * A total count of the number of non-air blocks in this block storage's Chunk. + * 在这个section中,非空气方块的数量 */ private int blockRefCount; /** * Contains the number of blocks in this block storage's parent chunk that require random ticking. Used to cull the * Chunk from random tick updates for performance reasons. + * 包含此section所属的父chunk中被标记的随机ticking的方块数量,由于性能问题,通常会在随机tick更新中剔除一些方块 + * 一般情况下,在一个chunk中会随机选择3个方块作为随机更新方块,在一个随机刻中,这些方块将会被更新 */ private int tickRefCount; private final BlockStateContainer data; - /** The NibbleArray containing a block of Block-light data. */ + /** + * The NibbleArray containing a block of Block-light data. + * 一个包含光照(点光源/局部光照???)数据的半字节数组 + */ private NibbleArray blockLight; /** * The NibbleArray containing skylight data. - * + * 一个包含skylight(全局光照???)数据的半字节数组 * Will be null if the provider for the world the chunk containing this block storage does not {@linkplain - * net.minecraft.world.WorldProvider#hasSkylight have skylight}. + * net.minecraft.world.WorldProvider# hasSkylight have skylight}. + * */ private NibbleArray skyLight; @@ -54,38 +66,47 @@ public class ExtendedBlockStorage return this.data.get(x, y, z); } + /** + * 设置某一个位置的方块的状态 + * @param x 方块在一个chunk的的x的位置 + * @param y 方块在一个chunk的的y的位置 + * @param z 方块在一个chunk的的z的位置 + * @param state 一个方块的状态 + */ public void set(int x, int y, int z, IBlockState state) { - if (Reflector.IExtendedBlockState.isInstance(state)) + if (Reflector.IExtendedBlockState.isInstance(state)) //判断这个state是不是由net.minecraftforge.common.property.IExtendedBlockState类继承IBlockState实现的 { state = (IBlockState)Reflector.call(state, Reflector.IExtendedBlockState_getClean); } - IBlockState iblockstate = this.get(x, y, z); - Block block = iblockstate.getBlock(); - Block block1 = state.getBlock(); + IBlockState iblockstate = this.get(x, y, z); //从这个section中获得这个方块的状态,可能是旧的方块 + Block block = iblockstate.getBlock(); //从section中的这个状态中获得方块 + Block block1 = state.getBlock(); //从传入的状态中获得方块,可能是新的方块 - if (block != Blocks.AIR) + //下面这段要从一个section中剔除旧的方块 + if (block != Blocks.AIR) //如果旧方块不是空气(不为空) { - --this.blockRefCount; + --this.blockRefCount; //就减少这个区块的非方块的数量,毕竟要把这个方块代替了 - if (block.getTickRandomly()) + if (block.getTickRandomly()) //如果这个方块是被挑选为随机刻更新的方块 { - --this.tickRefCount; + --this.tickRefCount; //那么就减少随机刻方块的数量 } } - if (block1 != Blocks.AIR) + //下面这段要在一个section中添加新方块 + if (block1 != Blocks.AIR) //如果旧的方块不是空气方块(不为空) { - ++this.blockRefCount; + ++this.blockRefCount; //增加非空方块的数量 - if (block1.getTickRandomly()) + if (block1.getTickRandomly()) //如果这个方块被选择在随机刻中更新 { - ++this.tickRefCount; + ++this.tickRefCount; //增加随机刻方块的数量 } } - this.data.set(x, y, z, state); + this.data.set(x, y, z, state); //通过真正的set方法传入新的方块 } /** @@ -99,6 +120,7 @@ public class ExtendedBlockStorage /** * Returns whether or not this block storage's Chunk will require random ticking, used to avoid looping through * random block ticks when there are no blocks that would randomly tick. + * */ public boolean needsRandomTick() { @@ -145,36 +167,39 @@ public class ExtendedBlockStorage return this.blockLight.get(x, y, z); } + /** + * 通过遍历检查的方式重新计算整个section中的非空方块的数量和随机刻方块的数量 + */ public void recalculateRefCounts() { - IBlockState iblockstate = Blocks.AIR.getDefaultState(); + IBlockState iblockstate = Blocks.AIR.getDefaultState(); //获取空气的方块状态 int i = 0; int j = 0; - for (int k = 0; k < 16; ++k) + for (int k = 0; k < 16; ++k) //遍历一个section中的所有方块 { for (int l = 0; l < 16; ++l) { for (int i1 = 0; i1 < 16; ++i1) { - IBlockState iblockstate1 = this.data.get(i1, k, l); + IBlockState iblockstate1 = this.data.get(i1, k, l); //从当前section中获取这个方块的状态 - if (iblockstate1 != iblockstate) + if (iblockstate1 != iblockstate) //如果这个方块不是空气 { - ++i; - Block block = iblockstate1.getBlock(); + ++i; //i的计数加一,也就是非空方块计数加一 + Block block = iblockstate1.getBlock(); //从状态中获得方块 - if (block.getTickRandomly()) + if (block.getTickRandomly()) //如果方块是随机刻方块 { - ++j; + ++j;//j的计数加一,也就是随机刻方块数量加一 } } } } } - this.blockRefCount = i; - this.tickRefCount = j; + this.blockRefCount = i; //重新赋值非空方块数量 + this.tickRefCount = j; //重新赋值随机刻方块数量 } public BlockStateContainer getData()