Press "Enter" to skip to content

Lesson 16.1 – Writing the function to move the player

Lesson Objectives

At the end of this lesson, you will know…

  • How to plan a function
  • How to write the code/logic for a function
  • Some of the most common C# commands

 

Ok, we’ve spent all this time building up the pieces we need for our game. Now it’s time to actually get the game to do something. The first thing we’re going to add the code to handle when the player moves to a new location.

By the way, this is a long lesson, and covers a lot of new things. So make sure you have some time to complete it.

 

Outline of the function

The first thing we need to do is figure out what’s going to happen during a move.

When I write a function that needs to do a lot of things, like this one, I like to do some planning first – so I don’t miss anything.

When the player moves to a new location, we’ll completely heal them, we’ll check to see if the location has any quests (and if the player can complete them), and if there are any monsters to fight there.

Here is an outline of the logic for a player move function. Something like this is often called “pseudo-code”. It isn’t C# code, but it represents what the code will do.

Each indentation level is where we handle a different condition – for example, the steps to follow if the location has a monster, and the steps to follow if the location doesn’t have a monster.

  • If the location has an item required to enter it
    • If the player does not have the item
      • Display message
      • Don’t let the player move here (stop processing the move)
  • Update the player’s current location
    • Display location name and description
    • Show/hide the available movement buttons
  • Completely heal the player (we assume they rested/healed while moving)
    • Update hit points display in UI
  • Does the location have a quest?
    • If so, does the player already have the quest?
      • If so, is the quest already completed?
        • If not, does the player have the items to complete the quest?
          • If so, complete the quest
            • Display messages
            • Remove quest completion items from inventory
            • Give quest rewards
            • Mark player’s quest as completed
      • If not, give the player the quest
        • Display message
        • Add quest to player quest list
  • Is there a monster at the location?
    • If so,
      • Display message
      • Spawn new monster to fight
      • Display combat comboboxes and buttons
        • Repopulate comboboxes, in case inventory changed
    • If not
      • Hide combat comboboxes and buttons
  • Refresh the player’s inventory in the UI – in case it changed
  • Refresh the player’s quest list in the UI – in case it changed
  • Refresh the cboWeapons ComboBox in the UI
  • Refresh the cboPotions ComboBox in the UI

 

Creating a shared function

We have four different functions for movement, one for each direction. And we need to do the steps shown above for moving in each direction.

We could do that by writing the same code in each function. But then, if we ever want to change that logic, we’d need to make the change in four places – and that often leads to mistakes.

So, we’re going to create a new shared “MoveTo” function to handle movement to any location. Each of the four movement functions will call that one new function.

 

Storing the player’s location

We also need a place to save the player’s current location. Since this value will change, we need to store it in either a variable or a property.

In this case, we’ll make a property in the Player class. It makes sense to do this because a player’s location is a “property” (in the general sense) of the player.

 

Storing the current monster

We also need a place to store the current monster that the player is fighting, in case they move to a location that has a monster there.

In the World class, we have a list of all the monsters in the game. However, we can’t use the monsters from there to fight against. We only have one “instance” of each monster. So, if we fought against the rat in the World.Monsters list, and killed it, the next time we fight against it, it would already be dead.

When we move to a new location, if it has a monster there, we’ll create a new instance of that type of monster and save it to a variable. Then, the player will fight against that instance of the monster.

 

Now that we know what we want to accomplish, we’re ready to add the code.

 

Creating the functions to move the player

Step 1: Start Visual Studio and open the solution.

 

Step 2: First, let’s create the new property to store the player’s current location.

Double-click on the Player class, in the Engine project. Add a new property named CurrentLocation, with a datatype of Location.

public Location CurrentLocation { get; set; }

Note: You don’t have to put the properties in any specific order. I just like to like to keep my List properties at the end of the properties. I find it a little easier to read when they’re grouped in the same place in every class.

 

