Tuesday, August 6, 2013

Bunny Hunters Online: The First Image

My college degree is both Computer Science and Film Production, and we have a rule in film.  Its called "the rule of ten."

Every dollar you spend preparing for your project, in what is called "pre-production" in film, saves ten dollars you would otherwise have to expend in shooting the movie or  what we call "production."
Furthermore, every dollar you spend in production, saves you ten dollars you would otherwise have to spend in editing and special effects and such, what is called "post-production."

Proper, efficient movie making is front-loaded.  You spend the most time where you get the most return, which is in that preparation before a frame of film (or video, these days) is shot.  Game making has very similar economics.  Preparation and planning are key.  For that reason, we have spent a number of blogs setting up the development environment for our game.  There will be a bit more fiddling with it a bit further on, but for now, we are finally ready to actually get something on screen.

To begin with, we are going to put the title screen up so we can see it display.  Although deeper into the project we will be using a scene graph engine (more on that later), for now we can just use Monogame directly.

If you look at the BHO Windows Store project generated by VisualStudio, you will see that there are two c-sharp files already generated for you.  Program.cs and Game.cs.  


Program.cs is the "main" file.  It is the one that invoked by the operating system to start your game.  Although there will be a Program.cs file in every platform project we create for BHO, it may contain different code depending on the needs of the particular platform.  It is the "glue" that connects Monogame code to the platform.  For the most part, we are going to leave that as it is.

The second file, Game.cs, is the actual Monogame game.  It will be exactly the same across all of the platforms BHO will be ported to.  In fact, there will be only one real Game.cs file which every platform's project will link to, just like the assets.

Game.cs begins as an empty shell of a program. All it does is display the blue screen that we saw when we tested the project in the previous blog.  In this blog it will be modified to display the title screen.  As this is not intended to be a full course in C# programming, I am not going to explain all the syntax but just call out the key areas that need to be changed to create BHO.

In order to display the title screen, we need the title screen image.  In Monogame images are stored in a Texture2D object.  At the top of the Game class in Game.cs there is a small global variables block that looks like this:

 public class Game1 : Game {
        GraphicsDeviceManager _graphics;        SpriteBatch _spriteBatch;

Add a Texture2D object to it, so it looks like this:

public class Game1 : Game{
        GraphicsDeviceManager _graphics;        SpriteBatch _spriteBatch;
        Texture2D startScreen;

All the art for BHO was produced for a game screen that is 800 pixels wide and 600 pixels tall.  Monogame needs to be instructed to set the display window to that resolution.  This can be done in the constructor method of Game.cs.  It currently looks like this:

 public Game1() {
      _graphics = new GraphicsDeviceManager(this);
      Content.RootDirectory = "Content";
 }

Adding these two lines sets the height and the width:

public Game1()
{
      _graphics = new GraphicsDeviceManager(this);
      Content.RootDirectory = "Content";
      _graphics.PreferredBackBufferHeight = 600;
      _graphics.PreferredBackBufferWidth = 800;
}

The next task is to load the title screen.  This is done in the  LoadContent method.  As generated, it looks like this:


protected override void LoadContent(){
      // Create a new SpriteBatch, which can be used to draw textures.
      _spriteBatch = new SpriteBatch(GraphicsDevice);
      // TODO: use this.Content to load your game content here
   
}

The template already has a place marked in comments for us to add the load code.  Adding this will load the title screen:


protected override void LoadContent(){
      // Create a new SpriteBatch, which can be used to draw textures.
      _spriteBatch = new SpriteBatch(GraphicsDevice);
      // TODO: use this.Content to load your game content here
      startScreen = Content.Load<Texture2D>("intro");
}

The final step is to display the title screen.  Monogame implemenst a classic Update/Render game loop. Every frame, first the game's Update method is called to calculate the new game state and then the Render method is called to display it.  For the moment, there is no game state so Update can be ignored.  The render method however must have the code to draw the title screen added to it.  It currently looks like this:


protected override void Draw(GameTime gameTime){
      GraphicsDevice.Clear(Color.CornflowerBlue);
         
      // TODO: Add your drawing code here
      base.Draw(gameTime);
}

Once again the template has already marked where the code must be added.  Add the following code between the TODO and base.Draw(gameTime) to draw the screen:


protected override void Draw(GameTime gameTime){
      GraphicsDevice.Clear(Color.CornflowerBlue);
          
      // TODO: Add your drawing code here
      _spriteBatch.Begin();
      _spriteBatch.Draw(startScreen, new Vector2(0, 0), Color.White);
      _spriteBatch.End();
      base.Draw(gameTime);
}

Build and run the project.  You should see the grey screen with the icon in the center for a moment, followed by this:


To quote Kermit the frog, "Yayyyyy!"   You have the first screen of the game being displayed.  Take a moment to pat yourself on the back.  But it isn't done.  This has led directly to our first refactor.

Refactoring is an idea that has been around software practically since the beginning, but was formalized as part of the Agile development lexicon.   This project is being done is steps, much like an agile project.  In an agile project you work on one thing, get it working, and then stop and clean it up before going on to the next thing.  This cleanup is called refactoring.  This first refactor is some additional organization to make going to other platforms easier.

As I mentioned above, the Game1.cs class, and all the classes that will be written later on, will be shared between projects.  However, if you look at the top of the Game1.cs file you will see this:

namespace BHO_Windows_Store

This is because every project has a default name space that it creates new classes in and, when a project is initially created, it is based on the name of the project.  This name however is misleading.  We want this code to be shared between all BHO projects.  So change that name space to just BHO like so.

namespace BHO

If you try to build the code now, you will get the following build error:

Error 2 The type or namespace name 'Game1' could not be found (are you missing a using directive or an assembly reference?) Z:\Google Drive\Projects\Cross Platform\BHO\Bunny Hunters Online\BHO Windows Store\Program.cs 15 74 BHO Windows Store

This is because Program.cs needs to use Game.cs, but they are no longer in the same namespace.  While this could be fixed by changing the namespace of Program.cs, that would be wrong because, again as mentioned above, Program.cs is specific to the BHO Windows Store project.

Instead, this is solved by adding a using statement to Program.cs.  Right now, the top of Program.cs looks like:

using System;
namespace BHO_Windows_Store;


Add using BHO; so it looks like this:

using System;
using BHO;
namespace BHO_Windows_Store

Build and run it again and you should get the title screen once more.  

Right now, if we created a new class, it would get the namespace BHO_Windows_Store and we would have to edit it.  This could get tedious.  Since all the code to be written from here out will be in the BHO namespace, it would be convenient to change the default.  This is easily done in VS2012.

Start by right clicking the BHO Windows Store project and select "properties" from the pop up context menu.




This will open the properties editor in the main edit window.  Click on Applications and you will see this form.


In the middle there is a field marked "Default namespace:"  that  contains BHO_Windows_Store.  Change that field to just BHO, save and close the properties editor.  Now all new classes will be created in the BHO namespace.

The last bit of refactoring is just to create a folder called "shared source" and move Game1.cs into it.  All new game code will go in this directory too in order to make it easy to move to a shared location later.




==
Edit Important:
On further experimentation, I  have determined that the linked source directory strategy originally given here doesn't quite work the way I'd hoped.  Although the initial Game1.cs file does end up in the externally linked directory, new classes you create from inside of VS2012 does not. Accordingly I am removing this step.  We will do it later after the source base for Windows Store is complete.
==

Voilla!  You are all set up to start some serious cross platform development!

Next blog will introduce the TwoDEngine scenegraph, and game state management with a simple Finite State Machine.




No comments:

Post a Comment