예제 #1
0
        void InitRandom()
        {
            var rand = new SimpleRNG(Seed);

            _randFirstAddX  = (rand.value - 0.5f) * 1000f;
            _randFirstAddY  = (rand.value - 0.5f) * 10000;
            _randSecondAddX = (rand.value - 0.5f) * 1000f;
            _randSecondAddY = (rand.value - 0.5f) * 1000f;
        }
예제 #2
0
        private CollMapPoint GetCollMapPoint(int x, int y, BlockSetProfile.BlockType?colliding = null)
        {
            CollMapPoint cachedPoint;

            if (_collMapPoints.TryGetValue(new Point2(x, y), out cachedPoint) &&
                (colliding == null || colliding.Value == cachedPoint.BlockType))
            {
                return(cachedPoint);
            }

            var noise = GetNoise(x, y);

            var matchingBlockInfos = BlockSet.BlockInfos.FindAll(b =>
                                                                 b.MinNoise <= noise && b.MaxNoise >= noise &&
                                                                 (colliding == null || colliding.Value == b.BlockType));

            if (matchingBlockInfos.Count == 0 && colliding != null)
            {
                matchingBlockInfos = BlockSet.BlockInfos
                                     .FindAll(b => colliding.Value == b.BlockType);
            }

            if (matchingBlockInfos.Count == 0)
            {
                Debug.LogError("No matching blocks found");
                return(default(CollMapPoint));
            }

            var rand      = new SimpleRNG(Util.Hash(Seed, x, y));
            var blockInfo = matchingBlockInfos
                            .RandomElement(bi => bi.Weight, rand);

            var point = new CollMapPoint(noise)
            {
                BlockInfo = blockInfo, BlockType = blockInfo.BlockType
            };

            _collMapPoints[new Point2(x, y)] = point;
            return(point);
        }
예제 #3
0
        private void CreatePoint(int x, int y, BlockSetProfile.BlockInfo blockInfo, int compactInfo,
                                 bool noLightEffects, SimpleRNG rand, BlockSetProfile.BlockType?isColliding = null)
        {
            var sprite = blockInfo.SpriteInfo
                         .RandomElement(ti => 1, rand);

            //if (tilingInfo == null)
            //{
            //    Debug.LogError("Tiling info not found");
            //    return;
            //}

            //var sprite = tilingInfo.Sprite;

            if (sprite == null)
            {
                Debug.LogError("Tiling info is broken");
                return;
            }

            CreatePoint(x, y, sprite, blockInfo, isColliding == null ? blockInfo.BlockType : isColliding.Value,
                        noLightEffects);
        }
