예제 #1
0
    // Create path areas
    private void CreatePathAreas(TerrainStructure terrainStructure)
    {
        List <int> availableSegments = _graph.FindNodesWithData(new AreaSegment(AreaSegment.EAreaSegmentType.MainPath)).ToList();

        availableSegments = availableSegments.Union(_graph.FindNodesWithData(new AreaSegment(AreaSegment.EAreaSegmentType.Start))).ToList();
        List <AreaSettingsFactory> availableSettings = terrainStructure.BiomeSettings.PathAreas.ToList();

        availableSettings.Sort();

        while (availableSegments.Count > 0 && availableSettings.Count > 0)
        {
            AreaSettingsFactory   settingsFactory = availableSettings.Last();
            Dictionary <int, int> matches         = _graph.MatchPattern(settingsFactory.GetPatternGraph());

            if (matches == null)
            {
                availableSettings.Remove(settingsFactory);
                continue;
            }

            foreach (var match in matches)
            {
                availableSegments.Remove(match.Value);
                _graph.RemoveNode(match.Value);
            }

            Graph <AreaData> areaDataGraph = terrainStructure.GetAreaDataGraph(matches.Values);
            List <Vector2[]> clearPolygons = terrainStructure.GetPathPolygons(matches.Values);
            Vector2[]        borderPolygon = terrainStructure.GetAreaSegmentsBorderPolygon(matches.Values);

            Areas.AddRange(settingsFactory.ProduceAreaSettings(areaDataGraph, clearPolygons, borderPolygon));
        }
    }
예제 #2
0
    public SceneryStructure(StoryStructure storyStructure, TerrainStructure terrainStructure)
    {
        _graph = new GrammarGraph <AreaSegment>(terrainStructure.AreaSegmentGraph);

        // Assign speacial areas
        CreateSpecialAreas(terrainStructure);

        // Assign paths to area settings
        CreatePathAreas(terrainStructure);

        // Assign boss area segments to area settings
        CreateBossAreas(terrainStructure);
    }
예제 #3
0
    // Set alphamap texture based on biome configuration
    public static float[,,] GenerateAlphaMap(TerrainStructure terrainStructure)
    {
        var result = new float[terrainStructure.HeightMapResolution, terrainStructure.HeightMapResolution,
                               terrainStructure.TextureCount];
        var cellSize = terrainStructure.MapSize / terrainStructure.HeightMapResolution;

        for (int y = 0; y < terrainStructure.HeightMapResolution; y++)
        {
            for (int x = 0; x < terrainStructure.HeightMapResolution; x++)
            {
                KeyValuePair <int, float> sample = terrainStructure.SampleTexture(new Vector2(x * cellSize, y * cellSize));
                result[y, x, sample.Key] = sample.Value;
            }
        }
        return(result);
    }
예제 #4
0
    // Generate a heightmap given terrain structure and biome configuration
    public static float[,] GenerateHeightMap(TerrainStructure terrainStructure)
    {
        var result   = new float[terrainStructure.HeightMapResolution, terrainStructure.HeightMapResolution];
        var cellSize = terrainStructure.MapSize / terrainStructure.HeightMapResolution;

        var octavesOffset = new Vector2[terrainStructure.Octaves];

        for (var i = 0; i < octavesOffset.Length; i++)
        {
            octavesOffset[i] = new Vector2(Random.Range(-100000f, 100000f), Random.Range(-100000f, 100000f));
        }

        // Generate heightmap
        for (var y = 0; y < terrainStructure.HeightMapResolution; y++)
        {
            for (var x = 0; x < terrainStructure.HeightMapResolution; x++)
            {
                var biomeHeight = terrainStructure.SampleHeight(new Vector2(x * cellSize, y * cellSize));
                var amplitude   = 1f;
                var frequency   = 1f;
                var noiseHeight = 0f;

                for (int i = 0; i < octavesOffset.Length; i++)
                {
                    var sampleX = (x + octavesOffset[i].x) / terrainStructure.MapSize * frequency *
                                  (biomeHeight.Scale * cellSize);
                    var sampleY = (y + octavesOffset[i].y) / terrainStructure.MapSize * frequency *
                                  (biomeHeight.Scale * cellSize);

                    /* Noise between -1 and 1 */
                    noiseHeight += (Mathf.PerlinNoise(sampleX, sampleY) * 2 - 1) * amplitude;

                    amplitude *= biomeHeight.Persistence;
                    frequency *= biomeHeight.Lacunarity;
                }
                float normalizedHeight = Mathf.InverseLerp(-1f, 1f, noiseHeight);
                float globalHeight     = (biomeHeight.LocalMax - biomeHeight.LocalMin) * normalizedHeight +
                                         biomeHeight.LocalMin;
                result[y, x] = globalHeight;
            }
        }

        return(result);
    }
