Ejemplo n.º 1
0
    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;
    }
Ejemplo n.º 2
0
    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();
    }
Ejemplo n.º 3
0
        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
                }
            }
        }