Step 3: Right-click on the SuperAdventure.cs form, in the SuperAdventure project, then select “View Code”.

 

Step 4: Because we have a lot of code to write, and it’s easy to mistype something, copy the new code for the SuperAdventure form from here (https://gist.github.com/ScottLilly/208630cfcdded1cbfdc0) and overwrite all the existing code in SuperAdventure.cs with it.

 

What’s in the code you just added?

On line 18, we added a new variable to hold the monster that the player is fighting at the current location.

In the form’s constructor, we do a couple things to start the game.

On line 25, we “move” the player to their home. Since the MoveTo function expects a location as the parameter, we need to use the World.GetLocationByID() function to get the correct location. This is where we use the constant World.LOCATION_ID_HOME, instead of using the value 1. It’s much easier to look at the code with the constant and know what it’s supposed to be doing when we use this clearly-named constant.

On line 26, we add an item to the player’s inventory – a rusty sword. They’ll need something to fight with when they encounter their first monster.

We added the new MoveTo function to handle all player movement.

We’ve also gone into each of the four functions that handle moving in a different direction and had them call the MoveTo function.

The MoveTo function

The first thing you may notice in this function are the lines that have a “//” in them. These are comments. Comments are ignored by the computer. They only exist for programmers to read, to know what the program is supposed to be doing. Everything after the double-slashes, until the end of the line, is ignored by the computer.

I used a lot more comments in this function than I normally would. That’s to make it easier for you to follow along with what is happening, and see how the code ties back to the pseudo-code we have above.

The second thing you may have noticed is that this function is long – over 300 lines long.

That’s really too long for a function.

When a function is that long, it’s difficult to keep track of what exactly it’s supposed to be doing. But we’re going to clean this up in the next lesson. Personally, I like to keep my functions around 10 to 40 lines long.

We’ll break this function into smaller functions in the next lesson.

 

What’s happening in the MoveTo() function?

On line 57, we have our first “if” statement.

In this case, we check if the new location has any items required to enter it.

The “!=” is how C# says “not equal to”. The exclamation point, when doing any sort of comparison in C#, means “not”. And “null” means nothing/empty.

So, if the ItemRequiredToEnter property of the location is not empty, we need to check if the player has the required item in their inventory. If it is empty, we don’t need to do anything – there is no required item, so the player can always move to the new location.

On line 72 we see if we found the required item in the player’s inventory. If we didn’t find an item with a matching ID, the “playerHasRequiredItem” variable will still be “false”.

Notice the exclamation point in front of playerHasRequiredItem.

Let’s assume the player does not have the required item in their inventory. The “playerHasRequiredItem” variable will have a value of “false”. Doing a “not” on a Boolean variable, reverses its value: “!true” equals “false”, and “!false” equals “true”.

Thinking “if not false” is not as clear as thinking “if true”. But they both mean the same thing.

On line 75, we display the message that the player is missing the item required to enter this location. This line has a new “+=” symbol.

“+=” means, take the value from the variable/property on the left, add the value on the right to it, and assign the results back into the variable/property on the left.

When you use “+=” with a string, it means, “add the string value on the right to the end of the existing string”. When you use it with a number, it means, “add the value on the right to the value on the left”.

Here, we take the text in the rtbMessages RichTextBox, and add our new message to the end of it. That way, the player can still see the old messages. If we used the “=” sign instead, it would replace the existing “Text” value with our new message.

We also have “Environment.NewLine”. This adds an “Enter” to the text, so the next thing we add to it will be displayed on the next line, instead of the end of the current line.

Line 76 has “return”. This means “exit out of this function”.

Since this function is a “void” function (see line 54), it doesn’t return a value. We can “return” here and not do the rest of the function. We want to do that in this case, because the player does not have the item required to enter the location. So, we don’t want to do the rest of the function, which would actually move them to the location.

On lines 84 through 87, we make the movement buttons visible, or not, based on whether or not the new location has a place to move to in each direction. We do this by checking if the property for the location is empty or not.

The “Visible” property of the buttons expects a Boolean value: true or false.

So, on line 84, if the LocationToNorth property is not empty, the value to the right of the equal sign will evaluate to “true”, and the button will be visible. If the LocationToNorth property is empty, this will evaluate to “false”, and the button will not be visible.

On line 100, we check if there is a quest at this location. If so, we need to do some more work.

Lines 106 through 117 are where we look through the player’s quest list, to see if they already have the quest at this location and if they already completed it.

Lines 128 through 163 looks at each item required to complete the quest, then checks each item in the player’s inventory, to see if they have it, and have enough of it, to complete the quest.

There are some “break” statements in this “foreach”. Those are used to stop looping through the items and exit the “foreach” loop. If we discover that the player doesn’t have one item, or enough of it, to complete the quest, we can stop checking for any other items.

Line 180 has a “-=”. The “+=” means, “add the value on the right to the variable/property on the left”. So, a “-=” means, “subtract the value on the right from the variable/property on the left”. You can only use this with numbers, and not strings, unlike the “+=”.

In this case, we are using it to remove items from the player’s inventory that they turn in to complete the quest.

On line 204, there is a “++”. When you have this after a variable or property, it means “add 1 to this variable or property”. There is also a “–“, for when you want to subtract 1 from a variable or property.

At lines 264 through 273, we create the new monster to fight, by making a new monster object, using the values from the standard monster in our World class.

 

Updating the DataGridViews in the UI

From lines 290 through 321 we update the DataGridView controls in the UI.

The player’s inventory will have changed if they completed a quest. The items needed to turn in were removed from their inventory. The reward item was added to their inventory. So, we need to update the UI with their current inventory.

Also, if they received a new quest, or completed an existing one, their quest list would change.

 

Updating the ComboBoxes in the UI

For the ComboBoxes in the UI, we create new lists to hold the specific datatype of items we want to show in the list (lines 324 and 353). Next, we go through all the items in the player’s inventory and add them to these lists, if they are the correct datatype (lines 326-335 and 355-364).

On lines 328 and 357, there is a new comparison: “is”. This is used to see if an object is a specific datatype.

Remember how we created the Weapon and HealingPotion sub-classes of the Item class? When you create a Weapon object, its datatype is both Weapon and Item. When you create a HealingPotion object, its datatype is both HealingPotion and Item.

If the lists are empty (weapons.Count or healingPotions.Count are equal to 0), we hide the ComboBox and “use” buttons, since there is no weapon or potion for the player to use.

If the lists have items in them, we “bind” the list to the comboboxes (lines 345-349 and 374-378). The “DisplayMember” determines what property will be displayed in the comboboxes. In this case, we want to display the value of the Name property. The “ValueMember” is the behind-the-scenes value we’ll use a little later, to know which item was selected.

NOTE: There are better ways to connect your list properties to DataGridViews and ComboBoxes. But we’re just concentrating on the basics in these tutorials.

NOTE: Hopefully you noticed something about the variable names. They are generally long and descriptive. That makes it easy to understand what values they are supposed to hold. By making your variable names descriptive, it will be easier to work with your program – especially when fixing bugs or making changes in the future.

There are a couple cases in the “foreach”s where I use short variables like “qci” and “ii”.

Since the foreach loop is only a few lines long, I sometimes use a shorter variable name. The variable has a very short life – it only exists within those few lines of the loop. You can display the whole loop on your screen, without scrolling. So, it’s easy to keep track of where the variable is populated and where it is used. If the loop was longer, I’d use a longer, more descriptive name.

 

Summary

Now you’ve seen how to plan out your logic in pseudo-code, and then create a function in the program to perform that logic.

You’ve seen how “if”s, “else”s, and “foreach”s are used in a function.

You’ve also seen what a huge function looks like, and you probably have an idea how difficult it would be to work with it. The next lesson will cover how to clean up that function and make it easier to understand.

We covered a lot in this lesson. If there was anything that wasn’t clear, please leave a comment below and I can update this lesson with some more details.

 

Source code for this lesson

Source code on GitHub

Source code on Dropbox

 

Next lesson: Lesson 16.2 – Refactoring the player movement function

Previous lesson: Lesson 15.1 – Getting random numbers for the game

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

220 Comments

  1. Elijah Scherz
    Elijah Scherz March 3, 2015

    I have a quick question regarding the IF statement on line 72.

    So if the statement was initially false, because the player did not have the weapon, then we wrote:

    if(!playerHasRequiredItem)

    Then doesn’t this mean “If playerHasRequiredItem is not false” then execute the IF statement? Or am I going insane, because I see inside the loop that this code was directed towards players who did not have the required item.

    You said that !false = true, so I thought this was how this would flow.

    • Scott Lilly
      Scott Lilly March 4, 2015

      “if(!playerHasRequiredItem)” actually means, “If playerHasRequiredItem is false”, not “If playerHasRequiredItem is not false”. Another way that line 72 could have been written is “if(playerHasRequiredItem == false)”, but much of the time, you’ll see programmers use the “!” instead.

      Boolean logic can be a little tricky, especially when you have “nots” in it.

      Maybe if you think of the “!” as “the opposite of”, that might help.

      If the player does not have the required item, then playerHasRequiredItem will be “false”. So, you would re-state the condition inside the parentheses “!playerHasRequiredItem” as “the opposite of false”. “The opposite of false” is “true”, so the code inside the curly braces is run.

      Let me know if that clears it up for you.

      • Simon
        Simon June 3, 2015

        I’m unsure how the logic ‘playerhasrequireditem’ could ever be true on line 72. If it was found to be true then the if statement is exited on the previous if statement. So it will only be a false value if we enter the 2nd if statement. In that case why would it be !false?

        • Scott Lilly
          Scott Lilly June 18, 2015

          Since we have the “!” (which is shorthand for “not”), the “if” would be true when “playerHasRequiredItem” is false.

          We check to see if the player has the required item. If they don’t, “playerHasRequiredItem” is false. When we get to the “if”, “not false” is the same as “true”. So, the message “You must have a…” is displayed and the player is not allowed to move to the location. This is boolean logic, and is something you’ll see in many programs. It can get more complex if you add in “or”s, and “and”s.

  2. Bri
    Bri August 2, 2015

    As soon as I pasted the code in the SuperAdventure.cs I got several errors regarding the dgvInventory. The recurring one being “the name ‘dgvInventory’ does not exist in the current context. ”

    could you explain why that may be and possible fixes? Had no errors before I pasted it.

    • Scott Lilly
      Scott Lilly August 3, 2015

      The most likely problems are either that you don’t have the datagrid for the inventory added to the UI, or that you may have mistyped the name. Double-check Lesson 12.1 to see if one of those is the problem. If it isn’t, please let me know and we can dig a little deeper.

      • Alex
        Alex August 19, 2015

        I have a similar problem. Pasting the code resulted in some errors related to dgvInventory

        more specific to this line:

        this.dgvInventory.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dataGridView1_CellContentClick);

        The datagrids are added, no mistypes were made, checked that twice.

        Also the “Design” tab doesn’t show any element while this is written.

        Although commenting the line gets the “Design” tab back to normal and it lets me run the program, it instantly exits with an “Unhandled exception”.

        • Scott Lilly
          Scott Lilly August 19, 2015

          It sounds like you accidentally double-clicked on the dgvInventory datagrid, while in the design editor. When someone does that, Visual Studio will create an event handler (in this case, a function to perform when the player clicks on the dgvInventory datagrid).

          Can you do this?:
          1. Comment out the line “this.dgvInventory.CellContentClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.dgvInventory_CellContentClick);”
          2. Check SuperAdventure.cs (the code editor) for a function named “dgvInventory_CellContentClick(object sender, DataGridViewCellEventArgs e)”. Comment out the complete function (from its name to the closing curly-bracket.
          3. Save the solution and rebuild it. Check if there are any errors. If so, please copy the complete error message here.
          4. Run the program. If you get an error while running it, please copy the complete error message here.

          • Alex
            Alex August 20, 2015

            Got to step 4 without errors, but running it results in a new exception at line 25:

            MoveTo(World.LocationByID(World.LOCATION_ID_HOME));

            An unhandled exception of type ‘System.TypeInitializationException’ occurred in SuperAdventure.exe

            Additional information: The type initializer for ‘Engine.World’ threw an exception.

          • Scott Lilly
            Scott Lilly August 20, 2015

            OK, we’re making some progress. It sounds like there is a problem with the static World class. Here are a couple things to check:

            1. Make sure the code in World.cs matches the code code from Lesson 11.1 https://gist.github.com/ScottLilly/803df1021fbc404b38f5
            2. Make sure the SuperAdventure and Engine projects are using the same versions of the .Net Framework. You can check this by double-clicking on “Properties” for each project in the Solution Explorer. Check the values in the “Target Framework” dropdown. If they aren’t the same, set them both to the highest (most recent) version.

            If that still doesn’t fix the problem (or give you a new error), I’d like to take a look at your solution. If you can upload the complete solution (all the files in, and underneath, the top-level directory), I can research it.

  3. Fred M.
    Fred M. October 21, 2015

    Hello Scott!

    Have some errors, could you have a look at this?

    Error    1    ‘System.Windows.Forms.Label’ does not contain a definition for ‘DataSource’ and no extension method ‘DataSource’ accepting a first argument of type ‘System.Windows.Forms.Label’ could be found (are you missing a using directive or an assembly reference?)    C:\Projects\Training Projects\Fred\Other Projects\SuperAdventure\SuperAdventure\SuperAdventure\SuperAdventure.cs    339    28    SuperAdventure

    It happens at cboWeapons and cboPotions. I don’t really know why.

    Thanks in advance!

    Fred

    • Scott Lilly
      Scott Lilly October 21, 2015

      Hi Fred,

      It sounds like you may have used labels, instead of combobox controls, when you added cboWeapons and cboPotions. Double-check lesson 12.1. If that is the case, all you need to do is delete the cboWeapons and cboPotions labels (open SuperAdventure.cs, in the UI design mode, click on each of the labels, and press the delete button), then add them back in as comboboxes.

      Please let me know if that is not the problem.

      • Fred M.
        Fred M. October 22, 2015

        Hello Scott,

        perfect! That was the problem. Thanks! 🙂

        Fred

        • Scott Lilly
          Scott Lilly October 22, 2015

          Cool! Let me know if you run into anything else.

  4. ED
    ED December 13, 2015

    Hello. I have an error, and I don’t know why it’s popping up. I don’t want to restart the entire project, so can you help?

    Heres the error:

    Error 1 ‘WindowsFormsApplication1.Superadventure.Dispose(bool)’: no suitable method found to override

    • Scott Lilly
      Scott Lilly December 13, 2015

      This error usually happens if a file (or project, or namespace) is renamed, and all the parts didn’t get renamed. For example, the SuperAdventure form has a SuperAdventure.Designer.cs file that needs to stay in-sync with the SuperAdventure.cs file.

      It’s a little difficult to explain how to track down the exact problem, and how to fix it. So, if you could upload all the files of your solution (including its sub-directories, and the files in them) to some place like Dropbox, I can look at it and get the solution working for you.

  5. Alexandre Ferraz
    Alexandre Ferraz December 20, 2015

    Hello!

    I’m having an awesome timing with your lessons. I was watching some Bob Tabor’s videos and learning some C# when I realized that I was in need for some practical exercises before continuing on and your lessons are just amazing to accomplish that! Well, after sharing my thoughts about your course I need to say that I’m with a problem.

    I got this: ‘SuperAdventure’ does not contain a definition for ‘button1_Click’ and no extension method ‘button1_Click’ accepting a first argument of type ‘SuperAdventure’ could be found (are you missing a using directive or an assembly reference?)’ (line64)

    I made a search here and there but could not figure out what to do to solve this 😐

    • Scott Lilly
      Scott Lilly December 20, 2015

      Thanks Alexandre!

      It sounds like maybe one of the buttons was not renamed, or maybe you accidentally double-clicked on one of the buttons before renaming it. When you add buttons to a form, Visual Studio automatically names them “button1”, “button2”, etc. It also adds information to the SuperAdventure.Designer.cs file, with the button’s name. The SuperAdventure.Designer.cs file is where the UI controls connect to the event handler methods (like “Click”) in SuperAdventure.cs.

      Open the UI editor for the SuperAdventure form and click once on each button (be careful to only click once – double-clicking creates some new code), to confirm if they have the names in lesson 12.1. You will see the name in the “Properties” section of Visual Studio (lower-right corner).

      Properties section, showing button name

      Please tell me if all the buttons have the names from lesson 12.1. There are two possible solutions, depending if the names match, or if they don’t. Then, I can tell you how to solve the problem.

  6. Alexandre Ferraz
    Alexandre Ferraz December 20, 2015

    Hey, Scott! Thanks for the answer!

    I realized what I had did wrong. I added buttons instead labels in the 03.1 lesson, what a shame haha. I commented out the line 64 because WVS didn’t let me access the visual UI and I couldn’t check what you said to check, the comment worked and I could let in, their names were correct for the buttons and then I checked the labels and found that their were not really labels.

    I just made them again and the program runned smoothly.

    Thanks again!

    • Scott Lilly
      Scott Lilly December 20, 2015

      You’re welcome! Let me know if you encounter any other problems.

  7. David
    David December 23, 2015

    I have gotten a lot of errors as soon as I put in this code here they are.

    1 ‘Item’ does not contain a constructor that takes 3 arguments – This one is repeated multiple times

    2 ‘SuperAdventure’ does not contain a definition for ‘SuperAdventure_Load’ and no extension method ‘SuperAdventure_Load’ accepting a first argument of type ‘SuperAdventure’ could be found

    3’Weapon’ does not contain a constructor that takes 5 arguments – repeated twice

    4 ‘HealingPotion’ does not contain a constructor that takes 4 arguments

    5‘LivingCreature’ does not contain a constructor that takes 2 arguments

    • Scott Lilly
      Scott Lilly December 23, 2015

      For problems 1, 3, 4, and 5, make sure you made the changes in Lesson 8.2, where we update the constructors.

      For error 2, did you name your UI project SuperAdventure, or did you use a different name? If you used a different name, please check this post (Lesson 02.2B – Fixing the namespace).

      If those do not fix the errors, please let me know, so we can get the program running.

  8. David
    David December 23, 2015

    Doing lesson 8.2 fixed all of the errors

    • Scott Lilly
      Scott Lilly December 24, 2015

      Cool. Let me know if you encounter any other problems.

  9. Ayeh
    Ayeh May 26, 2016

    Hi! scott are you still there?  ..

    i have an  ” Error 1 ‘SuperAdventure’ is a ‘namespace’ but is used like a ‘type’  ”      it’s in the program.cs. I can’t figure it out how did it happen?.

    I’m just copy your code and paste it.

    • Scott Lilly
      Scott Lilly May 28, 2016

      I’m still here.

      Did you name create the project with a different name from “SuperAdventure”? If so, please read this tip: Lesson 02.2B – Fixing the namespace

      If that does not fix the problem, can you upload your solution (all the files, all the sub-directories, and all the files in the sub–directories) to Dropbox or GitHub, so I can examine it?

  10. Ayeh
    Ayeh May 29, 2016

    thank you scott for the lesson 02.2b fixed my problem,.,

  11. Matthew
    Matthew June 26, 2016

    I have an Error on line 315 of SuperAdventure.Designer.cs saying:
    “Error CS1061 ‘SuperAdventure’ does not contain a definition for ‘SuperAdventure_Load’ and no extension method ‘SuperAdventure_Load’ accepting a first argument of type ‘SuperAdventure’ could be found (are you missing a using directive or an assembly reference?) Super Adventure c:\Projects in C#\Super Adventure\Super Adventure\Super Adventure.Designer.cs 315 Active”

    the line in question is:

    “this.Load += new System.EventHandler(this.SuperAdventure_Load);”

    How could I fix it?

    • Scott Lilly
      Scott Lilly June 26, 2016

      Can you comment out line 315 (add two forward slashes at the front of the line), in SuperAdventure.Designer.cs, so it will be:

      //this.Load += new System.EventHandler(this.SuperAdventure_Load);

      If you double-clicked on the form, in Design mode, that would have created that line, and a SuperAdventure_Load function. Then, if you pasted code from one of the other lessons, and it does not have the SuperAdventure_Load function, you would see that error. There is some more information on how the eventhandlers work in Lesson 21.3, if you want to know exactly what is happening there.

      Please tell me if that does not fix the problem.

      • Matthew
        Matthew July 5, 2016

        Thanks

  12. Gray Bear
    Gray Bear June 27, 2016

    Hello!

    I’ve been having troubles with a couple things.

    With the, ” foreach (QuestReward qci in newLocation.AvailableQuest.RewardItem)”, it gives me an error saying, “foreach statement cannot operate on variables of type ‘Engine.Item’ because ‘Engine.Item’ does not contain a public definition for ‘GetEnumerator’… I have three of these errors, and I’ve attempted to fix it myself, to no avail.

    How can I fix this, Scott?

    • Scott Lilly
      Scott Lilly June 27, 2016

      It sounds like you might have lines that say:
      foreach (QuestReward qci in newLocation.AvailableQuest.RewardItem)

      and they should say:
      foreach(QuestCompletionItem qci in newLocation.QuestAvailableHere.QuestCompletionItems)

      Those loops should be checking the items needed to complete the quest, instead of the quest’s reward item.

      If that doesn’t fix the problem, can you upload your SuperAdventure.cs file to Dropbox, or GitHub?

  13. Richard
    Richard September 8, 2016

    Hi the only issue im having right now is _currentMonster does not exist in the current context when i copied the super adventure.cs do you know what may have caused this?

    • Scott Lilly
      Scott Lilly September 8, 2016

      In SuperAdventure.cs, do you have this on line 18:

      private Monster _currentMonster;

      That line needs to be inside the curly braces for “public partial class SuperAdventure : Form”, but before the constructor “public SuperAdventure()”. If that line is there, check your Monster.cs class, and make sure it has “public class Monster” – if the “public” is missing, that would cause a problem.

      If those do not fix the problem, can you upload your solution to Dropbox, or GitHub (or, at least the Monster and SuperAdventure.cs files)? Then I can check them.

  14. Eve
    Eve September 19, 2016

    On line 84, we have ” btnNorth.Visible = (newLocation.LocationToNorth != null); ”
    Would you please explain how this line works in detail? Is it a simplified way to use bool?
    Thanks for any help!

    • Scott Lilly
      Scott Lilly September 20, 2016

      This is a way to calculate a boolean value (true or false).

      A similar line (using numbers, instead of boolean) could look like this:
      int total = (10 + 2) * 3;

      For that line, you would calculate everything on the right of the equal sign, and put the results (36) into the “total” variable.

      In the line you show, we want to calculate the result of the equation on the right “(newLocation.LocationToNorth != null)” and get a result of “true”, or “false”, and set “btnNorth.Visible” to the value of that result.

      The equation on the right might be clearer to understand if we replace some of the “code” with regular language. That would look like:

      newLocation.LocationToNorth is not (the "!=") empty ("null")

      “is not empty” is logically the same as “has a value”. So, we can also say:

      newLocation.LocationToNorth has a value

      So, if there is a value in LocationToNorth, the equation/statement will be “true”, and the button will be visible. If there is not a value in LocationToNorth, the equation will be false, and the button will not be visible.

      Boolean equations can be a little difficult to understand, but is important to learn. But, if you convert them from a math format to a “human language” format, they might be easier to understand.

      Please tell me if you still have a question.

  15. Eve
    Eve September 21, 2016

    I think I have a question because of the different usage of “newLocation.LocationToNorth != null”.

    if (newLocation.LocationToNorth != null)
    {
        // do something
    }

    In the above example, by writing ” newLocation.LocationToNorth != null “, we are assuming a situation that newLocation.LocationToNorth has a value, and we use an if statement to check if this situation is true or false.

    btnNorth.Visible = (newLocation.LocationToNorth != null);

    In this example, however, by writing ” newLocation.LocationToNorth != null “, we calculate the result of ” newLocation.LocationToNorth != null ” , get a result of “true”, or “false” (instead of just saying that “newLocation.LocationToNorth has a value” like the first example) , and set “btnNorth.Visible” to the value of that result.

    Is my guessing write? (I’m sorry if there are some unclear words in my description because I am not a native English speaker.)

    • Scott Lilly
      Scott Lilly September 21, 2016

      Yes. Because the equation returns a true or false, and we want to set the Visible property to the result of the equation (true or false), we can do this on one line – and not use an “if” statement.

  16. Eve
    Eve September 21, 2016

    Thank you! 🙂

  17. Adam
    Adam October 2, 2016

    Hey Scott,

    I’m getting two errors when I try and copy+paste the source code for SuperAdventure.

    Here’s what they say:

    ‘SuperAdventure’ does not contain a definition for ‘cboWeapons_SelectedIndexChanged’ and no extension ‘cboWeapons_SelectedIndexChanged’ accepting a first argument of type ‘SuperAdventure’ could be found (line 140)

    ‘SuperAdventure’ does not contain a definition for ‘SuperAdventure_Load’ and no extension method ‘SuperAdventure_Load’ accepting a first argument of type ‘SuperAdventure’ could be found (line 288)

    • Scott Lilly
      Scott Lilly October 2, 2016

      It sounds like you might have a couple extra eventhandlers. That could happen if you accidentally double-clicked on something while in the UI designer for the SuperAdventure screen.

      You should be able to edit the SuperAdventure.Designer.cs file, and either comment out those two lines (put double-slashes “//” at the front of them), or delete them. There is some more information on the Designer file, and eventhandlers, in Lesson 21.3.

      Please tell me if that does not fix the errors.

  18. Wout Janssen
    Wout Janssen November 18, 2016

    hello scott when im trying to copy the code for lesson 16.1 it gives about 80 errors.

    and deletes the work i did in lesson 12 adding the extra controls.

    • Scott Lilly
      Scott Lilly November 18, 2016

      Can you tell me what the error messages are (copy them here, or upload a screenshot someplace)? That will help identify the problem.

  19. Haukur
    Haukur November 25, 2016

    Hi Scott I named my game HaroldsEndeavour and when I copied you code I got one error It says ‘HaroldsEndeavour’ is a namespace but is used like a type. When I click on the error it takes me to program.cs and shows me that theres something wrong with this line  -> Application.Run(new HaroldsEndeavour());. sorry if this is a repost my other comment was just constantly awaiting moderation.

  20. Haykal
    Haykal November 25, 2016

    Hello Scott i have problem here
    MoveTo Does not exist in current context
    im I miss something?

Comments are closed.