RogueSharp V3 Tutorial – Simple Map Drawing

Next Tutorial Post – Player
Previous Tutorial Post – Color Palette

Goal

In this tutorial we’ll begin using the Map features of RogueSharp. We will create our own DungeonMap class that will start off very simple but give us lots of room for growth. We’ll also be drawing this to the map sub console and displaying it on the screen.

Creating the DungeonMap

When it comes to the Map class in RogueSharp it is designed to be generic so that it can be used in a variety of games. It has plenty of functionality for path-finding, determining field-of-view, selecting Cells and more.

What RogueSharp doesn’t have is any concept of doors, stairs, traps, bookcases, torches, or any other dungeon features that are specific to an individual game’s domain. These are really up to the game designer and not something that I feel should be baked into an engine.

With that said, we do really want all of these features in our game, so how can we add them and still use RogueSharp? The answer is we can create our own class that inherits all of the features of RougeSharp’s Map class but at the same time extends it with the features that are specific to our game.

Start by creating a new class in the Core folder called DungeonMap.cs and add the following code to it.

// Our custom DungeonMap class extends the base RogueSharp Map class
public class DungeonMap : Map
{
  // The Draw method will be called each time the map is updated
  // It will render all of the symbols/colors for each cell to the map sub console
  public void Draw( RLConsole mapConsole )
  {
    mapConsole.Clear();
    foreach ( Cell cell in GetAllCells() )
    {
      SetConsoleSymbolForCell( mapConsole, cell );
    }
  }

  private void SetConsoleSymbolForCell( RLConsole console, Cell cell )
  {
    // When we haven't explored a cell yet, we don't want to draw anything
    if ( !cell.IsExplored )
    {
      return;
    }

    // When a cell is currently in the field-of-view it should be drawn with ligher colors
    if ( IsInFov( cell.X, cell.Y ) )
    {
      // Choose the symbol to draw based on if the cell is walkable or not
      // '.' for floor and '#' for walls
      if ( cell.IsWalkable )
      {
        console.Set( cell.X, cell.Y, Colors.FloorFov, Colors.FloorBackgroundFov, '.' );
      }
      else
      {
        console.Set( cell.X, cell.Y, Colors.WallFov, Colors.WallBackgroundFov, '#' );
      }
    }
    // When a cell is outside of the field of view draw it with darker colors
    else
    {
      if ( cell.IsWalkable )
      {
        console.Set( cell.X, cell.Y, Colors.Floor, Colors.FloorBackground, '.' );
      }
      else
      {
        console.Set( cell.X, cell.Y, Colors.Wall, Colors.WallBackground, '#' );
      }
    }
  }
}

You’ll notice on line 7 that our DungeonMap class inherits from the base RogueSharp Map class. This means that we already get access to everything that Map can do!

The drawing code is pretty simple. We iterate through every Cell in the Map and then choose how to display it based on if it is explored, if it is walkable, and if it is in field-of-view or not.

At this point we don’t have any special map features that actually require us to have our own class. Don’t worry though, those features are only a few tutorials away.

Creating the MapGenerator

Now we need a class that will be responsible for generating interesting maps for us. Make a new folder called Systems and inside the folder create a new class called MapGenerator.cs

To start off with we’ll make one of the simplest maps. It will be all open floors with a wall around the entire edge of the map.

Add the following code to MapGenerator.cs

public class MapGenerator
{
  private readonly int _width;
  private readonly int _height;

  private readonly DungeonMap _map;

  // Constructing a new MapGenerator requires the dimensions of the maps it will create
  public MapGenerator( int width, int height )
  {
    _width = width;
    _height = height;
    _map = new DungeonMap();
  }

  // Generate a new map that is a simple open floor with walls around the outside
  public DungeonMap CreateMap()
  {
    // Initialize every cell in the map by
    // setting walkable, transparency, and explored to true
    _map.Initialize( _width, _height );
    foreach ( Cell cell in _map.GetAllCells() )
    {
      _map.SetCellProperties( cell.X, cell.Y, true, true, true );
    }

    // Set the first and last rows in the map to not be transparent or walkable
    foreach ( Cell cell in _map.GetCellsInRows( 0, _height - 1 ) )
    {
      _map.SetCellProperties( cell.X, cell.Y, false, false, true );
    }

    // Set the first and last columns in the map to not be transparent or walkable
    foreach ( Cell cell in _map.GetCellsInColumns( 0, _width - 1 ) )
    {
      _map.SetCellProperties( cell.X, cell.Y, false, false, true );
    }

    return _map;
  }
}