예제 #5
0
    // Redraws preview in the scene editor
    public void GenerateLevel()
    {
#if UNITY_EDITOR
        if (!GenerateOnPlay && Application.isPlaying)
        {
            return;
        }
#endif

        Random.InitState(Seed);
        ClearDisplay();
        MyStoryStructure   = new StoryStructure(0, 1, MainPathNodeCount, SidePathCount, SidePathNodeCount, new CharacterEnemy[4]);
        MyTerrainStructure = new TerrainStructure(MyStoryStructure, AvailableBiomes, MapSize, HeightMapResolution, Octaves, VoronoiSamples, LloydRelaxation, HeightNoise, AlphaNoise, BorderBlockerOffset);
        MySceneryStructure = new SceneryStructure(MyStoryStructure, MyTerrainStructure);

        switch (DrawMode)
        {
        case DrawModeEnum.TerrainSkeleton:
            DrawTerrainSkeleton();
            break;

        case DrawModeEnum.Terrain:
            DrawTerrain();
            break;

        case DrawModeEnum.ScenerySkeleton:
            DrawScenerySkeleton();
            break;

        case DrawModeEnum.Scenery:
            DrawTerrainAndScenery();
            break;

        case DrawModeEnum.GameLevel:
            DrawCompleteLevel();
            break;

        default:
            throw new ArgumentOutOfRangeException();
        }
    }
    public void Get_Terrain_Test()
    {
        //Arrange
        var terrainStructure = new TerrainStructure();

        var terrainModels = new List <TerrainModel>()
        {
            new TerrainModel()
            {
                Type = TerrainType.Grass
            },
            new TerrainModel()
            {
                Type = TerrainType.Road
            },
            new TerrainModel()
            {
                Type = TerrainType.Rail
            },
            new TerrainModel()
            {
                Type = TerrainType.Water
            }
        };

        terrainStructure.Construct(terrainModels);
        //Act
        var actual = new List <TerrainType>();

        for (int i = 0; i < 100000; i++)
        {
            actual.Add(terrainStructure.GetTerrain().Type);
        }

        //Assert
        CheckMaxRepetition(actual);
    }
예제 #7
0
    public static GameObject DrawAreaSegments(TerrainStructure terrainStructure, string name = "AreaSegments")
    {
        GameObject result = new GameObject(name);
        var        graph  = terrainStructure.AreaSegmentGraph;

        // Draw all lines
        GameObject edges = new GameObject("Edges");

        edges.transform.parent = result.transform;
        foreach (var edge in graph.GetAllEdges())
        {
            Vector2 start = terrainStructure.GetAreaSegmentCenter(edge.x);
            Vector2 end   = terrainStructure.GetAreaSegmentCenter(edge.y);
            Color   color;

            switch ((AreaSegment.EAreaSegmentEdgeType)graph.GetEdgeValue(edge.x, edge.y))
            {
            case AreaSegment.EAreaSegmentEdgeType.NonNavigable:
                color = Color.black;
                break;

            case AreaSegment.EAreaSegmentEdgeType.MainPath:
                color = Color.green;
                break;

            case AreaSegment.EAreaSegmentEdgeType.SidePath:
                color = Color.cyan;
                break;

            case AreaSegment.EAreaSegmentEdgeType.BossInnerPath:
                color = Color.red;
                break;

            case AreaSegment.EAreaSegmentEdgeType.SpecialInnerPath:
                color = Color.yellow;
                break;

            default:
                color = Color.gray;
                break;
            }

            GameObject line = DrawLine(new Vector3(start.x, 0, start.y), new Vector3(end.x, 0, end.y), 5, color);
            line.transform.parent = edges.transform;
        }

        // Draw all centers
        GameObject nodes = new GameObject("Nodes");

        nodes.transform.parent = result.transform;
        foreach (var id in graph.GetAllNodeIDs())
        {
            AreaSegment data   = graph.GetNodeData(id);
            Vector2     center = terrainStructure.GetAreaSegmentCenter(id);
            Color       color;
            switch (data.Type)
            {
            case AreaSegment.EAreaSegmentType.Empty:
                color = Color.white;
                break;

            case AreaSegment.EAreaSegmentType.Border:
                color = Color.black;
                break;

            case AreaSegment.EAreaSegmentType.Start:
                color = Color.blue;
                break;

            case AreaSegment.EAreaSegmentType.Boss:
                color = Color.red;
                break;

            case AreaSegment.EAreaSegmentType.Special:
                color = Color.yellow;
                break;

            case AreaSegment.EAreaSegmentType.MainPath:
                color = Color.green;
                break;

            case AreaSegment.EAreaSegmentType.SidePath:
                color = Color.cyan;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            GameObject node = DrawSphere(new Vector3(center.x, 0, center.y), 20, color);
            node.name             = "Node " + id + " - " + data.Type;
            node.transform.parent = nodes.transform;
        }

        return(result);
    }