Пример #1
0
        public void CopyTo()
        {
            RawList<int> list = new RawList<int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 100, 100 }, 10);
            RawList<int> listCopy = new RawList<int>(list);

            Assert.AreNotSame(list.Data, listCopy.Data);
            Assert.AreEqual(list.Count, listCopy.Count);
            CollectionAssert.AreEqual(list.Data.Take(list.Count), listCopy.Data.Take(list.Count));
            CollectionAssert.AreEqual(list, listCopy);

            RawList<int> listCopy2 = new RawList<int>();
            Assert.Throws<ArgumentNullException>(() => list.CopyTo(null, 0, 1));
            Assert.Throws<ArgumentException>(() => list.CopyTo(listCopy2, 0, 17));
            Assert.Throws<ArgumentException>(() => list.CopyTo(listCopy2, -1, 1));

            CollectionAssert.AreEqual(new int[] { }, listCopy2);
            list.CopyTo(listCopy2, 1, 2);
            CollectionAssert.AreEqual(new int[] { 0, 0, 1 }, listCopy2);
            list.CopyTo(listCopy2, 0, 10);
            CollectionAssert.AreEqual(list, listCopy2);
        }
Пример #2
0
        [Test] public void CopyTo()
        {
            RawList <int> list     = new RawList <int>(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 100, 100, 100 }, 10);
            RawList <int> listCopy = new RawList <int>(list);

            Assert.AreNotSame(list.Data, listCopy.Data);
            Assert.AreEqual(list.Count, listCopy.Count);
            CollectionAssert.AreEqual(list.Data.Take(list.Count), listCopy.Data.Take(list.Count));
            CollectionAssert.AreEqual(list, listCopy);

            RawList <int> listCopy2 = new RawList <int>();

            Assert.Throws <ArgumentNullException>(() => list.CopyTo(null, 0, 1));
            Assert.Throws <ArgumentException>(() => list.CopyTo(listCopy2, 0, 17));
            Assert.Throws <ArgumentException>(() => list.CopyTo(listCopy2, -1, 1));

            CollectionAssert.AreEqual(new int[] { }, listCopy2);
            list.CopyTo(listCopy2, 1, 2);
            CollectionAssert.AreEqual(new int[] { 0, 0, 1 }, listCopy2);
            list.CopyTo(listCopy2, 0, 10);
            CollectionAssert.AreEqual(list, listCopy2);
        }
Пример #3
0
        private static void GenerateCollisionShapes(TileEdgeMap edgeMap, Vector2 origin, Vector2 tileSize, bool roundedCorners, IList <ShapeInfo> shapeList)
        {
            // Traverse the edge map and gradually create chain / loop
            // shapes until all edges have been used.
            RawList <Point2>  currentChain = new RawList <Point2>();
            RawList <Vector2> vertexBuffer = new RawList <Vector2>();

            while (true)
            {
                // Begin a new continuous chain of nodes
                currentChain.Clear();

                // Find a starting node for our current chain.
                // If there is none, we found and handled all edges.
                Point2 start = edgeMap.FindNonEmpty();
                if (start == new Point2(-1, -1))
                {
                    break;
                }

                // Traverse the current chain node-by-node from the start we found
                Point2 current = start;
                while (true)
                {
                    // Add the current node to our continuous chain
                    currentChain.Add(current);

                    // Find the next node that connects to the current one.
                    // If there is none, our current chain is done.
                    Point2 next = edgeMap.GetClockwiseNextFrom(current);
                    if (next == new Point2(-1, -1))
                    {
                        break;
                    }

                    // Remove the edge we used to get to the next node
                    edgeMap.RemoveEdge(current, next);

                    // Use the next node as origin for traversing further
                    current = next;
                }

                // Generate a shape from the current chain
                bool isLoop = (start == currentChain[currentChain.Count - 1]);
                if (isLoop)
                {
                    currentChain.RemoveAt(currentChain.Count - 1);
                }
                vertexBuffer.Clear();

                // Rounded corners
                if (roundedCorners && currentChain.Count >= 3)
                {
                    vertexBuffer.Reserve(currentChain.Count * 2);
                    vertexBuffer.Count = 0;
                    for (int i = 0; i < currentChain.Count; i++)
                    {
                        int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count;
                        int nextIndex = (i + 1) % currentChain.Count;

                        Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i];
                        Vector2 prevVert    = origin + tileSize * (Vector2)currentChain[prevIndex];
                        Vector2 nextVert    = origin + tileSize * (Vector2)currentChain[nextIndex];

                        if (nextVert - currentVert != currentVert - prevVert)
                        {
                            if (!isLoop && (i == 0 || i == currentChain.Count - 1))
                            {
                                vertexBuffer.Add(currentVert);
                            }
                            else
                            {
                                vertexBuffer.Add(currentVert + (prevVert - currentVert).Normalized * tileSize * 0.2f);
                                vertexBuffer.Add(currentVert + (nextVert - currentVert).Normalized * tileSize * 0.2f);
                            }
                        }
                    }
                }
                // Sharp corners
                else
                {
                    vertexBuffer.Reserve(currentChain.Count);
                    vertexBuffer.Count = 0;
                    for (int i = 0; i < currentChain.Count; i++)
                    {
                        int prevIndex = (i - 1 + currentChain.Count) % currentChain.Count;
                        int nextIndex = (i + 1) % currentChain.Count;

                        Vector2 currentVert = origin + tileSize * (Vector2)currentChain[i];
                        Vector2 prevVert    = origin + tileSize * (Vector2)currentChain[prevIndex];
                        Vector2 nextVert    = origin + tileSize * (Vector2)currentChain[nextIndex];

                        if (nextVert - currentVert != currentVert - prevVert)
                        {
                            vertexBuffer.Add(currentVert);
                        }
                    }
                }

                Vector2[] vertices = new Vector2[vertexBuffer.Count];
                vertexBuffer.CopyTo(vertices, 0);
                shapeList.Add(isLoop ?
                              (ShapeInfo) new LoopShapeInfo(vertices) :
                              (ShapeInfo) new ChainShapeInfo(vertices));
            }
        }
