Now, we have reached a point where it might be useful to place the data that we have on the form into a text file, so that we can restore this data and we can make lots of different files to create 'levels'. The file specifications can include a list of rectangle properties (Left, Top, Width and Height or Right and Bottom) for the Platform, Wall, and Coin. The coin has a fixed width and height though, so we only need to have Left and Top for coins. So, let's make the specification: The first integer in the file will be the number of platforms, and following this integer will be the Left, Top, Right, and Bottom of each rectangle in the level. After these rectangle properties, the next integer will be the number of walls, followed by its respective rectangle properties (LTRB). The next integer is the number of coins, and it will be followed by Left and Top values only. OK. First, let's save what we have there. Of course, we would not want this in the final product so first, we need to set up some Conditional Compilation definitions. Of course, #define statements go at the top of the file.
#define TESTversion // Remove this line to stop the code from compiling the test version. |
#if TESTversion else if (e.KeyCode == Keys.S && e.Control) { savelevel(); } #endif |
private void savelevel() { System.IO.FileStream fs = new System.IO.FileStream(Application.StartupPath & @"\data.lvl", System.IO.FileMode.Create); System.IO.BinaryWriter bw = new System.IO.BinaryWriter(fs); bw.Write(platforms.Count); // Write number of platforms to file. foreach (Rectangle platform in platforms) { bw.Write(platform.Left); bw.Write(platform.Top); bw.Write(platform.Right); bw.Write(platform.Bottom); // Write LTRB to the binary file. } bw.Write(walls.Count); // Write number of walls to file. foreach (Rectangle wall in walls) { bw.Write(wall.Left); bw.Write(wall.Top); bw.Write(wall.Right); bw.Write(wall.Bottom); // Write each wall's LTRB to binary file. } bw.Write(coins.Count); // Number of coins. foreach( Rectangle coin in coins) { bw.Write(coin.Left); bw.Write(coin.Top); } // Done writing. Close the filestreams. bw.Close(); fs.Close(); } |
walls = new ArrayList(100); // The list of walls is set up. walls.Add(Rectangle.FromLTRB(225, 415, 275, 465)); walls.Add(Rectangle.FromLTRB(320, 480, 350, thelandheight)); walls.Add(Rectangle.FromLTRB(350, 520, 380, thelandheight)); // And three walls are added. |
platforms = new ArrayList(100); // Initialize the arraylist to hold up to 100 elements. platforms.Add(Rectangle.FromLTRB(50, 415, 200, thelandheight)); platforms.Add(Rectangle.FromLTRB(100, 465, 225, thelandheight)); platforms.Add(Rectangle.FromLTRB(150, 515, 250, PFMain.thelandheight)); // Instantiate the platforms for the level. coins = new ArrayList(100); coins.Add(new Rectangle(200, 530, thecoinsize, thecoinsize)); coins.Add(new Rectangle(100, 440, thecoinsize, thecoinsize)); coins.Add(new Rectangle(116, 440, thecoinsize, thecoinsize)); coins.Add(new Rectangle(132, 440, thecoinsize, thecoinsize)); coins.Add(new Rectangle(260, 355, thecoinsize, thecoinsize)); coins.Add(new Rectangle(230, 365, thecoinsize, thecoinsize)); coins.Add(new Rectangle(240, 510, thecoinsize, thecoinsize)); coins.Add(new Rectangle(20, 490, thecoinsize, thecoinsize)); coins.Add(new Rectangle(280, 400, thecoinsize, thecoinsize)); coins.Add(new Rectangle(200, 498, thecoinsize, thecoinsize)); // Ten coins going into the coins arraylist. |
loadlevel(); // Load the level information from the file. |
private void loadlevel() { System.IO.FileStream fs = new System.IO.FileStream(Application.StartupPath + @"\data.lvl", System.IO.FileMode.Open); System.IO.BinaryReader br = new System.IO.BinaryReader(fs); int lv; platforms = new ArrayList(br.ReadInt32()); // First is the number of platforms which will be set as the capacity of the platforms arraylist. for (lv = 0; lv < platforms.Capacity; lv++) { platforms.Add(Rectangle.FromLTRB(br.ReadInt32(), br.ReadInt32(), br.ReadInt32(), br.ReadInt32())); // The LTRB is read from the file. } walls = new ArrayList(br.ReadInt32()); // The number of walls precedes the wall data. for (lv = 0; lv < walls.Capacity; lv++) { walls.Add(Rectangle.FromLTRB(br.ReadInt32(), br.ReadInt32(), br.ReadInt32(), br.ReadInt32())); // LTRB read from file again. } coins = new ArrayList(br.ReadInt32()); // Number of coins. for (lv = 0; lv < coins.Capacity; lv++) { coins.Add(new Rectangle(br.ReadInt32(), br.ReadInt32(), thecoinsize, thecoinsize)); // Create rectangle with the fixed width that all coins have. } br.Close(); fs.Close(); } |
bool ismousedown; // Indicates if the mouse button is down. Point initialpt, finalpt; // The initial and final point of the rectangle that was dragged by the user. char modobject; // P for platform, W for wall, C for coin. |
modobject = 'P'; // Start off the modobject character to be P, representing platform. |
private void PFMain_MouseDown(object sender, MouseEventArgs e) { ismousedown = true; initialpt = new Point(e.X, e.Y); // Mouse is down. Set the initial point as well. } |
private void PFMain_MouseUp(object sender, MouseEventArgs e) { Rectangle placed; finalpt = new Point(e.X, e.Y); ismousedown = false; // set the final point and indicate the mouse is no longer down. // The selection will be added to one of the arraylists we have for the level, depending on modobject's value. switch (modobject) { case 'P': placed = Rectangle.FromLTRB(Math.Min(initialpt.X, finalpt.X), Math.Min(initialpt.Y, finalpt.Y), Math.Max(initialpt.X, finalpt.X), Math.Max(initialpt.Y, finalpt.Y)); platforms.Insert(0, placed); // Add the form to the list at the beginning so that building goes upwards instead of downwards. break; case 'W': placed = Rectangle.FromLTRB(Math.Min(initialpt.X, finalpt.X), Math.Min(initialpt.Y, finalpt.Y), Math.Max(initialpt.X, finalpt.X), Math.Max(initialpt.Y, finalpt.Y)); walls.Insert(0, placed); // Add wall to wall arraylist. break; case 'C': coins.Insert(0, new Rectangle(initialpt.X, initialpt.Y, thecoinsize, thecoinsize)); break; } } |
#if TESTversion this.MouseDown += new MouseEventHandler(PFMain_MouseDown); this.MouseUp += new MouseEventHandler(PFMain_MouseUp); #endif |
else if (e.KeyCode == Keys.P) { if (!ismousedown) { modobject = 'P'; } } else if (e.KeyCode == Keys.W) { if (!ismousedown) { modobject = 'W'; } } else if (e.KeyCode == Keys.C) { if (!ismousedown) { modobject = 'C'; } } |
if (ismousedown) { Rectangle outline; Point curse = Cursor.Position; curse = this.PointToClient(curse); // Get the cursor location relative to the form instead of the screen. outline = Rectangle.FromLTRB(Math.Min(initialpt.X, curse.X), Math.Min(initialpt.Y, curse.Y), Math.Max(initialpt.X, curse.X), Math.Max(initialpt.Y, curse.Y)); // Creates the drawing rectangle. Now it has to be drawn. gfx.DrawRectangle(Pens.Black, outline); } |