// Random endless level generation // Determines the amount of shepherds placed based on the current level number private ShepherdLevel CreateEndlessLevel(int level) { // create the output scriptable object var asset = ScriptableObject.CreateInstance <ShepherdLevel>(); // place the shepherds and sheep randomly List <Vector2> shepherds = RandomPos(level + 4); List <Vector2> sheep = RandomPos(2 * (level + 4)); // Print locations string sls = "Shepherd locations: \n"; foreach (Vector2 v in shepherds) { sls += "(" + v.x + ", " + v.y + "), "; } Debug.Log(sls); string shls = "Sheep locations: \n"; foreach (Vector2 v in sheep) { shls += "(" + v.x + ", " + v.y + "), "; } Debug.Log(shls); // Construct the voronoi diagram corresponding to the shepherd locations StartVoronoi(); foreach (Vector2 me in shepherds) { // Add vertex to the triangulation and update the voronoi Delaunay.AddVertex(m_delaunay, me); m_delaunay.SetOwner(me, Random.Range(0, 4)); m_dcel = Voronoi.Create(m_delaunay); } // Create vertical decomposition VerticalDecomposition vd = VertDecomp(m_dcel); // Use the vertical decomposition to determine the ownership of each sheep // and add the sheep to the level foreach (Vector2 s in sheep) { Trapezoid trap = vd.Search(s); Face area = trap.bottom.face; int i = area.owner; asset.addSheep(s, i); } // Normalize coordinates var rect = BoundingBoxComputer.FromPoints(asset.SheepList); asset.SheepList = Normalize(rect, 6f, asset.SheepList); // Set shepherd budget asset.setBudget(shepherds.Count); return(asset); }
public void DelaunayAddVertexTest() { var m_delaunay = Delaunay.Create(); Delaunay.AddVertex(m_delaunay, m_topVertex); Delaunay.AddVertex(m_delaunay, m_botVertex); Delaunay.AddVertex(m_delaunay, m_leftVertex); Delaunay.AddVertex(m_delaunay, m_farRightVertex); Delaunay.AddVertex(m_delaunay, m_rightVertex); m_delaunay.RemoveInitialTriangle(); Assert.IsTrue(Delaunay.IsValid(m_delaunay)); // check for triangles var triangles = (System.Collections.ICollection)m_delaunay.Triangles; Assert.Contains(new Triangle(m_topVertex, m_rightVertex, m_leftVertex), triangles); Assert.Contains(new Triangle(m_leftVertex, m_rightVertex, m_botVertex), triangles); Assert.Contains(new Triangle(m_topVertex, m_farRightVertex, m_rightVertex), triangles); Assert.Contains(new Triangle(m_rightVertex, m_farRightVertex, m_botVertex), triangles); }
// Handle inputs each frame void Update() { if (Input.GetKeyDown("c")) { VoronoiDrawer.CircleOn = !VoronoiDrawer.CircleOn; } if (Input.GetKeyDown("e")) { VoronoiDrawer.EdgesOn = !VoronoiDrawer.EdgesOn; } if (Input.GetKeyDown("v")) { VoronoiDrawer.VoronoiOn = !VoronoiDrawer.VoronoiOn; } // Handle mouse clicks if (Input.GetMouseButtonUp(0)) // LMB was clicked this frame { // Cast a ray, get everything it hits RaycastHit2D[] hit = Physics2D.RaycastAll(Camera.main.ScreenToWorldPoint(Input.mousePosition), Vector2.zero, Mathf.Infinity); if (hit.Length > 0) // If we hit something { // Grab the top hit GameObject GameObject lastHitObject = hit[hit.Length - 1].collider.gameObject; // If a shepherd was clicked, remove it if (lastHitObject.name == "shepherd(Clone)") { m_shepherds.Remove(lastHitObject); // remove from shepherd clone list shepherdLocs.Remove(lastHitObject.transform.position); // remove location from list Destroy(lastHitObject); // Create new Delaunay triangulation m_delaunay = Delaunay.Create(); foreach (KeyValuePair <Vector2, int> o in shepherdLocs) { Delaunay.AddVertex(m_delaunay, o.Key); m_delaunay.SetOwner(o.Key, o.Value); } // Create new Voronoi diagram m_dcel = Voronoi.Create(m_delaunay); VoronoiDrawer.setDCEL(m_dcel); // Create vertical decomposition and check solution if (shepherdLocs.Count > 0) { VerticalDecomposition vd = VertDecomp(m_dcel); Debug.LogAssertion("The current solution is " + (CheckSolution(vd) == 0 ? "correct!" : "wrong!")); VoronoiDrawer.SetVD(vd); } else { // If we do not have any shepherds, do not create vertical decomposition // Solution without shepherds is always wrong Debug.LogAssertion("The current solution is wrong!"); continueButton.SetActive(false); UpdateText(m_sheep.Count); } // Update Voronoi drawing UpdateMesh(); } } else // LMB was clicked on empty space { // Add shepherd at mouse location var mousePos = Input.mousePosition; if (!EventSystem.current.IsPointerOverGameObject() && shepherdLocs.Count < budget) { mousePos.z = 2.0f; var objectPos = Camera.main.ScreenToWorldPoint(mousePos); var obj = Instantiate(m_shepherdPrefab, objectPos, Quaternion.identity); SpriteRenderer sr = obj.GetComponent <SpriteRenderer>(); sr.color = Colors[m_activeShepherd]; // The new vertex var me = new Vector2(objectPos.x, objectPos.y); // store owner of vertex shepherdLocs.Add(me, m_activeShepherd); m_shepherds.Add(obj); // Add vertex to the triangulation Delaunay.AddVertex(m_delaunay, me); m_delaunay.SetOwner(me, m_activeShepherd); // Update Voronoi m_dcel = Voronoi.Create(m_delaunay); VoronoiDrawer.setDCEL(m_dcel); // Create vertical decomposition and check solution VerticalDecomposition vd = VertDecomp(m_dcel); CheckSolution(vd); // Update VD in drawer VoronoiDrawer.SetVD(vd); // Update Voronoi drawing UpdateMesh(); } } } }