Tuesday, May 31, 2011

XNA Game Design: Mouse Input (part 1)

Implementation for cursor input is a bit more complex, but still very similar to the keyboard's. If the keyboard input is just a case of checking boolean values of keyboard keys, mouse input is more like Cartesian graphing. Just like the keyboard, the mouse has it's own status property called MouseStateMouseState contains X and Y coordinates that are relative to the upper-left origin of the game window.

If you've played with the empty game window before, you might have noticed the mouse cursor disappears when moved onto the game window. This is a default property of XNA Windows games, and can be changed in the Game1 class with the line IsMouseVisible = true;.still, this does not provide us with a custom cursor graphic, and the mouse will still not be able to interact with our game.

Like the Keyboard class, XNA provides a Mouse class which has it's own GetState(method. However, the X and Y integers contained in the mousestate returned by Mouse.GetState() will contain negative values if they are above or to the left of the origin, and will return values greater than the width and height of the game window if they exceed the Game Window's boundaries.

So why is this bad?

Lets say you have a game where the character is the mouse cursor, and is being chased by angry monsters that bounce around the screen, and the goal of the game is to last as long as possible. If this problem isn't fixed, the player could move their cursor off the screen, and walk away. Effectively the player's coordinates would be outside the confines the game window, and the enemies would never reach the player.
Your game should not be broken by the player moving the cursor off the screen! As this cheesy photoshop shows, negative cursor coordinates (as well as coordinate beyond the confines of the game window) beat the game's logic, and the player can successfully cheat. This is bad!

The Cursor class we will be creating is different from the XNA Mouse class for two reasons. Of course the XNA Mouse class is protected and immutable, but more importantly it contains all the information about the actual onscreen mouse relative to our game window. We need this metadata to handle certain interactions with the Windows shell.

As such, the update and draw methods we will be implementing will focus more on the following two aspects:
  • Coordinates that are conducive to our game window.
  • A custom cursor texture that can be easily changed depending on the desired scenario.

Alright, lets get this general framework going.
static class Cursor
    //Current state of the Mouse
    public static MouseState State = Mouse.GetState();
    //Previous state of the Mouse
    public static MouseState Prevstate;
    //Graphic used to represent the cursor
    public static Texture2D Texture;
    //value representing mouse coordinates
    public static Vector2 Pos;

    public static void Update()
        PrevState = State;
        State = Mouse.GetState();
        Pos = new Vector2((float) state.X, (float) state.Y);

    public static void Draw(Spritebatch spritebatch)
        //We'll write this code later

Look familiar? It is essentially the same method as the keyboard. Still, this doesn't address the aforementioned problem, nor will it allow us to draw our special cursor graphic.

As you can see, we also added two new properties to the class These are Pos and Texture.

Again, these properties are public and static because we will not be making instances of Cursor, and because we want their access to be commonplace throughout the game. Those two types however, Texture2D and Vector2, are XNA framework types. Texture2D represents a two-dimensional image (of which we can assign a raster graphic, which we will be do in the next lesson) and Vector2; a set of two float values that can be used to identify a vector, or in our case, the Cartesian coordinates of the mouse. The reason we will be using Vector2 rather than Point (similar to a vector2, but composed of two integers instead of two floats) to represent our mouse cursor will be explained later, but you are right in thinking that such a datatype would be more conducive to representing the Cartesian coordinates of our cursor. You were thinking that, right?

Texture and Pos will both be implemented in the next lesson, and we will also tie-in our completed Input class into our main loop, giving our game the input it needs.

Yesterday's Homework Solution: In order to create a method that can tell the difference between holding a button down and pushing a button, we would need to check the previous state of the keyboard using our PrevState  property. Like before, we want the method to be static so it's implementation is ubiquitous.

    public static bool IsKeyTrigger(Keys k) //returns true if key is triggered at one moment. returns false if held.
        if ((State.IsKeyDown(k)) && !(PrevState.IsKeyDown(k))) return true;
        else return false;

Because State would return true so long as the key is pressed down, PrevState would only return false at the first moment the key is pressed. The next time Input.Update() is run, this method will begin returning false until the key is released and PrevState reset to false.

Homework: This lesson introduced three new XNA classes; Texture2DVector2 and Point. All three are quite useful, and we will be seeing them many more times in the future. Another class we will see frequently is the Rectangle class. Rectangle object, as you can imagine, represents a 2D space with an (X, Y) origin, a width and height.

Given a Rectangle r, return a boolean value indicating whether the cursor is within the confines of r. For reference, here are the members of rectangle, vector2 and point.

Monday, May 30, 2011

XNA Game Design: Keyboard Input

A windows game can take three types of input. These are from the Keyboard, Mouse and Xbox 360 game controller (Gamepad). This guide will not (for now) cover input from the Gamepad. This chapter in particular will focus on Keyboard input.

Input with the keyboard is relatively simple, and at this juncture you may choose to integrate keyboard input directly into the Game1 class, or making your own separate Input class to work with the Game1 class. This guide will be making it into a separate class, and therefore will require a separate .cs file.

To create a new class, right click on the Tutorial Project Icon in the Solution Explorer pane, and follow the command tree to Add, Class..., and then in the new window select Class and name it Input.cs

Remember this. We will be creating many, many more classes from here on out. This will be the only time class creation will be explicitly written out.

As far as I've seen, there doesn't seem to be an effective way of doing this. Every time you create a new class you need to re-append the necessary using statements used in all other classes. If anyone knows a way to make Visual Studio add them by default, send me a message.

These can be found already listed out at the top of the Game1 class, but I'll list them here as well. Just copy and past the following to continue using our favorite XNA framework in all our classes.

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

