Lesson 26.2 – Hiding Unvisited Locations on the World Map

Now that we have a map, it would be nice to only show the images for the locations the player has visited. That is what we’ll add in this lesson.

 

NOTE: In the last lesson, there wasn’t an image for the Bridge location. That’s because I used the images from the WPF version of these lessons, and there is no Bridge location in that game.

So, if you finished Lesson 26.1, and you don’t have a Bridge image (and you don’t have six columns of PictureBox controls), please go back to Lesson 26.1 and make the changes to add the missing column. This will require downloading the location images again (to get the Bridge image), and changing the WorldMap form (to add the new column and display the Bridge image).

 

STEP 1: Add FogLocation.png to SuperAdventure\Images

After adding it, set its properties to:

Build Action: Embedded Resource

Copy to Output Directory: Do not copy

 

Right-click and select “Save as”, to download

 

 

Step 2: Edit Engine\Player.cs

We’re going to store the ID of every location the player visits. We’ll save the IDs in a new List property named LocationsVisited (line 69).

Because this is a List property, we need to initialize it, otherwise it will be null, instead of an empty List. We’ll do that in the constructor (on line 80), where we initialize the other list properties.

Now, when the player moves to a new location, we need to add its ID to the property – if it hasn’t already been added. We do that inside the MoveTo function, on lines 174 to 177. If the LocationsVisited property does not already contain the ID of the location, we add it to the List.

 

Player.cs

 

 

Step 3: Edit SuperAdventure\SuperAdventure.cs and SuperAdventure\WorldMap.cs

In order to display the correct image for a location (the fog, or the location’s image), the WorldMap form needs the current player object, to know which locations the player has visited. So, we need to pass it from the SuperAdventure form, into the WorldMap form – like we do with the TradingScreen form.

In WorldMap.cs, we need to add a Player parameter to the constructor (line 13).

In SuperAdventure.cs, we pass the current player when we instantiate the WorldMap form (line 225).

 

Now, we can hide the unvisited locations by displaying the FogLocation in the PictureBox for any locations whose IDs are not in the player object’s LocationsVisited list.

I’ve done that by using the ternary operator inside the calls to SetImage (lines 17 through 25). If LocationVisited contains the location’s ID, we pass the name of the location’s image file. If the ID is not in LocationsVisited, we pass “FogLocation”.

 

WorldMap.cs

 

SuperAdventure.cs

 

 

Step 4: Edit Engine\Player.cs

We want to remember the player’s LocationsVisited values between game sessions. So, we need to update the code that saves the player’s data to the saved game file – and the code that creates the player object from that file.

In the ToXmlString() function, we’ll add a new section that creates nodes with the ID values in LocationsVisited (lines 349 through 361). This is like the code to save the InventoryItems and PlayerQuests.

We create a LocationsVisited node, with a child node named LocationVisited, to hold the location ID.

In the CreatePlayerFromXmlString() function we add code to read those values from the saved game file (lines 116 through 121).

 

Player.cs (with changes to save/read LocationsVisited from saved game file)

 

 

Step 5: Edit Engine\PlayerDataMapper.cs

We also need to save the LocationsVisited values to the database, and read them when loading a saved game from the database – if you are using a database to save the game data.

To save the location IDs, we’ll create a new table named LocationVisited. It will only have a single column “ID”, whose datatype is “int”, and does not all nulls. The script to create it is below.

 

 

Next, we need to update PlayerDataMapper to save the values into this table, and read the values from it.

The code to do this is like the code for adding and reading the values for the InventoryItems and PlayerQuests.

 

We save the Location IDs to the table in the SaveToDatabase() function, at lines 286 through 307.

The code to read from this table is in the CreateFromDatabase() frunction, at lines 111 through 131.

 

NOTE: I noticed a bug with the readers not closing. So, inside each “using” block of code in CreateFromDatabase, I’ve added a “reader.Close();”. These are on lines 58, 85, 108, and 130.

 

PlayerDataMapper.cs

 

 

Step 5: Test the game.

Now, as the player moves to new locations, the map will display more images – instead of the “fog” image for unvisited locations. The map should start to look like this (for example):

 

 

Summary

This uses hard-coded values for placing the images in the PictureBox, which isn’t the best way to create a map. This would be much more flexible if we used X and Y coordinates for the locations. Then, we could do things like having the map always centered on the player’s current location, and showing a 5 x 5 (or larger) grid of the surrounding locations.

If you follow the “Build a C#/WPF RPG” lessons, that is how we are building that world.

 

Source code for this lesson

From GitHub: https://gist.github.com/ScottLilly/bedda829265fdcf36e716051be98b795

From Dropbox: https://www.dropbox.com/sh/rg7krdqkhxdmrn8/AAA4o-2XVrCrIvZeirpRVyIwa?dl=0

 

 

Previous lesson: Lesson 26.1 Displaying a World Map

All lessons: Learn C# by Building a Simple RPG Index

Leave a Reply

Your email address will not be published. Required fields are marked *