void BuildChunk() { bool isSaved = LoadChunk(); blocksInChunk = new Block[World.chunkSize, World.chunkSize, World.chunkSize]; //create blocks and add them to 3D array for (int z = 0; z < World.chunkSize; z++) { for (int y = 0; y < World.chunkSize; y++) { for (int x = 0; x < World.chunkSize; x++) { Vector3 newBlockLocalPosition = new Vector3(x, y, z); Vector3 newBlockWorldPosition = new Vector3 ( (int)(x + chunkGameObject.transform.position.x), (int)(y + chunkGameObject.transform.position.y), (int)(z + chunkGameObject.transform.position.z) ); // if this chunk is saved, load the block data from the save file a continue to next iteration if (isSaved) { blocksInChunk[x, y, z] = new Block(SaveLoad.blockData.blockTypeMatrix[x, y, z], newBlockLocalPosition, this); continue; } // build block with a block type acording to the height (y position) if ((int)newBlockWorldPosition.y <= HeightGenerator.GenerateUnbreakableHeight(newBlockWorldPosition.x, newBlockWorldPosition.z)) { blocksInChunk[x, y, z] = new Block(Block.BlockType.UNBREAKABLE, newBlockLocalPosition, this); } else if ((int)newBlockWorldPosition.y <= HeightGenerator.GenerateStoneHeight(newBlockWorldPosition.x, newBlockWorldPosition.z)) { blocksInChunk[x, y, z] = new Block(Block.BlockType.STONE, newBlockLocalPosition, this); } else if ((int)newBlockWorldPosition.y < HeightGenerator.GenerateTerrainHeight(newBlockWorldPosition.x, newBlockWorldPosition.z)) { blocksInChunk[x, y, z] = new Block(Block.BlockType.DIRT, newBlockLocalPosition, this); } else if ((int)newBlockWorldPosition.y == HeightGenerator.GenerateTerrainHeight(newBlockWorldPosition.x, newBlockWorldPosition.z)) { blocksInChunk[x, y, z] = new Block(Block.BlockType.GRASS, newBlockLocalPosition, this); } else { blocksInChunk[x, y, z] = new Block(Block.BlockType.AIR, newBlockLocalPosition, this); } } } } toBeDrawn = true; }
public void NewGame() { ResetWorldToDefault(); // set random offset for the height generator algorithm heightGeneratorOffsetX = UnityEngine.Random.Range(10000, 30000); heightGeneratorOffsetZ = UnityEngine.Random.Range(10000, 30000); HeightGenerator.offsetX = heightGeneratorOffsetX; HeightGenerator.offsetZ = heightGeneratorOffsetZ; player.transform.position = new Vector3( 0f, HeightGenerator.GenerateTerrainHeight(0f, 0f) + 1, 0f ); lastPlayerPosition = player.transform.position; BuildWorld(); }
private void GenerateSurface(ref DataChunk chunk, Point3 pos) { int x, z, position, maxY, curY; double y, fX, terrainRange, treeChance; for (ushort xz = 0; xz < 16 * 16; xz++) { x = (xz & 0x00F); z = (xz & 0x0F0) / 0x10; x += pos.X * 0x10; z += pos.Z * 0x10; terrainRange = TerrainRangeGenerator.Generate(x, z); // Roughen up the surface a little 10% y = .9 + HeightRoughner.Generate(x, z) * .1; if (terrainRange >= .5) { #region Above sealevel y *= HeightGenerator.Generate(x, z); // Apply the TerrainRange noise y *= (terrainRange - .5) * 2; // Apply the max height y *= MaxMountainHight - MinSurfaceHeight; // This is were we seperate the mountains from the hills // .5(x+4(x-.5)^3+.5) fX = y / (MaxMountainHight - MinSurfaceHeight); fX = fX + (4 * ((fX - .5) * (fX - .5) * (fX - .5)) + .5); fX /= 2; y *= fX; // Apply the min height y += MinSurfaceHeight; // Round it and apply chunk height y = Math.Ceiling(y); maxY = (int)y; y -= pos.Y * 0x10; // Ceiling check if (y > 0xF) { y = 0xF; } // Air check if (y < 0) { continue; } y *= 0x100; position = xz + (int)y; // Surface block curY = (int)(pos.Y * 0x10 + y / 0x100); if (maxY - curY == 0) { if (SurfaceEnd == pos.Y) { treeChance = 0; } else { treeChance = TreeGenerator.Generate(x, z); treeChance *= Math.Round((terrainRange - .5) * 40 > 1 ? 1 : (terrainRange - .5) * 40, 1); treeChance = Math.Round(treeChance, 1); } chunk.Blocks[position] = new DataBlock() { Material = treeChance < 1 ? MaterialType.Grass : MaterialType.Stone, Position = (ushort)position }; } else { chunk.Blocks[position] = new DataBlock() { Material = maxY - curY <= 3 ? MaterialType.Dirt : MaterialType.Stone, Position = (ushort)position }; } // Non-surface blocks while (y >= 0x100) { y -= 0x100; curY = (int)(pos.Y * 0x10 + y / 0x100); position = xz + (int)y; chunk.Blocks[position] = new DataBlock() { Material = maxY - curY <= 3 ? MaterialType.Dirt : MaterialType.Stone, Position = (ushort)position }; } #endregion } else if (terrainRange >= .475) { #region Beach // Apply the TerrainRange noise y *= 1 - (.5 - terrainRange) * 40; // Apply the min height (which is basically the max height for beaches) y *= MinSurfaceHeight + 1; // Round it and apply chunk height y = Math.Ceiling(y); maxY = (int)y; y -= pos.Y * 0x10; // Ceiling check if (y > 0xF) { y = 0xF; } // Air check if (y < 0) { continue; } y *= 0x100; // Surface block position = xz + (int)y; chunk.Blocks[position] = new DataBlock() { Material = MaterialType.Sand, Position = (ushort)position }; // Non-surface blocks while (y >= 0x100) { y -= 0x100; curY = (int)(pos.Y * 0x10 + y / 0x100); position = xz + (int)y; chunk.Blocks[position] = new DataBlock() { Material = MaterialType.Sand, Position = (ushort)position }; } #endregion } else // terrainRange < .475 { #region Ocean // TODO: Water // Apply the TerrainRange noise y *= (.475 - terrainRange) * (1 / .475); // Apply the max depth y *= MaxOceanDepth; // Round it and apply chunk height y = Math.Ceiling(y); maxY = (int)y; y -= pos.Y * 0x10; // Ceiling check if (y > 0xF) { y = 0xF; } // Air check if (y < 0) { continue; } y *= 0x100; // Surface block position = xz + (int)y; chunk.Blocks[position] = new DataBlock() { Material = MaterialType.Stone, Position = (ushort)position }; // Non-surface blocks while (y >= 0x100) { y -= 0x100; curY = (int)(pos.Y * 0x10 + y / 0x100); position = xz + (int)y; chunk.Blocks[position] = new DataBlock() { Material = MaterialType.Stone, Position = (ushort)position }; } #endregion } } }