As with the DungeonMap, the MapGenerator also is not that interesting at this point but it gives us a solid foundation for adding features in the future.

Your project file structure should now look something like this:

ProjectStructureWithSystems

Project Structure

Hooking up the MapGenerator and Drawing

To start using our DungeonMap we need to first add it to Game.cs

public static DungeonMap DungeonMap { get; private set; }

Then in our Main() method of Game.cs we need to use our MapGenerator to create our DungeonMap.

MapGenerator mapGenerator = new MapGenerator( _mapWidth, _mapHeight );
DungeonMap = mapGenerator.CreateMap();

Now that the map is created all that is left is to draw it in our OnRootConsoleRender() method of Game.cs

DungeonMap.Draw( _mapConsole );

If everything worked when you run the game you should now see the map console has been replaced with this:

SimpleMapDrawing

Simple Map Drawing

If it didn’t work, don’t worry. The complete code so far can be found here:
https://bitbucket.org/FaronBracy/roguesharpv3tutorial/commits/tag/03BasicMap

Also, feel free to leave me comments if you have questions. I’ll do my best to answer them quickly.

Advertisements

25 thoughts on “RogueSharp V3 Tutorial – Simple Map Drawing

  1. Pingback: RogueSharp V3 Tutorial – Color Palette | Creating a Roguelike Game in C#

    1. Faron Bracy Post author

      Hello,
      The part of the series that you are looking for should be up by this weekend. In the meantime you could look at the code here -> http://bit.ly/1LaTUaW which shows how we handle moving the player in the completed code.

      Basically you need to put some code in OnRootConsoleUpdate() in Game.cs to handle keyPresses.

      RLKeyPress keyPress = _rootConsole.Keyboard.GetKeyPress();

      Then check if ( keyPress.Key == RLKey.Up ) and put your code in there to move the character up. Do the same for the other directions.

      Hope that will get you started until I get a chance to do better posts on it.

      Reply
      1. Nicholas Boullester

        I managed to get movement of the player, except he can move outside of the area and getCell and isWalkable don’t seem to be compatible with RLNET RLconsole _mapconsole which is where I’m getting stuck. definitely looking forward to this.

        now to figure out how to do something a bit less impressive in plain C++ console for my class assignment.

    2. Faron Bracy Post author

      Hi Nicholas,
      Sorry to hear that you are still struggling. If you post your code someplace I might be able to help you figure out what’s going wrong. You are correct that GetCell and IsWalkable are not features of RLNet. They are part of RogueSharp so if you are following this particular tutorial you’ll want to call them on the DungeonMap class which gets those features because it inherits from RougeSharp’s Map class.

      Reply
  2. Pingback: RogueSharp V3 Tutorial – Player | Creating a Roguelike Game in C#

  3. brettmichaelorr

    Loving the tutorial so far, but coming unstuck on something. My console window appears to have this massive padding around it, no matter what I set the width/height of the tiles to. I’m only doing the message log down the bottom, so there’s no other consoles being blitted on the top, sides etc. You can see the result here: http://imgur.com/a/rHIij and my code is here (for reference) http://pastebin.com/ycCLTxwx

    Do you know what might be the issue? Thanks again for the awesome tutorial!

    Reply
    1. Faron Bracy Post author

      Hello and thanks for visiting. Glad that you posted your code too as that helps a lot with troubleshooting. Unfortunately I don’t see anything wrong with the code. I loaded it up and tried it out to make sure I wasn’t missing anything and it came up like this -> http://screencast.com/t/UEqjOacOMl5 which I think is what you were hoping for. Have you custom modified MapGenerator.cs in any way? I really don’t think that’s the problem though because it’s clear that you set the screen width and height correctly.

      Sorry, I don’t have a good answer at this time. I’ll look into it further and see if I can come up with anything to help.

      Reply
      1. brettmichaelorr

        Hm. Thanks Faron. My code is exactly the same as yours in MapGenerator, and I was having the issue before I started. I tried a few different .NET framework targets (4.5, 4.5.1 and 4.5.2) and the same problem occurred.

        The only thing I can think, is that I have Windows displaying scaling on a non-default number (you know how you can tell Windows to adjust the size of text). It’s a long shot, but maybe that’s my issue – I’ll be able to try that tomorrow. Do you think that might be it?

        Thanks for the reply, I’m really liking the library and what it offers – far better than libtcod IMO, it’s a really nicely built engine.

      2. Faron Bracy Post author

        I was just starting to type a response to ask if you had display scaling on when you replied. I found this old issue with OpenTK and it appears it was not fixed. https://github.com/opentk/opentk/issues/47 I tried adjusting scaling on my own system and it worked as expected. Everything was zoomed in but I didn’t have any black padding.

        Another thing to try is to browse to your bin\debug folder manually and right click on the .exe that was produced and look at the compatibility settings. Try Disabling display scaling. http://screencast.com/t/I3tMvPqCkoYg

      3. brettmichaelorr

        Well I’ve tried your actual code (RogueSharpV3Tutorial.sln) and I’m still getting the display error: http://imgur.com/a/Kq1Ek
        Disabling scaling on the .exe didn’t fix it either, but turning my display down to the ‘Smallest’, which Windows apparently calls ‘100%’ (although I don’t think my home PC works like that), fixes the issue without any compatibility settings needed: http://imgur.com/a/VHcMJ

        So definitely a glitch in OpenTK, which means that, depending on what type of screen/display the end-user has, they might be fighting that black padding. Thanks for your help!

  4. Kalle Laatunen

    having issues with the class DungeonMap getting all kinds of errors mainly:
    “‘Dungeonmap’ does not contain a definition for ‘SetCellProperties’ and no extension method ‘SetCellProperties’ accepting a first argument of type ‘Dungeonmap’ could be found (are you missing a using directive or an assembly reference?)”
    and ”
    Inconsistent accessibility: return type ‘Dungeonmap’ is less accessible than method ‘MapGenerator.CreateMap()'”

    Reply
    1. Faron Bracy Post author

      Sorry that you are getting errors. Could you post a link to your code? Without seeing the code it will be hard for me to debug.
      It’s possible that your DungeonMap class is not public and that it does not inherit from Map
      Make sure your class is defined as:
      public class DungeonMap : Map
      If that doesn’t help I’m happy to look at your code further if you provide a link.

      Reply
      1. Kalle Laatunen

        Actually i suddenly got the errors to 1:
        ‘Dungeonmap’ does not contain a definition for ‘Draw’ and no extension method ‘Draw’ accepting a first argument of type ‘Dungeonmap’ could be found (are you missing a using directive or an assembly reference?)

  5. SKylan Lew

    Hey Faron,

    I didn’t realize coding a RL would be so easy, using RogueSharp and RLNET. I’m having a problem, when I run my code at the end of this section of the tutorial, I get

    An unhandled exception of type ‘System.TypeLoadException’ occurred in mscorlib.dll

    Additional information: Could not load type ‘RogueSharp.Map’ from assembly ‘RogueSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null’.

    The tutorial was working 100% up until the end of this section
    Game.cs https://gist.github.com/doublespoiler/141442413709630d9e3f50a2b9bb92b6
    DungeonMap.cs https://gist.github.com/doublespoiler/9bf04014971bccbd6f0ba1408b72e72c
    MapGenerator.cs https://gist.github.com/doublespoiler/ec6b255a2d1a864b0a54c0b4ad6f2529

    Reply
    1. Faron Bracy Post author

      Hello and thank you for visiting,

      If you’ve been following the tutorial series in order then this is first section where we’ve actually used functionality from the RougeSharp library and not just RLNET. The code that you shared looks okay to me.

      The error that you are experiencing usually means that the library cannot be found or that the type is missing from the library. Since RogueSharp has had the Map type in it since Version 1, I don’t think it could be that the type is missing. I would recommend going to NuGet package manager and removing and re-adding the RogueSharp NuGet package to the project. If you are still having issues after doing that please let me know. It would be helpful if I could download your entire solution and try it out here to help diagnose the issues.

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s