RogueSharp V3 Tutorial – Multiple Consoles

Next Tutorial Post – Color Palette
Previous Tutorial Post – Creating the Project

Goal

In this tutorial we’ll create sub consoles for each part of our game window and Blit them to the root console.

FourConsoles

Four Sub Consoles

Sub Consoles

Our game is more than a map. It will also have areas for the inventory, player statistics, and a message log. We could just draw all these directly to the root console but it will be better to draw each to their own console and Blit them to the root in their correct positions.

Defining Console Dimensions

First we need to define the width and height of each of our sub-consoles and declare each RLConsole. At the top of Game.cs add the following code:

public static class Game
{
  // The screen height and width are in number of tiles
  private static readonly int _screenWidth = 100;
  private static readonly int _screenHeight = 70;
  private static RLRootConsole _rootConsole;

  // The map console takes up most of the screen and is where the map will be drawn
  private static readonly int _mapWidth = 80;
  private static readonly int _mapHeight = 48;
  private static RLConsole _mapConsole;

  // Below the map console is the message console which displays attack rolls and other information
  private static readonly int _messageWidth = 80;
  private static readonly int _messageHeight = 11;
  private static RLConsole _messageConsole;

  // The stat console is to the right of the map and display player and monster stats
  private static readonly int _statWidth = 20;
  private static readonly int _statHeight = 70;
  private static RLConsole _statConsole;

  // Above the map is the inventory console which shows the players equipment, abilities, and items
  private static readonly int _inventoryWidth = 80;
  private static readonly int _inventoryHeight = 11;
  private static RLConsole _inventoryConsole;
  
  // ... additional code omitted
}

Instantiate the Consoles

Now we need to new up our four consoles with the widths and heights that we defined. In our Main() just after the line where we make a new RLRootConsole add the following code:

public static void Main()
{
  // ... previous code omitted
  // After the line that starts _rootConsole = new RLRootConsole( ...  

  // Initialize the sub consoles that we will Blit to the root console
  _mapConsole = new RLConsole( _mapWidth, _mapHeight );
  _messageConsole = new RLConsole( _messageWidth, _messageHeight );
  _statConsole = new RLConsole( _statWidth, _statHeight );
  _inventoryConsole = new RLConsole( _inventoryWidth, _inventoryHeight );
  
  // ... additional code omitted
}

Set Background Color and Label

Next we’ll want to set the background color of each console and put a label on them so that we can verify that they are in the correct positions when we Blit them to the Root console. In OnRootConsoleUpdate()  replace _rootConsole.Print( 10, 10, “It worked!”, RLColor.White ); with the following code:

private static void OnRootConsoleUpdate( object sender, UpdateEventArgs e )
{
  // Set background color and text for each console 
  // so that we can verify they are in the correct positions
  _mapConsole.SetBackColor( 0, 0, _mapWidth, _mapHeight, RLColor.Black );
  _mapConsole.Print( 1, 1, "Map", RLColor.White );  

  _messageConsole.SetBackColor( 0, 0, _messageWidth, _messageHeight, RLColor.Gray );
  _messageConsole.Print( 1, 1, "Messages", RLColor.White );

  _statConsole.SetBackColor( 0, 0, _statWidth, _statHeight, RLColor.Brown );
  _statConsole.Print( 1, 1, "Stats", RLColor.White );

  _inventoryConsole.SetBackColor( 0, 0, _inventoryWidth, _inventoryHeight, RLColor.Cyan );
  _inventoryConsole.Print( 1, 1, "Inventory", RLColor.White );
}

Blit and Render

The final step we’ll need to take is to update OnRootConsoleRender() to Blit each of our consoles to the root console in the correct positions. The RLNET method we will use is RLConsole.Blit which takes several parameters.

  • A source console
  • The X and Y position of the top left corner of a rectangular area from the source
  • The width and height of the rectangular area from the source that we will be Blitting
  • A destination console to Blit to
  • The X and Y position of the top left corner of where we will Blit to in the destination console
