Skip to content

Basic Monogame Guide

Glen edited this page Sep 30, 2017 · 8 revisions

The following is to get started with EmptyKeys with MonoGame


Folder structure/setup

To begin with, it's assumed you have Visual Studio and the latest version of MonoGame for Visual Studio installed.

  1. Create a solution, a MonoGame project, and a WPF User Control Library project.

  2. Add a folder called UI to the MonoGame project.

  3. In Tools -> NuGet Package Manager -> Manage NuGet Packages for Solution...:

    • Install EmptyKeysUI_MonoGame in to the MonoGame project.
    • Install EmptyKeysUI_Generator in to the WPF UCL project.
  4. In the Properties of the WPF UCL project, go to Build Events and add the following to Post-Build...

Replace <MonoGame Game> with the name of your project.

CD "$(SolutionDir)packages\EmptyKeysUI_Generator*\tools"

ekUIGen.exe -i="$(ProjectDir)\" -o="$(ProjectDir)..\<MonoGame Game>\UI" -oa="$(ProjectDir)..\<MonoGame Game>\Content" -rm=MonoGame /generate-bindings

Configure UI

  1. In the WPF UCL project, add the EmptyKeys Designer to your namespaces

    • Open the only XAML file in text editor mode. In the root node, add the following namespace:
    • xmlns:ek="clr-namespace:EmptyKeys.UserInterface.Designer;assembly=EmptyKeys.UserInterface.Designer"
  2. Change the root element from UserControl to ek:UIRoot and rename the File to BasicUI.xaml

    • You can safely delete the child .CS file.
  3. Add some basic XAML to the control like this: <TextBlock Text="Hello World" Grid.Row="0" />

  4. Build the WPF UCL project. Your output should look like this:

========== Build: 1 succeeded or up-to-date, 0 failed, 2 skipped, Completed at 3/31/2015 6:41:56 PM ==========

  • If you see errors, double check your Post-Build events and make sure everything is correct.
  1. In the MonoGame project, right click the UI folder and add the generated class(es).

    • Again, if you don't see any generated files, double-check your Post-Build events and build Output.

Create a font resource

  1. Open the MonoGame Pipeline Tool, and create a new Sprite Font named MyFont.

    • The Pipeline tool may be located in C:\Program Files (x86)\MSBuild\MonoGame\v3.0\Tools or a similar folder.
    • Once the tool is opened, open the Content.mgcb file in MonoGame Project\Content, where MonoGame Project is the folder of your primary MonoGame project.
    • In the Project section, right click the Content node and click Add -> New Item...
    • Pick the SpriteFont Description (.spritefont) option, and name it MyFont unless you would like to call it something more descriptive.
    • Save the content, close the tool, and make sure Visual Studio has loaded in any changes that it detects.
  2. Add the new Sprite Font to your project as Content

    • Right click on the Content folder in your MonoGame project, and click Add Item...
    • Navigate to your Content folder, make sure All Files is selected, then click on the .spritefont file that you made. Click on the down arrow on the Add button, and click Add As Link.
    • On the properties for the newly added item in your Solution Explorer, make sure the Build Action is set to Content and the Copy to Output Directory setting is set to Copy if newer.
  3. Edit the .spritefont file to your preference (Optional)

    • Open the .spritefont file in your favorite text editor (Visual Studio will work fine), and change the properties as you see fit. By default, you'll be provided with a 12-point-size Arial font.

Bringing it all together

  1. Under Game1.cs in the MonoGame project add the following lines:
public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        
        private EmptyKeys.UserInterface.Generated.BasicUI basicUI;
        private int nativeScreenWidth;
        private int nativeScreenHeight;
        public Client()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.PreparingDeviceSettings += graphics_PreparingDeviceSettings;
            graphics.DeviceCreated += graphics_DeviceCreated;
        }
        
        void graphics_PreparingDeviceSettings(object sender, PreparingDeviceSettingsEventArgs e)
        {
            nativeScreenWidth = graphics.PreferredBackBufferWidth;
            nativeScreenHeight = graphics.PreferredBackBufferHeight;
            
            // Or any other resolution
            graphics.PreferredBackBufferWidth = 1280;
            graphics.PreferredBackBufferHeight = 720;
            graphics.PreferMultiSampling = true;
            graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8;
        }
        
        void graphics_DeviceCreated(object sender, System.EventArgs e)
        {
            Engine engine = new MonoGameEngine(GraphicsDevice, nativeScreenWidth, nativeScreenHeight);
        }
        // ... means we skipped some code for brevity, do not remove or change the code that would otherwise be there
        ...
        protected override void LoadContent()
        {
            SpriteFont font = Content.Load<SpriteFont>("MyFont");
            EmptyKeys.UserInterface.FontManager.DefaultFont = EmptyKeys.UserInterface.Engine.Instance.Renderer.CreateFont(font);
            
            Viewport viewport = GraphicsDevice.Viewport;
            basicUI = new BasicUI(viewport.Width, viewport.Height);
            
            FontManager.Instance.LoadFonts(Content);
            // Load the images and sounds if necessary
            //ImageManager.Instance.LoadImages(Content);
            //SoundManager.Instance.LoadSounds(Content);
            
            // Replace the escape to close command from the update method
            RelayCommand command = new RelayCommand(new Action<object>(ExitEvent));
            KeyBinding keyBinding = new KeyBinding(command, KeyCode.Escape, ModifierKeys.None);
            basicUI.InputBindings.Add(keyBinding);
        }
        
        private void ExitEvent(object obj)
        {
            Exit();
        }
        ...
        protected override void Update(GameTime gameTime)
        {
            // remove the escape to exit line and add the following
            basicUI.UpdateInput(gameTime.ElapsedGameTime.Milliseconds);
            basicUI.UpdateLayout(gameTime.ElapsedGameTime.Milliseconds);
            base.Update(gameTime);
        }
        
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            basicUI.Draw(gameTime.ElapsedGameTime.TotalMilliseconds);
            base.Draw(gameTime);
        }
  1. Now your project should run with a hello world statement on a gray screen.

    Gray screen

    • To enable the UI elements to be transparent

    Transparent background,

    set the Background field to Transparent like so

<ek:UIRoot 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:ek="clr-namespace:EmptyKeys.UserInterface.Designer;assembly=EmptyKeys.UserInterface.Designer" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300" Background="Transparent">

For any help with getting your project setup see these examples, for more or come to the forums