Minecraft的世界生成过程(七)矿物和树
来源:互联网 发布:北京住宅成交数据 编辑:程序博客网 时间:2024/04/29 13:08
目前的世界是不是还少了点什么——没有树、矿石怎么致富!
本篇应该是最后一篇了,研究下树和矿石之类的点缀的生成
populate函数
上一篇提到的,在provideChunk之后调用
/** * Populates chunk with ores etc etc */ public void populate(IChunkProvider chunkProvider, int chunkX, int chunkZ) { // 如果生成了可掉落方块则立即掉落 BlockFalling.fallInstantly = true; int minBlockX = chunkX * 16; int minBlockZ = chunkZ * 16; BlockPos minBlockPos = new BlockPos(minBlockX, 0, minBlockZ); // 4个区块中心点生物群系 BiomeGenBase biome = this.worldObj.getBiomeGenForCoords(minBlockPos.add(16, 0, 16)); this.rand.setSeed(this.worldObj.getSeed()); long k = this.rand.nextLong() / 2L * 2L + 1L; long l = this.rand.nextLong() / 2L * 2L + 1L; this.rand.setSeed((long)chunkX * k + (long)chunkZ * l ^ this.worldObj.getSeed()); boolean hasVillage = false; ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(chunkX, chunkZ); net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.PopulateChunkEvent.Pre(chunkProvider, worldObj, rand, chunkX, chunkZ, hasVillage)); // 生成建筑 if (this.settings.useMineShafts && this.mapFeaturesEnabled) { this.mineshaftGenerator.generateStructure(this.worldObj, this.rand, chunkcoordintpair); } if (this.settings.useVillages && this.mapFeaturesEnabled) { hasVillage = this.villageGenerator.generateStructure(this.worldObj, this.rand, chunkcoordintpair); } if (this.settings.useStrongholds && this.mapFeaturesEnabled) { this.strongholdGenerator.generateStructure(this.worldObj, this.rand, chunkcoordintpair); } if (this.settings.useTemples && this.mapFeaturesEnabled) { this.scatteredFeatureGenerator.generateStructure(this.worldObj, this.rand, chunkcoordintpair); } if (this.settings.useMonuments && this.mapFeaturesEnabled) { this.oceanMonumentGenerator.generateStructure(this.worldObj, this.rand, chunkcoordintpair); } // 生成湖 if ( biome != BiomeGenBase.desert && biome != BiomeGenBase.desertHills && this.settings.useWaterLakes && !hasVillage && this.rand.nextInt(this.settings.waterLakeChance) == 0 && net.minecraftforge.event.terraingen.TerrainGen.populate(chunkProvider, worldObj, rand, chunkX, chunkZ, hasVillage, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAKE)) { int i1 = this.rand.nextInt(16) + 8; int j1 = this.rand.nextInt(256); int k1 = this.rand.nextInt(16) + 8; (new WorldGenLakes(Blocks.water)).generate(this.worldObj, this.rand, minBlockPos.add(i1, j1, k1)); } // 生成岩浆湖 if ( !hasVillage && this.rand.nextInt(this.settings.lavaLakeChance / 10) == 0 && this.settings.useLavaLakes && net.minecraftforge.event.terraingen.TerrainGen.populate(chunkProvider, worldObj, rand, chunkX, chunkZ, hasVillage, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.LAVA)) { int i2 = this.rand.nextInt(16) + 8; int l2 = this.rand.nextInt(this.rand.nextInt(248) + 8); int k3 = this.rand.nextInt(16) + 8; if (l2 < this.worldObj.getSeaLevel() || this.rand.nextInt(this.settings.lavaLakeChance / 8) == 0) { (new WorldGenLakes(Blocks.lava)).generate(this.worldObj, this.rand, minBlockPos.add(i2, l2, k3)); } } // 生成地牢(刷怪笼) if (this.settings.useDungeons) { boolean doGen = net.minecraftforge.event.terraingen.TerrainGen.populate(chunkProvider, worldObj, rand, chunkX, chunkZ, hasVillage, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.DUNGEON); for (int j2 = 0; doGen && j2 < this.settings.dungeonChance; ++j2) { int i3 = this.rand.nextInt(16) + 8; int l3 = this.rand.nextInt(256); int l1 = this.rand.nextInt(16) + 8; (new WorldGenDungeons()).generate(this.worldObj, this.rand, minBlockPos.add(i3, l3, l1)); } } // 生成树和矿石等 biome.decorate(this.worldObj, this.rand, new BlockPos(minBlockX, 0, minBlockZ)); // 生成动物 if (net.minecraftforge.event.terraingen.TerrainGen.populate(chunkProvider, worldObj, rand, chunkX, chunkZ, hasVillage, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ANIMALS)) { SpawnerAnimals.performWorldGenSpawning(this.worldObj, biome, minBlockX + 8, minBlockZ + 8, 16, 16, this.rand); } minBlockPos = minBlockPos.add(8, 0, 8); // 生成冰和雪 boolean doGen = net.minecraftforge.event.terraingen.TerrainGen.populate(chunkProvider, worldObj, rand, chunkX, chunkZ, hasVillage, net.minecraftforge.event.terraingen.PopulateChunkEvent.Populate.EventType.ICE); for (int x = 0; doGen && x < 16; ++x) { for (int z = 0; z < 16; ++z) { BlockPos topBlock = this.worldObj.getPrecipitationHeight(minBlockPos.add(x, 0, z)); BlockPos downBlock = topBlock.down(); if (this.worldObj.canBlockFreezeWater(downBlock)) { this.worldObj.setBlockState(downBlock, Blocks.ice.getDefaultState(), 2); } if (this.worldObj.canSnowAt(topBlock, true)) { this.worldObj.setBlockState(topBlock, Blocks.snow_layer.getDefaultState(), 2); } } } net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.PopulateChunkEvent.Post(chunkProvider, worldObj, rand, chunkX, chunkZ, hasVillage)); BlockFalling.fallInstantly = false; }
类名net.minecraft.world.biome.BiomeDecorator
public void decorate(World worldIn, Random random, BiomeGenBase biome, BlockPos minBlockPos) { if (this.currentWorld != null) { throw new RuntimeException("Already decorating"); } else { // 读取世界设置 this.currentWorld = worldIn; String s = worldIn.getWorldInfo().getGeneratorOptions(); if (s != null) { this.chunkProviderSettings = ChunkProviderSettings.Factory.jsonToFactory(s).func_177864_b(); } else { this.chunkProviderSettings = ChunkProviderSettings.Factory.jsonToFactory("").func_177864_b(); } this.randomGenerator = random; this.field_180294_c = minBlockPos; // 构造矿物、泥土、砂砾等数据 this.dirtGen = new WorldGenMinable(Blocks.dirt.getDefaultState(), this.chunkProviderSettings.dirtSize); this.gravelGen = new WorldGenMinable(Blocks.gravel.getDefaultState(), this.chunkProviderSettings.gravelSize); this.graniteGen = new WorldGenMinable(Blocks.stone.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.GRANITE), this.chunkProviderSettings.graniteSize); this.dioriteGen = new WorldGenMinable(Blocks.stone.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.DIORITE), this.chunkProviderSettings.dioriteSize); this.andesiteGen = new WorldGenMinable(Blocks.stone.getDefaultState().withProperty(BlockStone.VARIANT, BlockStone.EnumType.ANDESITE), this.chunkProviderSettings.andesiteSize); this.coalGen = new WorldGenMinable(Blocks.coal_ore.getDefaultState(), this.chunkProviderSettings.coalSize); this.ironGen = new WorldGenMinable(Blocks.iron_ore.getDefaultState(), this.chunkProviderSettings.ironSize); this.goldGen = new WorldGenMinable(Blocks.gold_ore.getDefaultState(), this.chunkProviderSettings.goldSize); this.redstoneGen = new WorldGenMinable(Blocks.redstone_ore.getDefaultState(), this.chunkProviderSettings.redstoneSize); this.diamondGen = new WorldGenMinable(Blocks.diamond_ore.getDefaultState(), this.chunkProviderSettings.diamondSize); this.lapisGen = new WorldGenMinable(Blocks.lapis_ore.getDefaultState(), this.chunkProviderSettings.lapisSize); // 生成 this.genDecorations(biome); this.currentWorld = null; this.randomGenerator = null; } } protected void genDecorations(BiomeGenBase biomeGenBaseIn) { net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Pre(currentWorld, randomGenerator, field_180294_c)); // 生成矿物 this.generateOres(); // ... int treeCount = this.treesPerChunk; if (this.randomGenerator.nextInt(10) == 0) { ++treeCount; } if(net.minecraftforge.event.terraingen.TerrainGen.decorate(currentWorld, randomGenerator, field_180294_c, net.minecraftforge.event.terraingen.DecorateBiomeEvent.Decorate.EventType.TREE)) for (int i = 0; i < treeCount; ++i) { int x = this.randomGenerator.nextInt(16) + 8; int z = this.randomGenerator.nextInt(16) + 8; // 1/10概率生成大树 WorldGenAbstractTree genTree = biomeGenBaseIn.genBigTreeChance(this.randomGenerator); // 只有大树实现了,设置叶子最远距离 genTree.func_175904_e(); BlockPos blockpos = this.currentWorld.getHeight(this.field_180294_c.add(x, 0, z)); // 生成树 if (genTree.generate(this.currentWorld, this.randomGenerator, blockpos)) { // 只有巨型菠萝树实现了 genTree.func_180711_a(this.currentWorld, this.randomGenerator, blockpos); } } // ... net.minecraftforge.common.MinecraftForge.EVENT_BUS.post(new net.minecraftforge.event.terraingen.DecorateBiomeEvent.Post(currentWorld, randomGenerator, field_180294_c)); } /** * Generates ores in the current chunk */ protected void generateOres() { net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Pre(currentWorld, randomGenerator, field_180294_c)); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, dirtGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIRT)) this.genStandardOre1(this.chunkProviderSettings.dirtCount, this.dirtGen, this.chunkProviderSettings.dirtMinHeight, this.chunkProviderSettings.dirtMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, gravelGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRAVEL)) this.genStandardOre1(this.chunkProviderSettings.gravelCount, this.gravelGen, this.chunkProviderSettings.gravelMinHeight, this.chunkProviderSettings.gravelMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, dioriteGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIORITE)) this.genStandardOre1(this.chunkProviderSettings.dioriteCount, this.dioriteGen, this.chunkProviderSettings.dioriteMinHeight, this.chunkProviderSettings.dioriteMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, graniteGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GRANITE)) this.genStandardOre1(this.chunkProviderSettings.graniteCount, this.graniteGen, this.chunkProviderSettings.graniteMinHeight, this.chunkProviderSettings.graniteMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, andesiteGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.ANDESITE)) this.genStandardOre1(this.chunkProviderSettings.andesiteCount, this.andesiteGen, this.chunkProviderSettings.andesiteMinHeight, this.chunkProviderSettings.andesiteMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, coalGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.COAL)) this.genStandardOre1(this.chunkProviderSettings.coalCount, this.coalGen, this.chunkProviderSettings.coalMinHeight, this.chunkProviderSettings.coalMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, ironGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.IRON)) this.genStandardOre1(this.chunkProviderSettings.ironCount, this.ironGen, this.chunkProviderSettings.ironMinHeight, this.chunkProviderSettings.ironMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, goldGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.GOLD)) this.genStandardOre1(this.chunkProviderSettings.goldCount, this.goldGen, this.chunkProviderSettings.goldMinHeight, this.chunkProviderSettings.goldMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, redstoneGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.REDSTONE)) this.genStandardOre1(this.chunkProviderSettings.redstoneCount, this.redstoneGen, this.chunkProviderSettings.redstoneMinHeight, this.chunkProviderSettings.redstoneMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, diamondGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.DIAMOND)) this.genStandardOre1(this.chunkProviderSettings.diamondCount, this.diamondGen, this.chunkProviderSettings.diamondMinHeight, this.chunkProviderSettings.diamondMaxHeight); if (net.minecraftforge.event.terraingen.TerrainGen.generateOre(currentWorld, randomGenerator, lapisGen, field_180294_c, net.minecraftforge.event.terraingen.OreGenEvent.GenerateMinable.EventType.LAPIS)) this.genStandardOre2(this.chunkProviderSettings.lapisCount, this.lapisGen, this.chunkProviderSettings.lapisCenterHeight, this.chunkProviderSettings.lapisSpread); net.minecraftforge.common.MinecraftForge.ORE_GEN_BUS.post(new net.minecraftforge.event.terraingen.OreGenEvent.Post(currentWorld, randomGenerator, field_180294_c)); } /** * Standard ore generation helper. Generates most ores. */ protected void genStandardOre1(int blockCount, WorldGenerator generator, int minHeight, int maxHeight) { if (maxHeight < minHeight) { int t = minHeight; minHeight = maxHeight; maxHeight = t; } else if (maxHeight == minHeight) { if (minHeight < 255) { ++maxHeight; } else { --minHeight; } } // 生成blockCount堆矿石 for (int i = 0; i < blockCount; ++i) { BlockPos blockpos = this.field_180294_c.add(this.randomGenerator.nextInt(16), this.randomGenerator.nextInt(maxHeight - minHeight) + minHeight, this.randomGenerator.nextInt(16)); generator.generate(this.currentWorld, this.randomGenerator, blockpos); } }
生成矿物
划一条线,然后沿着线上生成numberOfBlocks个椭球,把椭球内的方块替换为矿石
类名net.minecraft.world.gen.feature.WorldGenMinable
public boolean generate(World worldIn, Random rand, BlockPos position) { // 在xz平面上的方向 float angle = rand.nextFloat() * (float)Math.PI; // 起始点和结束点 double startX = (double)((float)(position.getX() + 8) + MathHelper.sin(angle) * (float)this.numberOfBlocks / 8.0F); double endX = (double)((float)(position.getX() + 8) - MathHelper.sin(angle) * (float)this.numberOfBlocks / 8.0F); double startZ = (double)((float)(position.getZ() + 8) + MathHelper.cos(angle) * (float)this.numberOfBlocks / 8.0F); double endZ = (double)((float)(position.getZ() + 8) - MathHelper.cos(angle) * (float)this.numberOfBlocks / 8.0F); double startY = (double)(position.getY() + rand.nextInt(3) - 2); double endY = (double)(position.getY() + rand.nextInt(3) - 2); // numberOfBlocks是反混淆错误,应该是几个椭球的意思 for (int i = 0; i < this.numberOfBlocks; ++i) { // 插值参数 float t = (float)i / (float)this.numberOfBlocks; // 椭球中心 double centerX = startX + (endX - startX) * (double)t; double centerY = startY + (endY - startY) * (double)t; double centerZ = startZ + (endZ - startZ) * (double)t; // 椭球尺寸(可以看出XZ和Y尺寸一样,应该是球) double scale = rand.nextDouble() * (double)this.numberOfBlocks / 16.0D; double diameterXZ = (double)(MathHelper.sin((float)Math.PI * t) + 1.0F) * scale + 1.0D; double diameterY = (double)(MathHelper.sin((float)Math.PI * t) + 1.0F) * scale + 1.0D; // 椭球包围盒 int minX = MathHelper.floor_double(centerX - diameterXZ / 2.0D); int minY = MathHelper.floor_double(centerY - diameterY / 2.0D); int minZ = MathHelper.floor_double(centerZ - diameterXZ / 2.0D); int maxX = MathHelper.floor_double(centerX + diameterXZ / 2.0D); int maxY = MathHelper.floor_double(centerY + diameterY / 2.0D); int maxZ = MathHelper.floor_double(centerZ + diameterXZ / 2.0D); // 把这个椭球里的方块替换为矿石 for (int x = minX; x <= maxX; ++x) { double xDist = ((double)x + 0.5D - centerX) / (diameterXZ / 2.0D); if (xDist * xDist < 1.0D) // 参考椭球方程 { for (int y = minY; y <= maxY; ++y) { double yDist = ((double)y + 0.5D - centerY) / (diameterY / 2.0D); if (xDist * xDist + yDist * yDist < 1.0D) // 参考椭球方程 { for (int z = minZ; z <= maxZ; ++z) { double zDist = ((double)z + 0.5D - centerZ) / (diameterXZ / 2.0D); if (xDist * xDist + yDist * yDist + zDist * zDist < 1.0D) // 参考椭球方程 { BlockPos blockpos = new BlockPos(x, y, z); // 可以替换这个方块 if (worldIn.getBlockState(blockpos).getBlock().isReplaceableOreGen(worldIn, blockpos, this.predicate)) { // 替换为矿石 worldIn.setBlockState(blockpos, this.oreBlock, 2); } } } } } } } } return true; }
生成树
随便找了一个可可豆树的类,类名net.minecraft.world.gen.feature.WorldGenTrees
public boolean generate(World worldIn, Random rand, BlockPos position) { int height = rand.nextInt(3) + this.minTreeHeight; boolean isReplaceable = true; if (position.getY() >= 1 && position.getY() + height + 1 <= 256) { // 检查所有方块可替换 for (int y = position.getY(); y <= position.getY() + 1 + height; ++y) { int xzSize = 1; // 底端 if (y == position.getY()) { xzSize = 0; } // 顶端 if (y >= position.getY() + height - 1) { xzSize = 2; } // 检查这个平面所有方块可替换 BlockPos.MutableBlockPos tmpPos = new BlockPos.MutableBlockPos(); for (int x = position.getX() - xzSize; x <= position.getX() + xzSize && isReplaceable; ++x) { for (int z = position.getZ() - xzSize; z <= position.getZ() + xzSize && isReplaceable; ++z) { if (y >= 0 && y < 256) { if (!this.isReplaceable(worldIn, tmpPos.set(x, y, z))) { isReplaceable = false; } } else { isReplaceable = false; } } } } if (!isReplaceable) { return false; } else { BlockPos downPos = position.downPos(); Block downBlock = worldIn.getBlockState(downPos).getBlock(); // 是可生成树的土壤 boolean isSoil = downBlock.canSustainPlant(worldIn, downPos, net.minecraft.util.EnumFacing.UP, (net.minecraft.block.BlockSapling)Blocks.sapling); if (isSoil && position.getY() < 256 - height - 1) { downBlock.onPlantGrow(worldIn, downPos, position); // 生成叶子 for (int y = position.getY() + height - 3; y <= position.getY() + height; ++y) { int restHeight = y - (position.getY() + height); int xzSize = 1 - restHeight / 2; for (int x = position.getX() - xzSize; x <= position.getX() + xzSize; ++x) { int xOffset = x - position.getX(); for (int z = position.getZ() - xzSize; z <= position.getZ() + xzSize; ++z) { int zOffset = z - position.getZ(); if ( Math.abs(xOffset) != xzSize || Math.abs(zOffset) != xzSize // 不在边缘4个点 || rand.nextInt(2) != 0 && restHeight != 0) { BlockPos blockpos = new BlockPos(x, y, z); Block block = worldIn.getBlockState(blockpos).getBlock(); if ( block.isAir(worldIn, blockpos) || block.isLeaves(worldIn, blockpos) || block.getMaterial() == Material.vine) { this.setBlockAndNotifyAdequately(worldIn, blockpos, this.metaLeaves); } } } } } // 生成木头 for (int y = 0; y < height; ++y) { BlockPos upPos = position.up(y); Block upBlock = worldIn.getBlockState(upPos).getBlock(); if ( upBlock.isAir(worldIn, upPos) || upBlock.isLeaves(worldIn, upPos) || upBlock.getMaterial() == Material.vine) { this.setBlockAndNotifyAdequately(worldIn, position.up(y), this.metaWood); // 生成藤蔓 if (this.vinesGrow && y > 0) { if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(-1, y, 0))) { this.func_181651_a(worldIn, position.add(-1, y, 0), BlockVine.EAST); } if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(1, y, 0))) { this.func_181651_a(worldIn, position.add(1, y, 0), BlockVine.WEST); } if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(0, y, -1))) { this.func_181651_a(worldIn, position.add(0, y, -1), BlockVine.SOUTH); } if (rand.nextInt(3) > 0 && worldIn.isAirBlock(position.add(0, y, 1))) { this.func_181651_a(worldIn, position.add(0, y, 1), BlockVine.NORTH); } } } } // 生成藤蔓 if (this.vinesGrow) { for (int y = position.getY() + height - 3; y <= position.getY() + height; ++y) { int restHeight = y - (position.getY() + height); int xzSize = 2 - restHeight / 2; BlockPos.MutableBlockPos tmpPos = new BlockPos.MutableBlockPos(); for (int x = position.getX() - xzSize; x <= position.getX() + xzSize; ++x) { for (int z = position.getZ() - xzSize; z <= position.getZ() + xzSize; ++z) { tmpPos.set(x, y, z); if (worldIn.getBlockState(tmpPos).getBlock().isLeaves(worldIn,tmpPos)) { BlockPos blockpos2 = tmpPos.west(); BlockPos blockpos3 = tmpPos.east(); BlockPos blockpos4 = tmpPos.north(); BlockPos blockpos1 = tmpPos.south(); if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos2).getBlock().isAir(worldIn,blockpos2)) { this.func_181650_b(worldIn, blockpos2, BlockVine.EAST); } if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos3).getBlock().isAir(worldIn,blockpos3)) { this.func_181650_b(worldIn, blockpos3, BlockVine.WEST); } if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos4).getBlock().isAir(worldIn,blockpos4)) { this.func_181650_b(worldIn, blockpos4, BlockVine.SOUTH); } if (rand.nextInt(4) == 0 && worldIn.getBlockState(blockpos1).getBlock().isAir(worldIn,blockpos1)) { this.func_181650_b(worldIn, blockpos1, BlockVine.NORTH); } } } } } // 生成可可豆 if (rand.nextInt(5) == 0 && height > 5) { for (int yOffset = 0; yOffset < 2; ++yOffset) { for (EnumFacing enumfacing : EnumFacing.Plane.HORIZONTAL) { if (rand.nextInt(4 - yOffset) == 0) { EnumFacing enumfacing1 = enumfacing.getOpposite(); this.func_181652_a(worldIn, rand.nextInt(3), position.add(enumfacing1.getFrontOffsetX(), height - 5 + yOffset, enumfacing1.getFrontOffsetZ()), enumfacing); } } } } } return true; } else { return false; } } } else { return false; } }
生成动物
虽然生成方块研究完了,姑且研究下动物
类名net.minecraft.world.SpawnerAnimals
/** * Called during chunk generation to spawn initial creatures. * * @param biomeIn The biome to use for the weighted entity creatureList * @param randomIn The random to use for mob spawning */ public static void performWorldGenSpawning(World worldIn, BiomeGenBase biomeIn, int x, int z, int xSize, int zSize, Random randomIn) { // 这个生物群系可生成的生物 List<BiomeGenBase.SpawnListEntry> creatureList = biomeIn.getSpawnableList(EnumCreatureType.CREATURE); if (!creatureList.isEmpty()) { while (randomIn.nextFloat() < biomeIn.getSpawningChance()) { BiomeGenBase.SpawnListEntry spawn = (BiomeGenBase.SpawnListEntry)WeightedRandom.getRandomItem(worldIn.rand, creatureList); int entityCount = spawn.minGroupCount + randomIn.nextInt(1 + spawn.maxGroupCount - spawn.minGroupCount); IEntityLivingData data = null; int spawnX = x + randomIn.nextInt(xSize); int spawnZ = z + randomIn.nextInt(zSize); int centerX = spawnX; int centerZ = spawnZ; for (int i = 0; i < entityCount; ++i) { boolean hasSpawned = false; // 尝试生成4次 for (int j = 0; !hasSpawned && j < 4; ++j) { BlockPos topPos = worldIn.getTopSolidOrLiquidBlock(new BlockPos(spawnX, 0, spawnZ)); // 能生成在这个方块上 if (canCreatureTypeSpawnAtLocation(EntityLiving.SpawnPlacementType.ON_GROUND, worldIn, topPos)) { EntityLiving entity; try { entity = (EntityLiving)spawn.entityClass.getConstructor(new Class[] {World.class}).newInstance(new Object[] {worldIn}); } catch (Exception exception) { exception.printStackTrace(); continue; } // 设置位置和方向 entity.setLocationAndAngles((double)((float)spawnX + 0.5F), (double)topPos.getY(), (double)((float)spawnZ + 0.5F), randomIn.nextFloat() * 360.0F, 0.0F); // 生成 worldIn.spawnEntityInWorld(entity); data = entity.onInitialSpawn(worldIn.getDifficultyForLocation(new BlockPos(entity)), data); hasSpawned = true; } spawnX += randomIn.nextInt(5) - randomIn.nextInt(5); for (spawnZ += randomIn.nextInt(5) - randomIn.nextInt(5); spawnX < x || spawnX >= x + xSize || spawnZ < z || spawnZ >= z + xSize; spawnZ = centerZ + randomIn.nextInt(5) - randomIn.nextInt(5)) { spawnX = centerX + randomIn.nextInt(5) - randomIn.nextInt(5); } } } } } }
0 0
- Minecraft的世界生成过程(七)矿物和树
- Minecraft的世界生成过程(一)生成地形之前
- Minecraft的世界生成过程(二)生物群系
- Minecraft的世界生成过程(三)噪声函数
- Minecraft的世界生成过程(四)地表
- Minecraft的世界生成过程(六)村庄
- 进阶篇,第一章:矿物的生成
- Unity3D MineCraft 使用Unity3D制作MineCraft 我的世界 存盘和读取问题解决
- 我的世界 unity3d minecraft 用unity3d来制作类似我的世界的游戏 优化树和草
- Minecraft (我的世界)服务器搭建经验分享
- Unity3D MineCraft 我的世界 用Unity3D制作类似MineCraft我的世界的游戏:各种树
- Minecraft:随时随地创造你的世界
- Minecraft我的世界开服教程
- Unity实现类似我的世界(Minecraft)的创建物体以及销毁物体的功能
- Minecraft世界生成器代码
- Unity3D MineCraft 我的世界 类似游戏的地形编辑器
- bzoj[1855] [Scoi2010]股票交易 ,[2826]Minecraft的世界末日
- 我的世界 Unity3D MineCraft 用Unity3D制作类似MineCraft我的世界的游戏 洞穴算是完成了
- Minecraft的世界生成过程(六)村庄
- 文章标题
- 03网络请求_02_Volley_3_定制自己的Request
- 蓝桥杯 危险系数
- mybatis hello world
- Minecraft的世界生成过程(七)矿物和树
- 理解springMVC的controller
- STM32 HAL库、标准外设库、LL库(STM32 Embedded Software)
- 03网络请求_02_Volley_4_带你从源码的角度理解Volley
- log4j.properties 源码
- 51nod 1284 2、3、5、7的倍数 (容斥原理)
- Netty学习(六)-LengthFieldBasedFrameDecoder解码器
- mybatis中接口没有实现类的动态代理探究
- 安卓开发——问题:RecycleView做瀑布流滚动时,已加载item的位置来回变动