private static void OnRootConsoleRender( object sender, UpdateEventArgs e )
{
  // Blit the sub consoles to the root console in the correct locations
  RLConsole.Blit( _mapConsole, 0, 0, _mapWidth, _mapHeight, 
    _rootConsole, 0, _inventoryHeight );
  RLConsole.Blit( _statConsole, 0, 0, _statWidth, _statHeight, 
    _rootConsole, _mapWidth, 0 );
  RLConsole.Blit( _messageConsole, 0, 0, _messageWidth, _messageHeight, 
    _rootConsole, 0, _screenHeight - _messageHeight );
  RLConsole.Blit( _inventoryConsole, 0, 0, _inventoryWidth, _inventoryHeight, 
    _rootConsole, 0, 0 );

  // Tell RLNET to draw the console that we set
  _rootConsole.Draw();
}

And that’s it! If you run the program now you should see output similar to the screenshot at the beginning of this post.

Complete code for this post – https://bitbucket.org/FaronBracy/roguesharpv3tutorial/commits/tag/01SetupConsoles

Closing thoughts

So far we haven’t used RogueSharp at all. I think it is necessary to do some of these basic setup tasks to pave the way for the future. Don’t worry though we’ll be getting into RogueSharp functionality shortly.

Advertisements

9 thoughts on “RogueSharp V3 Tutorial – Multiple Consoles

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

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

  3. Radizmo

    Great tutorials. Appreciate your work.

    How do you handle multiple lines of text to a console? I could create some sort of function but would like your input on your approach.

    Thanks.

    Reply
    1. Faron Bracy Post author

      Hello,
      Sorry I didn’t get back with you sooner, I was away for Easter. What I did to make a message log with multiple lines of text is to make a MessageLog system to handle it. You can see the code here -> http://bit.ly/1RAgYQ7

      Basically you call the Add( string message ) method on it to add a new message to the log. It keeps the most recent 9 (adjustable) messages on the queue. When you call Draw() it prints them to the console by iterating over each message on the queue and incrementing the y position to draw it.

      I believe RLNET also has a bunch of overloads of it’s Print method on the console. Some over the overloads allow you to wrap text naturally. So you could just specify a paragraph of text and it will automatically wrap where appropriate.

      Hope this helps,
      Faron

      Reply
      1. Radizmo

        Thanks Faron and Happy belated Easter! :).

        I like the idea of the queue and the approach. Appreciate the reply and keep up the tutorials.

  4. Radizmo

    Ok, so I tweaked the message log a little for 2 reasons: 1) the code was deleting my background console color and 2) I wanted to make it so the “old” lines were shown in light gray and the new line in white instead of all white. here is the code:

    using System.Collections.Generic;
    using System.Linq;

    using RLNET;

    namespace TOARL
    {
    public class MessageLog
    {
    private readonly Queue _lines;
    private RLColor color;

    public MessageLog(RLColor backgroundColor)
    {
    _lines = new Queue();
    color = backgroundColor;
    }

    public void Add(string message)
    {
    _lines.Enqueue(message);
    if (_lines.Count > 9)
    {
    _lines.Dequeue();
    }
    }

    public void Draw(RLConsole console)
    {
    console.Clear();
    console.SetBackColor(0, 0, console.Width, console.Height, color);
    string[] lines = _lines.ToArray();
    if (lines.Length==0)
    return;

    int i = 0;
    for (i = 0; i < lines.Count()-1; i++)
    {
    console.Print(1, i + 1, lines[i], RLColor.LightGray);
    }
    console.Print(1, i + 1, lines[i], RLColor.White);
    }

    }
    }

    Reply
  5. FroggEater

    Hey! Awesome tutorial by the way, I just get an exception with RLNet.dll, “System.ArgumentNullException”, the value cannot be null. It is around the first Blit line, or so it says. An idea about where it could come from?

    Thanks

    Reply
    1. Faron Bracy Post author

      Hi,
      Thanks for visiting! If it’s with the first Blit then it is probably the _mapConsole or the _rootConsole. Make sure that you “new” them up in your Main() function. If that’s still not working please post your code someplace and I can take a look at it. You could also compare it to the completed code here -> https://bitbucket.org/FaronBracy/roguesharpv3tutorial/src/e019fab2ff2091b919519a9a79c0760d0182f080/RogueSharpV3Tutorial/Game.cs?at=01SetupConsoles&fileviewer=file-view-default

      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