Пример #4
0
        private static void GetTileAreaOutlines(IReadOnlyGrid<bool> tileArea, Vector2 tileSize, ref List<Vector2[]> outlines)
        {
            // Initialize the container we'll put our outlines into
            if (outlines == null)
                outlines = new List<Vector2[]>();
            else
                outlines.Clear();

            // Generate a data structure containing all visible edges
            TileEdgeMap edgeMap = new TileEdgeMap(tileArea.Width + 1, tileArea.Height + 1);
            for (int y = 0; y < edgeMap.Height; y++)
            {
                for (int x = 0; x < edgeMap.Width; x++)
                {
                    // Determine highlight state of the four tiles around this node
                    bool topLeft     = x > 0              && y > 0               && tileArea[x - 1, y - 1];
                    bool topRight    = x < tileArea.Width && y > 0               && tileArea[x    , y - 1];
                    bool bottomLeft  = x > 0              && y < tileArea.Height && tileArea[x - 1, y    ];
                    bool bottomRight = x < tileArea.Width && y < tileArea.Height && tileArea[x    , y    ];

                    // Determine which edges are visible
                    if (topLeft     != topRight   ) edgeMap.AddEdge(new Point2(x, y), new Point2(x    , y - 1));
                    if (topRight    != bottomRight) edgeMap.AddEdge(new Point2(x, y), new Point2(x + 1, y    ));
                    if (bottomRight != bottomLeft ) edgeMap.AddEdge(new Point2(x, y), new Point2(x    , y + 1));
                    if (bottomLeft  != topLeft    ) edgeMap.AddEdge(new Point2(x, y), new Point2(x - 1, y    ));
                }
            }

            // Traverse edges to form outlines until no more edges are left
            RawList<Vector2> outlineBuilder = new RawList<Vector2>();
            while (true)
            {
                // Find the beginning of an outline
                Point2 current = edgeMap.FindNonEmpty();
                if (current.X == -1 || current.Y == -1) break;

                // Traverse it until no more edges are left
                while (true)
                {
                    Point2 next = edgeMap.GetClockwiseNextFrom(current);
                    if (next.X == -1 || next.Y == -1) break;

                    outlineBuilder.Add(next * tileSize);
                    edgeMap.RemoveEdge(current, next);
                    current = next;
                }

                // Close the loop by adding the first element again
                if (outlineBuilder.Count > 0)
                    outlineBuilder.Add(outlineBuilder[0]);

                // If we have enough vertices, keep the outline for drawing
                Vector2[] outline = new Vector2[outlineBuilder.Count];
                outlineBuilder.CopyTo(outline, 0);
                outlines.Add(outline);

                // Reset the outline builder to an empty state
                outlineBuilder.Clear();
            }
        }