Esempio n. 1
0
        /// <summary>
        /// 设置海拔,距离海岸线越远,海拔越高
        /// </summary>
        /// <returns>返回最高点</returns>
        private float _LandRiseElevation( )
        {
            // 待设置的拐角
            Queue <RasterIndex> cornerQueue = new Queue <RasterIndex>(_coastCornerList);

            // 某一圈的数量
            int count = cornerQueue.Count;

            // 离海洋的距离,从1开始
            float dis = 1;

            // 广度优先搜索,每次加入一个内圈的
            while (cornerQueue.Count > 0)
            {
                // 上一圈已经全部搞定
                if (count == 0)
                {
                    count = cornerQueue.Count;
                    dis  += 0.1f;
                }

                RasterIndex corner = cornerQueue.Dequeue();
                count--;

                uint x = corner.x;
                uint y = corner.y;
                _cornerElevations[x, y] = dis;

                // 周围4个点是否是land?是否已加入下一圈?已加入设为255
                if (_cornerTypes[x + 1, y] == CornerType.kLand && _cornerElevations[x + 1, y] == 0)
                {
                    _cornerElevations[x + 1, y] = byte.MaxValue;
                    cornerQueue.Enqueue(new RasterIndex(x + 1, y));
                }
                if (_cornerTypes[x, y + 1] == CornerType.kLand && _cornerElevations[x, y + 1] == 0)
                {
                    _cornerElevations[x, y + 1] = byte.MaxValue;
                    cornerQueue.Enqueue(new RasterIndex(x, y + 1));
                }
                if (_cornerTypes[x - 1, y] == CornerType.kLand && _cornerElevations[x - 1, y] == 0)
                {
                    _cornerElevations[x - 1, y] = byte.MaxValue;
                    cornerQueue.Enqueue(new RasterIndex(x - 1, y));
                }
                if (_cornerTypes[x, y - 1] == CornerType.kLand && _cornerElevations[x, y - 1] == 0)
                {
                    _cornerElevations[x, y - 1] = byte.MaxValue;
                    cornerQueue.Enqueue(new RasterIndex(x, y - 1));
                }
            }

            return(dis);
        }
Esempio n. 2
0
        /// <summary>
        /// 用栅格逼近圆
        /// </summary>
        /// <param name="center">圆心</param>
        /// <param name="radius">圆半径</param>
        /// <returns>栅格的标号,只需第一象限的1/4</returns>
        public RasterIndex[] GetCircleIndices(RasterIndex center, float radius)
        {
            float minSize = Mathf.Min(_border.size.x, _border.size.y);

            radius = Mathf.Min(minSize * 0.9f, radius);
            uint radiusNumber = (uint)(radius / _squareSize);

            List <RasterIndex> result = new List <RasterIndex>();

            // 第一个栅格的位置
            RasterIndex index = new RasterIndex();

            index.x = center.x;
            index.y = center.y - radiusNumber;
            result.Add(index);

            while (index.x <= center.x + radiusNumber && index.y <= center.y)
            {
                // 向右下方
                RasterIndex right = new RasterIndex(index.x + 1, index.y);

                RasterIndex down = new RasterIndex(index.x, index.y + 1);

                RasterIndex rightDown = new RasterIndex(index.x + 1, index.y + 1);

                index = right;
                float dis     = Vector2.Distance(GetSquareCenter(index), GetSquareCenter(center));
                float minDiff = Mathf.Abs(dis - radius);

                dis = Vector2.Distance(GetSquareCenter(down), GetSquareCenter(center));
                float diff = Mathf.Abs(dis - radius);
                if (diff < minDiff)
                {
                    minDiff = diff;
                    index   = down;
                }

                dis  = Vector2.Distance(GetSquareCenter(rightDown), GetSquareCenter(center));
                diff = Mathf.Abs(dis - radius);
                if (diff < minDiff)
                {
                    minDiff = diff;
                    index   = rightDown;
                }

                result.Add(index);
            }

            return(result.ToArray());
        }
Esempio n. 3
0
        // Start is called just before any of the Update methods is called the first time
        public void Start( )
        {
            // 初始化栅格
            Rect border = new Rect(Vector2.zero, mapSize);

            _squareSize = border.size.x / m;
            n           = (uint)(border.size.y / _squareSize);
            _raster     = new Raster(border, m, 0.5f);

            float minSize = Mathf.Min(mapSize.x, mapSize.y) * 0.48f;

            radius           = Mathf.Min(minSize, radius);
            normalizedRadius = radius / minSize;

            // 默认整个栅格的中心
            _centerIndex = new RasterIndex(m / 2, n / 2);
            _centerPoint = _raster.GetSquareCenter(_centerIndex);

            _setElevationMethods = new Dictionary <byte, SetElevationDelegate>();
            _setElevationMethods.Add((byte)ElevationType.kFlat, _FlatElevation);
            _setElevationMethods.Add((byte)ElevationType.kRise, _LandRiseElevation);

            _setIsIslandMethods = new Dictionary <byte, SetIsIslandDelegate>();
            _setIsIslandMethods.Add((byte)IslandType.kCircle, _IsInsideCircleIsland);
            _setIsIslandMethods.Add((byte)IslandType.kPerlin, _IsInsidePerlinIsland);

            float maxHeight = 0;

            if (islandType == IslandType.kCircle)
            {
                _noise1D = new PerlinNoise1D(ampl: 100, count: 8, freq: 10);
                _SetCoastPoint();
                maxHeight = _setElevationMethods[(byte)elevationType]();
                _SetHeight(terrain.terrainData, maxHeight);
            }
            else if (islandType == IslandType.kPerlin)
            {
                _noise2D = new PerlinNoise2D((uint)mapSize.x, (uint)mapSize.y);
                _SetCoastPoint();
                maxHeight = _setElevationMethods[(byte)elevationType]();
                _SetHeight(terrain.terrainData, maxHeight);
            }

            //Test();
        }
Esempio n. 4
0
 public Vector2 GetSquareCenter(RasterIndex index)
 {
     return(SquareCenters[index.x, index.y]);
 }
Esempio n. 5
0
 public Vector2[] GetSquareCorner(RasterIndex index)
 {
     return(GetSquareCorner(index.x, index.y));
 }