예제 #4
0
        private GameObject GenerateBlocksJoined(int xOffest, int yOffest)
        {
            var rand = new SimpleRNG(Util.Hash(Seed, xOffest, yOffest));

            _vertices.Clear();
            _uvs.Clear();
            _triangles.Clear();
            _lightAbsorptionColors.Clear();
            _lightEmissionColors.Clear();

            var meshObj = (GameObject)Instantiate(MeshObjectPrefab);

            meshObj.name = "Block Mesh { X = " + xOffest / ChunkSize + "; Y = " + yOffest / ChunkSize + " }";
            var meshObjTransform = meshObj.transform;

            meshObjTransform.position = meshObjTransform.position.WithXY(xOffest, yOffest);
            meshObjTransform.parent   = Container;

            var collMap = new CollMapPoint[ChunkSize, ChunkSize];

            for (int x = 0; x < ChunkSize; x++)
            {
                for (int y = 0; y < ChunkSize; y++)
                {
                    collMap[x, y] = GetCollMapPoint(x + xOffest, y + yOffest);
                }
            }

            for (int x = 0; x < ChunkSize; x++)
            {
                for (int y = 0; y < ChunkSize; y++)
                {
                    var blockInfo = collMap[x, y].BlockInfo;

                    if (blockInfo.AditionalObjectPrefab != null && blockInfo.AditionalObjectProbability >= rand.value)
                    {
                        var addObj = (GameObject)Instantiate(blockInfo.AditionalObjectPrefab);

                        addObj.transform.parent        = meshObjTransform;
                        addObj.transform.localPosition = blockInfo.AditionalObjectPrefab
                                                         .transform.position.WithXY(x + 0.5f, y + 0.5f);
                    }

                    if (blockInfo.SpriteInfo.Length == 0)
                    {
                        Debug.LogError("Sprite Info is broken");
                        continue;
                    }

                    var compactInfo =
                        (SafeIndex(collMap, x, y + 1, ChunkSize, ChunkSize,
                                   () => GetCollMapPoint(x + xOffest, y + yOffest))
                         .BlockType == BlockSetProfile.BlockType.CollidingWall
                            ? 1
                            : 0) +
                        (SafeIndex(collMap, x + 1, y, ChunkSize, ChunkSize,
                                   () => GetCollMapPoint(x + xOffest, y + yOffest))
                         .BlockType == BlockSetProfile.BlockType.CollidingWall
                            ? 2
                            : 0) +
                        (SafeIndex(collMap, x, y - 1, ChunkSize, ChunkSize,
                                   () => GetCollMapPoint(x + xOffest, y + yOffest))
                         .BlockType == BlockSetProfile.BlockType.CollidingWall
                            ? 4
                            : 0) +
                        (SafeIndex(collMap, x - 1, y, ChunkSize, ChunkSize,
                                   () => GetCollMapPoint(x + xOffest, y + yOffest))
                         .BlockType == BlockSetProfile.BlockType.CollidingWall
                            ? 8
                            : 0);

                    CreatePoint(x, y, blockInfo, compactInfo, false, rand);
                }
            }

            var blockMesh = new Mesh();

            blockMesh.vertices  = _vertices.ToArray();
            blockMesh.uv        = _uvs.ToArray();
            blockMesh.triangles = _triangles.ToArray();
            blockMesh.RecalculateBounds();
            ;

            var meshFilter = meshObj.GetComponent <MeshFilter>();

            meshFilter.mesh = blockMesh;

            var meshRenderer = meshObj.GetComponent <MeshRenderer>();
            var texture      = BlockSet.BlockInfos
                               .First(bi => bi.SpriteInfo.Any(si => si != null))
                               .SpriteInfo.First(ti => ti != null)
                               .texture;
            var mpb = new MaterialPropertyBlock();

            mpb.SetTexture("_MainTex", texture);
            meshRenderer.SetPropertyBlock(mpb);

            for (int x = 0; x < ChunkSize; x++)
            {
                var yStart = 0;
                for (int y = 0; y < ChunkSize; y++)
                {
                    if (collMap[x, y].BlockInfo.BlockType != BlockSetProfile.BlockType.CollidingWall)
                    {
                        if (y - yStart > 0)
                        {
                            var obj = new GameObject();
                            obj.layer                   = meshObj.layer;
                            obj.transform.parent        = meshObjTransform;
                            obj.transform.localPosition = new Vector3(x, 0);
                            obj.name = "Collider x = " + x;
                            var coll = obj.AddComponent <BoxCollider2D>();
                            coll.size   = new Vector2(1, (y - yStart));
                            coll.offset = new Vector2(0.5f, yStart + coll.size.y / 2f);
                        }
                        yStart = y + 1;
                    }
                }
                if (ChunkSize - yStart > 0)
                {
                    var obj = new GameObject();
                    obj.layer                   = meshObj.layer;
                    obj.transform.parent        = meshObjTransform;
                    obj.transform.localPosition = new Vector3(x, 0);
                    obj.name = "Collider x = " + x;
                    var coll = obj.AddComponent <BoxCollider2D>();
                    coll.size   = new Vector2(1, (ChunkSize - yStart));
                    coll.offset = new Vector2(0.5f, yStart + coll.size.y / 2f);
                }
            }

            var lightObstaclesObject = (GameObject)Instantiate(LightObstaclesPrefab);

            lightObstaclesObject.transform.parent        = meshObjTransform;
            lightObstaclesObject.transform.localPosition = Vector3.zero;
            //lightObstaclesObject.transform.localPosition += new Vector3(0, 0, -10);
            var lightObstaclesMeshFilter = lightObstaclesObject.GetComponent <MeshFilter>();

            lightObstaclesMeshFilter.mesh = ChunkMeshFromColors(_lightAbsorptionColors);

            var ambientLightObject = (GameObject)Instantiate(AmbientLightPrefab);

            ambientLightObject.transform.parent        = meshObjTransform;
            ambientLightObject.transform.localPosition = Vector3.zero;
            //ambientLightObject.transform.localPosition += new Vector3(0, 0, -5);
            var ambientLightMeshFilter = ambientLightObject.GetComponent <MeshFilter>();

            ambientLightMeshFilter.mesh = ChunkMeshFromColors(_lightEmissionColors);

            return(meshObj);
        }
예제 #5
0
        public static T RandomElement <T>(this IEnumerable <T> enumerable, Func <T, int> weightFunc, SimpleRNG rand)
        {
            int totalWeight = 0;          // this stores sum of weights of all elements before current
            T   selected    = default(T); // currently selected element

            foreach (var data in enumerable)
            {
                int weight = weightFunc(data);                    // weight of current element
                int r      = rand.Range(0, totalWeight + weight); // random value
                if (r >= totalWeight)                             // probability of this is weight/(totalWeight+weight)
                {
                    selected = data;
                }
                // it is the probability of discarding last selected element and selecting current one instead
                totalWeight += weight; // increase weight sum
            }

            return(selected); // when iterations end, selected is some element of sequence.
        }