root/Code/oMaE/oMaE/Screens/Map.cs @ 119

Revision 119, 21.5 KB (checked in by acarter, 2 years ago)

Committed in semi-stable state

Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using Microsoft.Xna.Framework;
6using Microsoft.Xna.Framework.Audio;
7using Microsoft.Xna.Framework.Content;
8using Microsoft.Xna.Framework.GamerServices;
9using Microsoft.Xna.Framework.Graphics;
10using Microsoft.Xna.Framework.Input;
11using Microsoft.Xna.Framework.Media;
12using oMaE.Overworld.Objects;
13
14namespace oMaE.Overworld
15{
16    /// <summary>
17    /// The map of the game.
18    /// </summary>
19    public class Map : GameObject
20    {
21        private string[] map;
22        private int[][] minimap;
23        /// <summary>
24        /// The entrance of the warehouse.
25        /// </summary>
26        public Door Entrance;
27        /// <summary>
28        /// Starting location on minimap.
29        /// </summary>
30        public Point mStart;
31        public int NumDoors = 0;
32        private Vector2 start = Vector2.Zero;
33        /// <summary>
34        /// All the wall in the compound.
35        /// </summary>
36        public LinkedList<Wall> Walls { get { return GenerateWalls(); } }
37        /// <summary>
38        /// All the doors in the compound.
39        /// </summary>
40        public LinkedList<Door> Doors { get { return GenerateDoors(); } }
41        /// <summary>
42        /// All the crates in the compound.
43        /// </summary>
44        public LinkedList<Crate> Crates { get { return GenerateCrates(); } }
45        /// <summary>
46        /// Makes a new map.
47        /// </summary>
48        /// <param name="num">The map number.</param>
49        public Map(int num)
50        {
51            Visible = false;
52        }
53        /// <summary>
54        /// Initializes the minimap.
55        /// </summary>
56        private void init()
57        {
58            minimap = new int[3 * map.Length + 2][];
59            for (int i = 0; i < minimap.Length; ++i)
60            {
61                minimap[i] = new int[3 * map[0].Length + 2];
62                for (int j = 0; j < minimap[i].Length; ++j)
63                    minimap[i][j] = 0;
64            }
65            for (int i = 0; i < map.Length; ++i)
66            {
67                for (int j = 0; j < map[i].Length; ++j)
68                {
69                    switch (map[i][j])
70                    {
71                        case '+':
72                            minimap[3 * i + 2][3 * j + 1] = -1;
73                            minimap[3 * i + 1][3 * j + 2] = -1;
74                            minimap[3 * i + 2][3 * j + 2] = -1;
75                            minimap[3 * i + 3][3 * j + 2] = -1;
76                            minimap[3 * i + 2][3 * j + 3] = -1;
77                            break;
78                        case '|':
79                            minimap[3 * i + 1][3 * j + 2] = -1;
80                            minimap[3 * i + 2][3 * j + 2] = -1;
81                            minimap[3 * i + 3][3 * j + 2] = -1;
82                            break;
83                        case '-':
84                            minimap[3 * i + 2][3 * j + 1] = -1;
85                            minimap[3 * i + 2][3 * j + 2] = -1;
86                            minimap[3 * i + 2][3 * j + 3] = -1;
87                            break;
88                        case 'I':
89                            minimap[3 * i + 2][3 * j + 1] = -2;
90                            minimap[3 * i + 2][3 * j + 2] = -2;
91                            minimap[3 * i + 2][3 * j + 3] = -2;
92                            NumDoors++;
93                            break;
94                        case 'E':
95                            minimap[3 * i + 2][3 * j + 1] = -4;
96                            minimap[3 * i + 2][3 * j + 2] = -4;
97                            minimap[3 * i + 2][3 * j + 3] = -4;
98                            NumDoors++;
99                            break;
100                        case 'd':
101                            minimap[3 * i + 1][3 * j + 2] = -2;
102                            minimap[3 * i + 2][3 * j + 2] = -2;
103                            minimap[3 * i + 3][3 * j + 2] = -2;
104                            NumDoors++;
105                            break;
106                        case 'r':
107                            minimap[3 * i + 2][3 * j + 2] = -1;
108                            minimap[3 * i + 3][3 * j + 2] = -1;
109                            minimap[3 * i + 2][3 * j + 3] = -1;
110                            break;
111                        case 'J':
112                            minimap[3 * i + 2][3 * j + 2] = -1;
113                            minimap[3 * i + 2][3 * j + 1] = -1;
114                            minimap[3 * i + 3][3 * j + 2] = -1;
115                            break;
116                        case '/':
117                            minimap[3 * i + 2][3 * j + 2] = -1;
118                            minimap[3 * i + 2][3 * j + 1] = -1;
119                            minimap[3 * i + 1][3 * j + 2] = -1;
120                            break;
121                        case 'L':
122                            minimap[3 * i + 2][3 * j + 2] = -1;
123                            minimap[3 * i + 1][3 * j + 2] = -1;
124                            minimap[3 * i + 2][3 * j + 3] = -1;
125                            break;
126                        case 'v':
127                            minimap[3 * i + 2][3 * j + 1] = -1;
128                            minimap[3 * i + 2][3 * j + 2] = -1;
129                            minimap[3 * i + 2][3 * j + 3] = -1;
130                            minimap[3 * i + 3][3 * j + 2] = -1;
131                            break;
132                        case 'n':
133                            minimap[3 * i + 2][3 * j + 1] = -1;
134                            minimap[3 * i + 2][3 * j + 2] = -1;
135                            minimap[3 * i + 2][3 * j + 3] = -1;
136                            minimap[3 * i + 1][3 * j + 2] = -1;
137                            break;
138                        case '<':
139                            minimap[3 * i + 1][3 * j + 2] = -1;
140                            minimap[3 * i + 2][3 * j + 2] = -1;
141                            minimap[3 * i + 3][3 * j + 2] = -1;
142                            minimap[3 * i + 2][3 * j + 1] = -1;
143                            break;
144                        case '>':
145                            minimap[3 * i + 1][3 * j + 2] = -1;
146                            minimap[3 * i + 2][3 * j + 2] = -1;
147                            minimap[3 * i + 3][3 * j + 2] = -1;
148                            minimap[3 * i + 2][3 * j + 3] = -1;
149                            break;
150                        case 'M':
151                        case '*':
152                            minimap[3 * i + 2][3 * j + 2] = 2;
153                            break;
154                        case 'Y':
155                            mStart = new Point(3 * i + 2, 3 * j + 2);
156                            start = new Vector2(j, i);
157                            break;
158
159                    }
160                }
161            }
162            floodFill(1 + 3 * (int)start.Y, 1 + 3 * (int)start.X);
163        }
164        /// <summary>
165        /// Opened a crate.
166        /// </summary>
167        /// <param name="p">The location of the crate.</param>
168        public void GetCrate(Point p)
169        {
170            minimap[p.X][p.Y] = 1;
171        }
172        private LinkedList<Crate> GenerateCrates()
173        {
174            LinkedList<Crate> crates = new LinkedList<Crate>();
175            for (int i = 0; i < map.Length; ++i)
176            {
177                for (int j = 0; j < map[i].Length; ++j)
178                {
179                    Vector2 center = 20 * (new Vector2(j, i) - start);
180                    switch (map[i][j])
181                    {
182                        case '*':
183                        case 'M':
184                            crates.AddFirst(new Crate(center, new Point(3*i + 2, 3*j+2)));
185                            break;
186                    }
187                }
188            }
189            return crates;
190        }
191        private LinkedList<Door> GenerateDoors()
192        {
193            LinkedList<Door> doors = new LinkedList<Door>();
194            for (int i = 0; i < map.Length; ++i)
195            {
196                for (int j = 0; j < map[i].Length; ++j)
197                {
198                    Vector2 top = 20 * (new Vector2(j, i) - new Vector2(0.0f, 0.5f) - start);
199                    Vector2 bottom = 20 * (new Vector2(j, i) + new Vector2(0.0f, 0.5f) - start);
200                    Vector2 left = 20 * (new Vector2(j, i) - new Vector2(0.5f, 0.0f) - start);
201                    Vector2 right = 20 * (new Vector2(j, i) + new Vector2(0.5f, 0.0f) - start);
202                    Vector2 center = 20 * (new Vector2(j, i) - start);
203                    Point mLoc = new Point(3 * i + 2, 3 * j + 2);
204                    Door partner;
205                    switch (map[i][j])
206                    {
207                        case 'E':
208                            doors.AddFirst(partner = new Door(Color.Black, Color.Black, Color.LightSlateGray, left, right, mLoc, 30, 40, ""));
209                            doors.AddFirst(new Door(Color.Black, Color.Black, Color.LightSlateGray, right, left, partner, 30, 40, ""));
210                            Entrance = partner;
211                            break;
212                        case 'I':
213                            doors.AddFirst(partner = new Door(Color.Red, Color.Green, Color.LightSlateGray, left, right, mLoc, 10, 40));
214                            doors.AddFirst(new Door(Color.Red, Color.Green, Color.LightSlateGray, right, left, partner, 10, 40));
215                            break;
216                        case 'd':
217                            doors.AddFirst(partner = new Door(Color.Red, Color.Green, Color.LightSlateGray, top, bottom, mLoc, 10, 40));
218                            doors.AddFirst(new Door(Color.Red, Color.Green, Color.LightSlateGray, bottom, top, partner, 10, 40));
219                            break;
220                    }
221                }
222            }
223            return doors;
224        }
225        private LinkedList<Wall> GenerateWalls()
226        {
227            LinkedList<Wall> walls = new LinkedList<Wall>();
228            for (int i = 0; i < map.Length; ++i)
229            {
230                for (int j = 0; j < map[i].Length; ++j)
231                {
232                    Vector2 top = 20 * (new Vector2(j, i) - new Vector2(0.0f, 0.5f) - start); 
233                    Vector2 bottom = 20 * (new Vector2(j, i) + new Vector2(0.0f, 0.5f) - start); 
234                    Vector2 left = 20 * (new Vector2(j, i) - new Vector2(0.5f, 0.0f) - start); 
235                    Vector2 right = 20 * (new Vector2(j, i) + new Vector2(0.5f, 0.0f) - start);
236                    Vector2 center = 20 * (new Vector2(j, i) - start);
237                    switch (map[i][j])
238                    {
239                        case '+':
240                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
241                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
242                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
243                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
244                            break;
245                        case '|':
246                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
247                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
248                            break;
249                        case '-':
250                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
251                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
252                            break;
253                        case 'r':
254                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, center, 40f));
255                            walls.AddFirst(new Wall(Color.LightSlateGray, center, bottom, 40f));
256                            walls.AddFirst(new Wall(Color.LightSlateGray, right, center, 40f));
257                            walls.AddFirst(new Wall(Color.LightSlateGray, center, right, 40f));
258                            break;
259                        case 'J':
260                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, center, 40f));
261                            walls.AddFirst(new Wall(Color.LightSlateGray, center, bottom, 40f));
262                            walls.AddFirst(new Wall(Color.LightSlateGray, left, center, 40f));
263                            walls.AddFirst(new Wall(Color.LightSlateGray, center, left, 40f));
264                            break;
265                        case '/':
266                            walls.AddFirst(new Wall(Color.LightSlateGray, left, center, 40f));
267                            walls.AddFirst(new Wall(Color.LightSlateGray, center, left, 40f));
268                            walls.AddFirst(new Wall(Color.LightSlateGray, top, center, 40f));
269                            walls.AddFirst(new Wall(Color.LightSlateGray, center, top, 40f));
270                            break;
271                        case 'L':
272                            walls.AddFirst(new Wall(Color.LightSlateGray, right, center, 40f));
273                            walls.AddFirst(new Wall(Color.LightSlateGray, center, right, 40f));
274                            walls.AddFirst(new Wall(Color.LightSlateGray, top, center, 40f));
275                            walls.AddFirst(new Wall(Color.LightSlateGray, center, top, 40f));
276                            break;
277                        case 'v':
278                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
279                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
280                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, center, 40f));
281                            walls.AddFirst(new Wall(Color.LightSlateGray, center, bottom, 40f));
282                            break;
283                        case 'n':
284                            walls.AddFirst(new Wall(Color.LightSlateGray, left, right, 40f));
285                            walls.AddFirst(new Wall(Color.LightSlateGray, right, left, 40f));
286                            walls.AddFirst(new Wall(Color.LightSlateGray, top, center, 40f));
287                            walls.AddFirst(new Wall(Color.LightSlateGray, center, top, 40f));
288                            break;
289                        case '>':
290                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
291                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
292                            walls.AddFirst(new Wall(Color.LightSlateGray, right, center, 40f));
293                            walls.AddFirst(new Wall(Color.LightSlateGray, center, right, 40f));
294                            break;
295                        case '<':
296                            walls.AddFirst(new Wall(Color.LightSlateGray, top, bottom, 40f));
297                            walls.AddFirst(new Wall(Color.LightSlateGray, bottom, top, 40f));
298                            walls.AddFirst(new Wall(Color.LightSlateGray, left, center, 40f));
299                            walls.AddFirst(new Wall(Color.LightSlateGray, center, left, 40f));
300                            break;
301                    }
302                }
303            }
304            return walls;
305        }
306        private void floodFill(int x, int y)
307        {
308            // FIXME
309            try
310            {
311                if (minimap[x][y] == 0)
312                {
313                    minimap[x][y] = 1;
314                    floodFill(x, y + 1);
315                    floodFill(x + 1, y);
316                    floodFill(x, y - 1);
317                    floodFill(x - 1, y);
318                }
319            }
320            catch (IndexOutOfRangeException)
321            {
322            }
323        }
324        private void floodFillOpen(int x, int y)
325        {
326            try
327            {
328                if (minimap[x][y] == -2)
329                {
330                    minimap[x][y] = -3;
331                    floodFillOpen(x, y + 1);
332                    floodFillOpen(x + 1, y);
333                    floodFillOpen(x, y - 1);
334                    floodFillOpen(x - 1, y);
335                }
336                else
337                {
338                    floodFill(x, y);
339                }
340            }
341            catch (IndexOutOfRangeException)
342            {
343            }
344        }
345        /// <summary>
346        /// Loads content.
347        /// </summary>
348        /// <param name="Content">The content manager.</param>
349        public override void LoadContent(ContentManager Content)
350        {
351            string[][] test = Content.Load<string[][]>("AppData/Maps");
352            map = test[0];
353            base.LoadContent(Content);
354        }
355        public void Reset()
356        {
357            init();
358        }
359        /// <summary>
360        /// Updates on the map
361        /// </summary>
362        /// <param name="gamestate">The current gamestate</param>
363        public override void Update(GameState gamestate)
364        {
365            if (gamestate.Pressed(MouseButton.LEFT))
366            {
367                gamestate.Handle(MouseButton.LEFT);
368                driver.CloseMap();
369            }
370            base.Update();
371        }
372        /// <summary>
373        /// Enter a new room.
374        /// </summary>
375        /// <param name="pos">Location of opening door.</param>
376        public void EnterRoom(Point pos)
377        {
378            // Console.WriteLine(pos);
379            floodFillOpen(pos.X, pos.Y);
380        }
381        /// <summary>
382        /// Draws the minimap to the screen.
383        /// </summary>
384        /// <param name="screen">The screen to be drawn on.</param>
385        public override void Draw(Screen2D screen)
386        {
387            screen.FillRectangle(new Rectangle(0, 0, 1000, 500), new Color(0, 0, 255, 127));
388            int majorSize = 200 / map.Length, minorSize = 75 / map.Length;
389            int xcoord, dxcoord, ycoord = 50, dycoord;
390            for (int i = 1; i < minimap.Length - 1; ++i)
391            {
392                xcoord = (1000 - map[(i - 1) / 3].Length * (2 * majorSize + minorSize)) / 2;
393                dycoord = (i % 3 == 2 ? minorSize : majorSize);
394                for (int j = 1; j < minimap[i].Length - 1; ++j)
395                {
396                    dxcoord = (j % 3 == 2 ? minorSize : majorSize);
397                    Color c;
398                    switch (minimap[i][j])
399                    {
400                        case -1:
401                            c = Color.Black;
402                            break;
403                        case -2:
404                            c = Color.Red;
405                            break;
406                        case -3:
407                            c = Color.Green;
408                            break;
409                        case -4:
410                            c = Color.Maroon;
411                            break;
412                        case 2:
413                            c = Color.Yellow;
414                            break;
415                        case 1:
416                            c = Color.Blue;
417                            break;
418                        default:
419                            c = Color.Gray;
420                            break;
421                    }
422                    screen.FillRectangle(new Rectangle(xcoord, ycoord, dxcoord, dycoord), c);
423                    xcoord += dxcoord;
424                }
425                ycoord += dycoord;
426            }
427            Vector2 loc = ((driver.World3D.CameraPosition2D * (1 / 20.0f)) + start) * (2 * majorSize + minorSize) + new Vector2((1000 - map[0].Length * (2 * majorSize + minorSize)) / 2, 50);
428            screen.FillRectangle(new Rectangle((int)loc.X + 5, (int)loc.Y + 5, 10, 10), Color.White);
429            screen.DrawText("Click anywhere to close", new Vector2(500, 10), TextHorizontal.CENTERED, TextVertical.TOP, Color.White);
430            // FIXME
431            screen.FillRectangle(new Rectangle(830, 50, 150, 400), Color.MediumPurple);
432            screen.DrawText("Key", new Vector2(905, 60), FontSize.LARGE, TextHorizontal.CENTERED, TextVertical.TOP, Color.White);
433            screen.FillRectangle(new Rectangle(850, 120, 20, 20), Color.Black);
434            screen.DrawText("Wall", new Vector2(900, 130), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
435            screen.FillRectangle(new Rectangle(850, 160, 20, 20), Color.Blue);
436            screen.DrawText("Visited", new Vector2(900, 170), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
437            screen.FillRectangle(new Rectangle(850, 200, 20, 20), Color.Gray);
438            screen.DrawText("Unvisited", new Vector2(900, 210), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
439            screen.FillRectangle(new Rectangle(850, 240, 20, 20), Color.Maroon);
440            screen.DrawText("Entrance", new Vector2(900, 250), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
441            screen.FillRectangle(new Rectangle(850, 280, 20, 20), Color.Red);
442            screen.DrawText("Locked", new Vector2(900, 290), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
443            screen.FillRectangle(new Rectangle(850, 320, 20, 20), Color.Green);
444            screen.DrawText("Unlocked", new Vector2(900, 330), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
445            screen.FillRectangle(new Rectangle(850, 360, 20, 20), Color.Yellow);
446            screen.DrawText("Part", new Vector2(900, 370), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
447            screen.FillRectangle(new Rectangle(850, 400, 20, 20), Color.White);
448            screen.DrawText("You", new Vector2(900, 410), TextHorizontal.LEFT, TextVertical.CENTERED, Color.White);
449            base.Draw(screen);
450        }
451    }
452}
Note: See TracBrowser for help on using the browser.