Beispiel #1
0
 public static void GetState(ref KeyboardState state)
 {
     Allegro5.al_get_keyboard_state(ref state);
 }
Beispiel #2
0
 public static void AllegroMain()
 {
     Allegro.InstallSystem();
     Keyboard.Install();
     Image.Init();
     Font.Init();
     Ttf.Init();
     var font = Ttf.LoadFont("Arial.ttf", 12, TtfFlags.None);
     var black = new Color(0, 0, 0);
     var gray = new Color(0.5f, 0.5f, 0.5f);
     var yellow = new Color(1, 1, 0);
     var red = new Color(1, 0, 0);
     var random = new Random();
     var visualization = true;
     var keyboardState = new KeyboardState();
     using (var display = Display.Create(800, 600))
     {
         var bitmap = Image.LoadBitmap("map.png");
         Blender.Set(BlendOperation.Add, BlendMode.Alpha, BlendMode.InverseAlpha, new Color(1, 1, 1));
         Display.Clear(black);
         bitmap.Draw(0, 0, DrawFlags.None);
         font.Draw(Display.Width / 2, Display.Height - 50, FontDrawFlags.AlignCentre, "Do you want visualization? (Y/N)");
         Display.Flip();
         keyboardState = new KeyboardState();
         while (!(keyboardState.KeyDown(Key.Y) || keyboardState.KeyDown(Key.N)))
         {
             Keyboard.GetState(ref keyboardState);
         }
         visualization = keyboardState.KeyDown(Key.Y);
         var map = PathFinder.MakeMap(bitmap);
         var height = map.GetLength(0);
         var width = map.GetLength(1);
         var zones = new List<Rectangle>();
         while (true)
         {
             Rectangle? biggestRectangle = null;
             for (var startY = 0; startY < height; startY++)
             {
                 for (var startX = 0; startX < width; startX++)
                 {
                     var startNode = map[startY, startX];
                     if (startNode.InGroup)
                     {
                         continue;
                     }
                     var value = startNode.Value;
                     var endX = startX;
                     for (; endX < width; endX++)
                     {
                         var node = map[startY, endX];
                         if (node.InGroup || value != node.Value)
                         {
                             break;
                         }
                     }
                     if (biggestRectangle.HasValue)
                     {
                         var necessaryHeight = (int)(biggestRectangle.Value.GetArea() / ((float)endX - startX));
                         var jumpY = startY + necessaryHeight;
                         if (jumpY >= height || map[jumpY, startX].InGroup || value != map[jumpY, startX].Value)
                         {
                             continue;
                         }
                     }
                     var endY = startY;
                     for (; endY < height; endY++)
                     {
                         for (var x = startX; x < endX; x++)
                         {
                             var node = map[endY, x];
                             if (node.InGroup || value != node.Value)
                             {
                                 goto foundY;
                             }
                         }
                     }
                 foundY:
                         if (visualization)
                     {
                         Keyboard.GetState(ref keyboardState);
                         if (keyboardState.KeyDown(Key.Escape))
                         {
                             return;
                         }
                         Display.Clear(black);
                         bitmap.Draw(0, 0, DrawFlags.None);
                         foreach (var zone in zones)
                         {
                             Primitives.DrawFilledRectangle(zone.X1, zone.Y1, zone.X2, zone.Y2, gray);
                         }
                         if (biggestRectangle.HasValue)
                         {
                             Primitives.DrawFilledRectangle(biggestRectangle.Value.X1,
                                                            biggestRectangle.Value.Y1,
                                                            biggestRectangle.Value.X2,
                                                            biggestRectangle.Value.Y2,
                                                            yellow);
                         }
                         Primitives.DrawFilledRectangle(startX, startY, endX, endY, red);
                         Display.Flip();
                     }
                     var rectangle = new Rectangle(startX, startY, endX, endY);
                     if (!biggestRectangle.HasValue || rectangle.GetArea() > biggestRectangle.Value.GetArea())
                     {
                         biggestRectangle = rectangle;
                     }
                 }
             }
             if (!biggestRectangle.HasValue)
             {
                 break;
             }
             for (var y = biggestRectangle.Value.Y1; y < biggestRectangle.Value.Y2; y++)
             {
                 for (var x = biggestRectangle.Value.X1; x < biggestRectangle.Value.X2; x++)
                 {
                     map[y, x].InGroup = true;
                 }
             }
             zones.Add(biggestRectangle.Value);
         }
         Display.Clear(black);
         bitmap.Draw(0, 0, DrawFlags.None);
         foreach (var zone in zones)
         {
             var color = new Color((float)random.NextDouble(), (float)random.NextDouble(), (float)random.NextDouble());
             Primitives.DrawFilledRectangle(zone.X1, zone.Y1, zone.X2, zone.Y2, color);
         }
         font.Draw(Display.Width / 2, Display.Height - 50, FontDrawFlags.AlignCentre, zones.Count.ToString());
         Display.Flip();
         keyboardState = new KeyboardState();
         while (!(keyboardState.KeyDown(Key.Escape) || keyboardState.KeyDown(Key.Enter)))
         {
             Keyboard.GetState(ref keyboardState);
         }
         if (keyboardState.KeyDown(Key.Escape))
         {
             return;
         }
         var pathNodes = new List<PathNode>();
         foreach (var zone in zones)
         {
             var nodes = new PathNode[]
             {
                 new PathNode(zone.X1, zone.Y1),
                 new PathNode(zone.X1, zone.Y2),
                 new PathNode(zone.X2, zone.Y1),
                 new PathNode(zone.X2, zone.Y2)
             };
             nodes[0].Neighbors.AddRange(new PathNode[] { nodes[1], nodes[2], nodes[3] });
             nodes[1].Neighbors.AddRange(new PathNode[] { nodes[0], nodes[2], nodes[3] });
             nodes[2].Neighbors.AddRange(new PathNode[] { nodes[0], nodes[1], nodes[3] });
             nodes[3].Neighbors.AddRange(new PathNode[] { nodes[0], nodes[1], nodes[2] });
             pathNodes.AddRange(nodes);
         }
         var foundDuplicates = true;
         while (foundDuplicates)
         {
             foundDuplicates = false;
             for (var i = 0; i < pathNodes.Count; i++)
             {
                 var node1 = pathNodes[i];
                 for (var j = 0; j < pathNodes.Count;)
                 {
                     var node2 = pathNodes[j];
                     if (!object.ReferenceEquals(node1, node2) && node1.X == node2.X && node1.Y == node2.Y)
                     {
                         node1.Neighbors.AddRange(node2.Neighbors);
                         foreach (var neighbor in node2.Neighbors)
                         {
                             for (var k = 0; k < neighbor.Neighbors.Count; k++)
                             {
                                 if (object.ReferenceEquals(neighbor.Neighbors[k], node2))
                                 {
                                     neighbor.Neighbors[k] = node1;
                                 }
                             }
                         }
                         pathNodes.RemoveAt(j);
                         foundDuplicates = true;
                     }
                     else
                     {
                         j++;
                     }
                 }
             }
         }
         Display.Clear(black);
         bitmap.Draw(0, 0, DrawFlags.None);
         foreach (var node in pathNodes)
         {
             foreach (var neighbor in node.Neighbors)
             {
                 Primitives.DrawLine(node.X, node.Y, neighbor.X, neighbor.Y, red, 0);
             }
         }
         font.Draw(Display.Width / 2, Display.Height - 50, FontDrawFlags.AlignCentre, pathNodes.Count.ToString());
         Display.Flip();
         keyboardState = new KeyboardState();
         while (!keyboardState.KeyDown(Key.Escape))
         {
             Keyboard.GetState(ref keyboardState);
         }
     }
 }