{"id":6323,"date":"2007-04-16T14:15:00","date_gmt":"2007-04-16T14:15:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/04\/16\/using-xml-as-a-resource-in-your-code-one-more-series-on-gamewriting-matt-gertz\/"},"modified":"2024-07-05T14:48:30","modified_gmt":"2024-07-05T21:48:30","slug":"using-xml-as-a-resource-in-your-code-one-more-series-on-gamewriting-matt-gertz","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/using-xml-as-a-resource-in-your-code-one-more-series-on-gamewriting-matt-gertz\/","title":{"rendered":"Using XML as a resource in your code &#8211;one more series on gamewriting (Matt Gertz)"},"content":{"rendered":"<h2><font face=\"Cambria\" color=\"#365f91\" size=\"5\">Using XML as a resource in your code \u2013one more series on gamewriting (Matt Gertz)<\/font><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">This is actually going to be part one of a two-part blog.<span>&nbsp; <\/span>In this post, I\u2019m going to cover some basic usage of XML, as well as a few other interesting coding points such as debug-only code.<span>&nbsp; <\/span>In the second part, I\u2019ll cover the creation and handling of on-the-fly controls.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">As has probably become apparent over my posts so far, I have a certain fondness for creating small computer games, and while I promise not to make every post about writing them, nevertheless this post does cover the creation of a different type of game than I\u2019ve discussed previously.<span>&nbsp; <\/span>Some background\u2026<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The first computer that my wife and I bought together was a Macintosh Centris 650, a really nice machine for the time and quite a change from my old Commodore 128.<span>&nbsp; <\/span>Being avid gamers, we quickly discovered all sorts of fun titles, such as the SSI Gold Box games, Civilization, SimLife, and so on.<span>&nbsp; <\/span>However, there was one title that absolutely blew me away; a watershed title that proved to me that the world had changed.<span>&nbsp; <\/span>In a word:<span>&nbsp; <\/span>Myst.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Myst was an immersive game where you could walk around, look around, and interact with your environment.<span>&nbsp; <\/span>The actual navigation was actually not too dissimilar to that of the Gold Box games, but the photorealism combined with the real-time interaction with the scene was taking it to the next level.<span>&nbsp; <\/span>This weekend, while sitting and trying to think of a topic for this blog, I was wondering if I could build something like Myst from scratch using Visual Basic.<span>&nbsp; <\/span>I could (for example) create a virtual walkthrough of my new house to mail to my relatives or something.<span>&nbsp; <\/span>So, I sat down to figure out how to do it.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">The first thing I would need was a form.<span>&nbsp; <\/span>I created a new windows app and set the form size to be 800 x 600, keeping everything in the 4:3 ratio used by most monitors and digital cameras.<span>&nbsp; <\/span>The next thing I would need is a way to show the current image, and you might think that I\u2019d use a PictureBox for this.<span>&nbsp; <\/span>However, after careful thought, I realized that it would be best just to assign the image to the background of the form itself \u2013 that way, I could use transparency if I chose to overlay other items onto the form.<span>&nbsp; <\/span>(Recall from my last post that transparency is only enabled relative to the form itself!)<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">My next assumption would be that I would map the virtual area into a 3-dimensional grid, with x and y giving the coordinates for each \u201ccell\u201d on the floor, and z indicating which floor I was on.<span>&nbsp; <\/span>In each cell, I should be able to turn left or left, maybe look up or down, and maybe move forward.<span>&nbsp; <\/span>My direction would be important to know, as well as how high or low I was looking.<span>&nbsp; <\/span>I came up with this:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> Cells(maxX, maxY, maxZ) <span>As<\/span> Cell<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> currentX <span>As<\/span> <span>Integer<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> currentY <span>As<\/span> <span>Integer<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> currentZ <span>As<\/span> <span>Integer<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> currentOrientation <span>As<\/span> Orientation<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> currentAttitude <span>As<\/span> Attitude<\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Using these enums:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Enum<\/span> Attitude<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Down = 1<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Neutral = 2<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Up = 3<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Enum<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Enum<\/span> Orientation<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>TowardsLargerY = 0 <span>&#8216; i.e., North<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>TowardsLargerX = 1 <span>&#8216; i.e., East<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>TowardsSmallerY = 2 <span>&#8216; i.e., South<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>TowardsSmallerX = 3 <span>&#8216; i.e., West<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Enum<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Each \u201cCell\u201d is just a structure owned by the form containing information on what you can do in the cell: can you step into that cell (i.e., is it active \u2013 that&#8217;s important since not all areas are perfect rectangles and you may want to \u201ccut out\u201d some sections of the grid as not relevant), can you look up or down, etc:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Protected<\/span> <span>Structure<\/span> Cell<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> IsActive <span>As<\/span> <span>Boolean<\/span> <span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkTowardLargerY <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkTowardLargerX <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkTowardSmallerY <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkTowardSmallerX <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkUpTowardLargerY <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkUpTowardLargerX <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkUpTowardSmallerY <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkUpTowardSmallerX <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkDownTowardLargerY <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkDownTowardLargerX <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkDownTowardSmallerY <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanWalkDownTowardSmallerX <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanLookUp <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> CanLookDown <span>As<\/span> <span>Boolean<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Structure<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">On the form, I laid out five labels \u2013 one on the left, one on the right, one towards the top, one towards the bottom, and one in the middle.<span>&nbsp; <\/span>By setting their Autosize properties to False, I stretch them so that, all together, they covered the entire form.<span>&nbsp; <\/span>I then cleared their text and set their background color to \u201cTransparent\u201d so that the image on the form could show through them.<span>&nbsp; <\/span>I also changed their cursor properties to show a cursor pointing left, right, etc. as appropriate, and set the default form\u2019s cursor to the \u201cno smoking\u201d sign.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Why do this?<span>&nbsp; <\/span>Well, now I can use these labels to (a) show the user what would happen if they clicked there to navigate relative to the current image and (b) handle the click event in that area rather easily.<span>&nbsp; <\/span>I can also enable or disable the labels as necessary \u2013 for example, if the user cannot move forward in their current cell, I simply disable the central label, therefore ignoring all clicks there and allowing the \u201cno smoking\u201d cursor of the base form to now show through.<span>&nbsp; <\/span>That gives valuable feedback to the player.<span>&nbsp; <\/span>A very simple&nbsp;example of the event handler for one of the labels (PanLeft) follows:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> PanLeft_Click(<span>ByVal<\/span> sender <span>As<\/span> <span>Object<\/span>, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>ByVal<\/span> e <span>As<\/span> System.EventArgs) <span>Handles<\/span> PanLeft.Click<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>TransitTo(currentX, currentY, currentZ, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>LeftOrientation(currentOrientation), currentAttitude)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Where:<\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpFirst\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">TransitTo() updates the current player position\/orientation\/attitude, shows the indicated new image, and enables\/disables labels as necessary based on info from the new adjacent cells.<\/font><\/font><\/span><\/p>\n<p class=\"MsoListParagraphCxSpLast\"><span><span><font face=\"Calibri\" size=\"3\">&#8211;<\/font><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><\/span><span><font size=\"3\"><font face=\"Calibri\">LeftOrientation() is a helper function which just returns the orientation 90 degrees to the left \u2013 for example, TowardsLargerY (north) if we were currently aimed TowardsLargerX (east).<span>&nbsp; <\/span><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">The logic for the central label (PanForward) is actually slightly more complex, since we need to see if we\u2019re changing nor only X or Y but possibly Z as well, as might happen if their were stairs or a ladder in front of the user, but otherwiseis <span>&nbsp;<\/span>pretty much the same sort of thing as the other labels. <\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><font size=\"3\"><span><font face=\"Calibri\">To test it out, I created a 2x2x1 cell \u201chouse\u201d to walk around in \u2013 that is, four cells total.<span>&nbsp; <\/span>(Yes, I didn\u2019t test the Z-axis transitions yet, and no doubt that will come back to bite me later \u2013 maybe I\u2019ll have to talk about debugging in the next post. <\/font><\/span><span><span>J<\/span><\/span><span><font face=\"Calibri\">)<span>&nbsp; <\/span>Now, each cell <b>could<\/b> have up to 4 orientations * 3 attitudes = 12 views, and since I didn\u2019t block any up\/down views in any of my four cells, that meant I needed 48 images total.<span>&nbsp; <\/span>I generated some basic GIFs using Paint.exe, and added them into the resource manager, creating some helper functions to assist me in loading them from My.Resources based on the x\/y\/z\/orientation\/attitude.<span>&nbsp; <\/span>(In the \u201creal world,\u201d I might&nbsp;use digital camera shots and load those instead.) However, note that in the game logic as written, not all of the cells would necessarily have to have look up or look down capability, and not all cells can necessarily be traversed to.<span>&nbsp; <\/span>How is all of that information stored and acted upon?<span>&nbsp; <\/span>I didn\u2019t want to hard-code the actual layout into the code, so I needed to store this information in a separate file instead.<span>&nbsp; <\/span>XML is a good way to store it, being human-readable (unlike a binary file).<span>&nbsp; <\/span>Here\u2019s a bit of the XML file I created to detail the logic for one cell, created as file MAZE.XML:<span>&nbsp; <\/span><\/font><\/span><\/font><\/p>\n<p class=\"MsoNormal\"><span>&lt;?<\/span><span>xml<\/span><span> <\/span><span>version<\/span><span>=<\/span><span>&#8220;<span>1.0<\/span>&#8220;<span> <\/span><span>encoding<\/span><span>=<\/span>&#8220;<span>utf-8<\/span>&#8220;<span> ?&gt;<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&lt;<\/span><span>cells<\/span><span>&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp; <\/span>&lt;<\/span><span>cell<\/span><span> <\/span><span>active<\/span><span>=<\/span><span>&#8220;<span>true<\/span>&#8220;<span> <\/span><span>x-pos<\/span><span>=<\/span>&#8220;<span>0<\/span>&#8220;<span> <\/span><span>y-pos<\/span><span>=<\/span>&#8220;<span>0<\/span>&#8220;<span> <\/span><span>z-pos<\/span><span>=<\/span>&#8220;<span>0<\/span>&#8220;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span>lookup<\/span><span>=<\/span><span>&#8220;<span>true<\/span>&#8220;<span> <\/span><span>lookdown<\/span><span>=<\/span>&#8220;<span>true<\/span>&#8220;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span>walk-larger-x<\/span><span>=<\/span><span>&#8220;<span>true<\/span>&#8220;<span> <\/span><span>walk-larger-y<\/span><span>=<\/span>&#8220;<span>true<\/span>&#8220;<span> <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp; <\/span><\/span><span>walk-smaller-x<\/span><span>=<\/span><span>&#8220;<span>false<\/span>&#8220;<span> <\/span><span>walk-smaller-y<\/span><span>=<\/span>&#8220;<span>false<\/span>&#8220;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span>walkup-larger-x<\/span><span>=<\/span><span>&#8220;<span>false<\/span>&#8220;<span> <\/span><span>walkup-larger-y<\/span><span>=<\/span>&#8220;<span>false<\/span>&#8220;<span><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp; <\/span><\/span><span>walkup-smaller-x<\/span><span>=<\/span><span>&#8220;<span>false<\/span>&#8220;<span> <\/span><span>walkup-smaller-y<\/span><span>=<\/span>&#8220;<span>false<\/span>&#8220;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><\/span><span>walkdown-larger-x<\/span><span>=<\/span><span>&#8220;<span>false<\/span>&#8220;<span> <\/span><span>walkdown-larger-y<\/span><span>=<\/span>&#8220;<span>false<\/span>&#8220;<span> <\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp; <\/span><\/span><span>walkdown-smaller-x<\/span><span>=<\/span><span>&#8220;<span>false<\/span>&#8220;<span> <\/span><span>walkdown-smaller-y<\/span><span>=<\/span>&#8220;<span>false<\/span>&#8220;<span>&gt;<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp; <\/span>&lt;\/<\/span><span>cell<\/span><span>&gt;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>[\u2026 etc \u2026]<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&lt;\/<\/span><span>cells<\/span><span>&gt;<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Again, in the \u201creal world,\u201d a separate application would likely generate the file from graphs that the developer drew, but I wrote this one by hand.<span>&nbsp; <\/span>Anyway, each &lt;cell&gt; element contains all of the information I want to load into the structure representing a given location, including which cell the information pertains to.<span>&nbsp; <\/span>I added the file into the resource manager, noting that My.Resources.Maze will now return a string containing the contents of the XML file \u2013 cool.<span>&nbsp;&nbsp; <\/span>Using the XML resource to initialize the cells during the game is extremely easy, and here is an excerpt from my code for accessing that file resource:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Sub<\/span> LoadMazeRules()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Load the maze rules from the built-in XML file<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> x <span>As<\/span> <span>Integer<\/span> = 0<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> y <span>As<\/span> <span>Integer<\/span> = 0<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> z <span>As<\/span> <span>Integer<\/span> = 0<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> xmlDoc <span>As<\/span> <span>New<\/span> XmlDocument<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>xmlDoc.LoadXml(<span>My<\/span>.Resources.Maze)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> outerNode <span>As<\/span> XmlNode = _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>xmlDoc.GetElementsByTagName(<span>&#8220;cells&#8221;<\/span>).Item(0)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>For<\/span> <span>Each<\/span> node <span>As<\/span> XmlNode <span>In<\/span> outerNode.ChildNodes<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>x = node.Attributes.GetNamedItem(<span>&#8220;x-pos&#8221;<\/span>).Value<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>y = node.Attributes.GetNamedItem(<span>&#8220;y-pos&#8221;<\/span>).Value<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>z = node.Attributes.GetNamedItem(<span>&#8220;z-pos&#8221;<\/span>).Value<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>With<\/span> Cells(x, y, z)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span>.CanLookDown = node.Attributes.GetNamedItem(<span>&#8220;lookdown&#8221;<\/span>).Value<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>.CanLookUp = node.Attributes.GetNamedItem(<span>&#8220;lookup&#8221;<\/span>).Value<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8216; (Etc\u2026 keep loading in attributes for this cell)<\/span><span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>With<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Next<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">As you can see, I start out by declaring a new XmlDocument instance.<span>&nbsp; <\/span>The method LoadXml can take a string which contains valid XML , and since that\u2019s exactly what I can provide from calling My.Resources.Maze(), life is good.<span>&nbsp; <\/span>At any element level, I can query for child elements by name \u2013 I know that \u201ccells\u201d is a child of the XmlDocument node, so I get the first (and only) instance of that, and then I know that \u201ccell\u201d elements are children of that node, so I query for those.<span>&nbsp; <\/span>Having that list, I can then enumerate over it and pick out all of the information I want from the attributes via GetNamedItem(), supplying the desired attribute as the argument.<span>&nbsp; <\/span>It\u2019s very important to note that XML elements, tags, etc are all case-sensitive, so querying for \u201cCell\u201d instead of \u201ccell\u201d will not work!<span>&nbsp; <\/span>Also note that I need not make any assumptions about the ordering of the cell elements with respect to my internal array, since I\u2019m taking the coordinates directly from the XML itself.<span>&nbsp; <\/span>If, for some reason, the XML is missing a cell, that cell structure\u2019s members will all default to zero or false (including IsActive), so I could just leave out any inactive cells if I wished to.<span>&nbsp; <\/span>When I\u2019m done with the XmlDocument, it just goes out of scope and I don\u2019t worry about it anymore.<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">There are other ways to retrieve XML as well, and you can see some of these from the snippets provided in Visual Basic 2005.<span>&nbsp; <\/span>To see these, in the editor type \u201c?\u201d and press the TAB key, and then navigate down to the XML item and select it.<span>&nbsp; <\/span>There are a lot of snippets here, but two of them are particularly interesting.<span>&nbsp; <\/span>The first one is \u201cRead XML from a String,\u201d which looks like this:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> reader <span>As<\/span> XmlReader = XmlReader.Create( _<\/span><\/p>\n<p class=\"MsoNormal\"><span>New<\/span><span> StringReader( <span>&#8220;&lt;book\/&gt;&#8221;<\/span><span> <\/span>))<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>While<\/span> reader.Read()<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>While<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">and where you replace the argument to StringReader with your own XML string.<span>&nbsp; <\/span>This is analogous to reading in a normal stream serially, and it\u2019s particularly useful<span>&nbsp; <\/span>when you need to find something in a XML string but you don\u2019t want to duplicate everything into an XmlDocument.<span>&nbsp; <\/span>It\u2019s fast and doesn\u2019t cache anything.<span>&nbsp; <\/span>In the \u201cwhile\u201d loop, you would add code to check reader.NodeType, see what it is (e.g., XmlNodeType.Element),<span>&nbsp; <\/span>and act appropriately to that to collect information from the members reader.Name, reader.Value, etc.<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">The second interesting snippet is actually two snippets: \u201cWrite class data to an XML file\u201d and the<span>&nbsp;<\/span>corresponding \u201cRead class data from an XML file.\u201d<span>&nbsp; <\/span>Essentially, the former just writes out all of the data from a class instance into the XML file, and the latter reads it back in.<span>&nbsp; <\/span>If I had created a tool to automatically generate my XML file for my virtual walk-through, I might have used these snippets to write out the cell values to an XML file and then read them back in later, putting the logic (and the structure) in a class library to be shared by both.<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">I\u2019ve included the code written thus far in a ZIP file attached to this post. <span>&nbsp;<\/span>You\u2019ll note when you look through it that I\u2019ve added a routine to check the validity of the XML information \u2013 it\u2019s pretty straightforward, and the only interesting thing is that I only run the validation when debugging (i.e., the code is in an <b>#if DEBUG<\/b> block).<span>&nbsp; <\/span>For my next post, we\u2019ll add some state to this game, and add some controls on the fly to give the player something to do other than walk around.<\/font><\/font><\/span><\/p>\n<p><span>&#8211;Matt&#8211;*<\/span><\/p>\n<p><a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/MSDNBlogsFS\/prod.evol.blogs.msdn.com\/CommunityServer.Components.PostAttachments\/00\/02\/15\/60\/73\/Maze.zip\">Maze.zip<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using XML as a resource in your code \u2013one more series on gamewriting (Matt Gertz) This is actually going to be part one of a two-part blog.&nbsp; In this post, I\u2019m going to cover some basic usage of XML, as well as a few other interesting coding points such as debug-only code.&nbsp; In the second [&hellip;]<\/p>\n","protected":false},"author":258,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[22,195],"tags":[101,165],"class_list":["post-6323","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-matt-gertz","category-visual-basic","tag-matt-gertz","tag-vb2005"],"acf":[],"blog_post_summary":"<p>Using XML as a resource in your code \u2013one more series on gamewriting (Matt Gertz) This is actually going to be part one of a two-part blog.&nbsp; In this post, I\u2019m going to cover some basic usage of XML, as well as a few other interesting coding points such as debug-only code.&nbsp; In the second [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6323","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/258"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=6323"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6323\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=6323"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=6323"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=6323"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}