Пример #1
0
        public void RemoveShot(Vector3 pos)
        {
            if (shots.Count == 0)
            {
                return;
            }

            float      min     = Vector3.Distance(shots[0].Point1, pos);
            LineObject closest = shots[0];

            for (int i = 1; i < shots.Count; i++)
            {
                if (Vector3.Distance(shots[i].Point1, pos) < min)                   // Alternatively, closest line: shots[i].line.DistanceToPoint(pos) < min
                {
                    closest = shots[i];
                    min     = shots[i].DistanceToPoint(pos);
                }
            }

            foreach (LineObject wall in walls)
            {
                Vector2?intersection = wall.Intersect(closest);
                if (intersection != null)
                {
                    wall.repair();
                }
            }

            shots.Remove(closest);
            Destroy(closest.obj);
            UpdateWallDestroyed();
            UpdateRemainingShots();
        }
Пример #2
0
        void Update()
        {
            if (controller.IsLevelComplete())
            {
                // Do nothing when level is complete
                return;
            }

            if (Input.GetMouseButtonDown(0) && controller.CanAddShot())
            {
                CreateNewShot();
            }
            else if (Input.GetMouseButton(0) && controller.CanAddShot())
            {
                UpdateNewShotEndpoint();
            }
            else if (Input.GetMouseButtonUp(0) && controller.CanAddShot() && shot != null)
            {
                if (shotEnd.Equals(shotStart))
                {
                    Destroy(shot);
                }
                else
                {
                    LineObject newShot = new LineObject(shotStart, shotEnd, shot);
                    controller.AddNewShot(newShot);
                }
                shot = null;
            }
            else if (Input.GetMouseButtonDown(1))
            {
                controller.RemoveShot(Camera.main.ScreenToWorldPoint(Input.mousePosition + 10 * Vector3.forward));
            }
        }
Пример #3
0
        public void AddNewShot(LineObject shot)
        {
            shots.Add(shot);
            foreach (LineObject wall in walls)
            {
                Vector2?intersection = wall.Intersect(shot);
                if (intersection != null)
                {
                    wall.Break();
                }
            }

            if (CheckSolution())
            {
                advanceButton.SetActive(true);
            }

            UpdateWallDestroyed();
            UpdateRemainingShots();
        }
Пример #4
0
        public void GenerateNewLevel(int maxWalls)
        {
            ClearLevel();

            // Generator code
            walls = new List <LineObject>();
            List <LineObject> eventWalls = new List <LineObject>();

            int N = maxWalls;

            while (N > 0)
            {
                Vector2 position1 = new Vector3(UnityEngine.Random.Range(MIN_WIDTH, MAX_WIDTH), UnityEngine.Random.Range(MIN_HEIGHT, MAX_HEIGHT));
                Vector2 position2 = new Vector3(UnityEngine.Random.Range(MIN_WIDTH, MAX_WIDTH), UnityEngine.Random.Range(MIN_HEIGHT, MAX_HEIGHT));

                LineObject newLine = new LineObject(position1, position2);

                if (newLine.IsHorizontal == false)
                {
                    walls.Add(newLine);
                    N -= 1;
                }
            }

            // Remove all too short walls
            walls.RemoveAll(item => item.Magnitude < MIN_WALL_SIZE);

            foreach (LineObject wall in walls)
            {
                eventWalls.Add(new LineObject(new Vector2(wall.Point1.x, wall.Point1.y), new Vector2(wall.Point2.x, wall.Point2.y)));                 // deep copy
            }

            sweep = new DownwardSweepLine(walls);
            List <Intersection> intersections = sweep.Run();

            List <SweepEvent> eventPoints = new List <SweepEvent>();

            foreach (SweepEvent ev in sweep.producedEvents)
            {
                SweepEvent copy = new SweepEvent(ev.EventType);                 // deep copy
                copy.StatusItem = new StatusItem(new LineObject(ev.StatusItem.LineObject.Point1, ev.StatusItem.LineObject.Point2));
                if (ev.IntersectingStatusItem != null)
                {
                    copy.IntersectingStatusItem = new StatusItem(new LineObject(ev.IntersectingStatusItem.LineObject.Point1, ev.IntersectingStatusItem.LineObject.Point2));
                }
                eventPoints.Add(copy);
            }

            // Split intersections into multiple walls doesnt always work. If there are many walls we cant just simply split
            Dictionary <LineObject, List <Vector2> > map = new Dictionary <LineObject, List <Vector2> >();

            for (int i = 0; i < intersections.Count; i++)
            {
                if (!map.ContainsKey(intersections[i].one))
                {
                    map.Add(intersections[i].one, new List <Vector2>());
                }
                if (!map.ContainsKey(intersections[i].two))
                {
                    map.Add(intersections[i].two, new List <Vector2>());
                }
                Vector2?intersection = intersections[i].one.Intersect(intersections[i].two);
                // safety check
                if (intersection != null)
                {
                    map[intersections[i].one].Add((Vector2)intersection);
                    map[intersections[i].two].Add((Vector2)intersection);
                }
            }

            foreach (LineObject oldSeg in map.Keys)
            {
                List <Vector2> points = map[oldSeg];
                points.Add(oldSeg.Point1);
                points.Add(oldSeg.Point2);
                points.Sort((a, b) => a.x.CompareTo(b.x));
                walls.Remove(oldSeg);
                for (int i = 0; i < points.Count - 1; i++)
                {
                    walls.Add(new LineObject(points[i], points[i + 1]));
                }
            }

            // Remove all too short walls
            walls.RemoveAll(item => item.Magnitude < MIN_WALL_SIZE);


            // Add GameObject to the remaining walls
            float sizeFactor = 0.8f * (float)Math.Exp(-0.03 * ((float)walls.Count)) + 0.01f;

            foreach (LineObject line in walls)
            {
                Vector2 position1 = line.Point1;
                Vector2 position2 = line.Point2;

                GameObject newWall = Instantiate(wallPrefab, wallObjects);
                newWall.transform.Find("StartCastle").position = position1;
                newWall.transform.Find("EndCastle").position   = position2;
                newWall.GetComponent <LineRenderer>().SetPosition(0, position1);
                newWall.GetComponent <LineRenderer>().SetPosition(1, position2);

                newWall.transform.Find("StartCastle").localScale = new Vector3(sizeFactor, sizeFactor, sizeFactor);
                newWall.transform.Find("EndCastle").localScale   = new Vector3(sizeFactor, sizeFactor, sizeFactor);
                newWall.GetComponent <LineRenderer>().startWidth = 0.4f * sizeFactor;
                newWall.GetComponent <LineRenderer>().endWidth   = 0.4f * sizeFactor;

                line.obj = newWall;
            }

            // Use ShotSolver to find the budget of shots
            shotSolver = new ShotSolver(walls);

            List <Line> greedyShots = shotSolver.GreedyCover();

            maxShots = greedyShots.Count;
            updateEventsVis(eventWalls, eventPoints);
            updateSolverVis(greedyShots);
        }
Пример #5
0
 internal StatusItem(LineObject lineObject)
 {
     LineObject = lineObject;
 }
Пример #6
0
 public Intersection(LineObject one, LineObject two)
 {
     this.one = one;
     this.two = two;
 }