Keyboard input is handled through the Keyboard class. The Keyboard class has a method called GetState. GetState returns the status of the keyboard in the form of a KeyBoardState object. KeyboardState objects contain the methods that check whether certain keys are pressed (IsKeyDown and IsKeyUp).

If your brain has since shut off in those few lines, I don't blame you. Overall however it's not as painful as it seems. Let's get started, shall we?

Our Input class will need to be static, and subsequently most other properties will be static as well. We Really just need an update method and two KeyBoardState properties.

static class Input
    //current state of the keyboard
    public static KeyboardState State Keyboard.GetState();
    //previous state of the keyboard
    static KeyboardState PrevState; 

    public static void Update()
        PrevState = State;
        State = Keyboard.GetState();

This simple code effectively gets the job done. Because the class is static, it can be referenced globally throughout the program (and something as ubiquitous as game input should be globally available to all components of the program). We're not making instances of Input, and we're presuming the player has only one keyboard hooked up. It all works.

Now an observant person would look at this code and ask, "Why do we have two KeyboardState properties if we would only want to use one?"  We need the PrevState property mostly for making methods down the line that handle more complex input questions that something like Input.State.IsKeyDown() can't handle.

Speaking of which, that's the homework. Tomorrow's lesson will cover Mouse input, which is considerably more difficult.

Yesterday's Homework Solution: In the Draw method, the first line of code should read
Every time the draw method is called, this line of code erases everything currently on the screen and replaces with our friendly Cornflower Blue color. Changing .CornflowerBlue to .Black will make the screen default to black. Microsoft has provided a number of public static color constants for us to work with. More on all this at a later chapter.

Homework: a method like Input.State.IsKeyDown() can 't tell the difference between whether a key is being pressed repeatedly, or being held down (truthfully, it just tells if a key is being pressed down in the first place). Design a method to return true if a key is being pressed and has not been held down.

Sunday, May 29, 2011

XNA Game Design: The Basics

This course will focus more on making a windows game as opposed to an XBOX or Windows Phone game. For now, open Visual C# and select New Project. You should be given a set of a few options to pick from in the middle panel. Scroll down and find Windows Game (4.0).

A lot of options here. For now, we will use this tutorial project to teach the fundamentals. Don't be expecting to convert this simple project into your awesome game at some point.

Name your project Tutorial and save it wherever you like. If none of this has shown up, XNA game studio may not have been installed correctly (or it might not be installed at all). Make sure you installed all the components correctly if this is the case.

The first thing your project should open is a class titled Game1 . This is your main game loop, and is effectively the first thing that is run when your code starts (actually it's the second, but I'll get into that at the end). Lets look at the methods contained in Game1 :

  • Initialize() - base.initialize() will initialize all the components of the parent class (see below).
  • LoadContent() - Called at the game's start to preload any necessary content
  • UnloadContent() - Called at the game's end to unload all content (no touchy)
  • Update(GameTime gameTime) - all updates to the game's internal logic should be done from this method.
  • Draw(GameTime gameTime) - all calls to change the game's drawn sprites should come form here.

Also note that Game1 extends Microsoft.Xna.Framework.Game , and all of these methods are overrides of methods contained in the parent class (right click the "Game" in Microsoft.Xna.Framework.Game and select Go To Definition to see them all. Doing this with any class will open that class in a new tab).

I'm going to digress here for a moment. Effectively, any videogame needs to perform three critical operations to be considered a videogame.

Think about it; so long as it performs this loop a few dozen times a second, this is the simplest program architecture all videogames are composed of.

Our Game1 class contains two of these methods (Update() and  Draw()), and in fact, both of them don't contain any content in them. They're just explicitly stated- empty called methods (well, they're not fully empty, but you get my drift).

As you can tell, we got a lot of work to do. Our next lesson will cover making a class to procure keyboard input. Before we end today however, go to the title bar and select Debug, and then select Start Debugging. If you didn't change anything just yet, the solution should build and a new window should pop up.

Cornflower Blue. Classy.

At least we have a window showing up. Microsoft completed most of our boilerplate code for us, and the nastier bits we would normally have to slog through are taken care of further up the class hierarchy (we're not allowed to see what's going on under the hood, so for now assume it operates on principles of magic and unicorns).

HOMEWORK: Find where in the Game1 code the background is set to the light blue, and change it to black. Save and exit.

Saturday, May 28, 2011

XNA Game Design: Introduction

So... You want to make a videogame, eh? Good luck.

The first step to making a videogame is the hardest; being realistic about the process. On your own, you will not make a triple-A title capable of competing with Half-Life or any quality title currently out there. Chances are, it may not be very good, and will never make a dime.

But that's because you are not working for a professional company, and you probably have very little to no programming experience.

Which is why a certain line will be drawn here; You must have knowledge of a simple object-oriented programming to proceed. You don't have to know C#, but you should at least be mildly familiar with Java, Python, or some other related programming language (if you know Java, you know C#. Trust me). Familiarity with simple Algebra 2 topics or concurrent enrollment in a computer science class should suffice at a bare minimum. Knowledge of simple trigonometry wouldn't hurt.

I hate to turn away a whole bunch of wide eyed eager faces, but that's the truth. I can't teach you to read the code. I can however, encourage you to take more math and science courses, and enjoy your childhood while you can. Keep reading this blog too- that can't hurt.

This course will be using Microsoft visual C# 2010 express alongside the Microsoft XNA game studio 4.0 libraries.  This guide will cover the basics of designing a simple 2D game, and teaching good programming practices to keep your game development process neat, tidy and object oriented.

It will also cover the more frustrating aspects of starting of your adventure in XNA game design, and will give you the instructions on how to escape these pit falls.

> Download Microsoft Visual C# 2010 Express
> Download Microsoft XNA Game Studio 4.0

Install, and tomorrow we will begin covering the basics.