Building a 2D RPG in XNA: Part 1.2 – Building the basic skeleton

January 20th, 2010

This tutorial is in continuation from Building a 2D RPG in XNA: Part 1.1

Handling the player input

In part 1.1 I used some code I had previously written for ease and speed of getting the basics set up, and I will be doing the same for the handling of player input. You might want to read up on my logic and method for the code below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    class KeyboardH
{
KeyboardState PreviousState;
KeyboardState CurrentState;

public int Init()
{
PreviousState = Keyboard.GetState();
CurrentState = Keyboard.GetState();

return 0;
}

public int UpdateKeyboard()
{
PreviousState = CurrentState;
CurrentState = Keyboard.GetState();

return 0;
}

public bool KeyPressed(Keys k)
{
return ((CurrentState.IsKeyDown(k)) && (PreviousState.IsKeyUp(k)));
}
public bool KeyDown(Keys k)
{
return (CurrentState.IsKeyDown(k));
}
}

For now I have limited the code to checking if a button is pressed (ie. pushed down) and if it ihas been held down. This will allow us to in any part of the game check which keyboard buttons the players are pressing and act accordingly.

Once you have added the keyboard handling class, you just need to create an instance of it, and init it (or make it a constructor if you prefer) and then call KeyboardH.UpdateKeyboard() at the start of your update code. You may remember previously we made the game exit when the game was at the main menu when the player presses Escape, with the keyboard handling class, we can now replace the line with a much simpler and more efficient method:

1
if (KeyHandle.KeyPressed(Keys.Escape)) { this.Exit(); }

Getting the mouse input

Due to the style of the RPG that is being in made as this tutorial progresses, I will not cover handling mouse input, but it is a very easy topic to look at and all you will really need to get kcik started is the MSDN reference “How To: Get the Current Mouse Position (Windows)

You should now have a class that allows you to handle all your keypressing without having to get the keyboard’s state every time you want to check if a single key is pressed. Part 1.3 will introduce a main menu class that updates and draws itself, and tie all the parts of the basic skeleton together for us so that we can move onto part 2.1 where we begin the actual RPG engine.

Discuss this tutorial on the forums.

Building a 2D RPG in XNA: Part 1.1 – Building the basic skeleton

January 18th, 2010

First of all, it is important to know what all you want to put in your RPG, what style you want it to be in, and how all the mechanics will work together. For your RPG you should be aiming for a certain style the whole way through to ensure your end result is at least in some way consistent.

Now, chances are you will be modeling the game around your own thoughts and ideas, but this set of tutorials will create a game that is not unlike the popular pokemon gameboy games.

The first important step should be deciding how you would like to manage things, and split everything into categories for yourself putting each part of the game into its own “category”. I have split mine into the menu, the RPG game and the battles, as 3 seperate parts.

The menu: The menu should use one single class to hande the beginning of a new game or continuing a saved game (at a later stage even starting a network game). It is a fairly simple part of our game and we dont need to do anthing special with it.

The RPG: This is where the actual thought has to go into how you want to structure the games levels, and such. For the purpose of this tutorial the RPG part will be split up into a few parts: a map engine, a dialogue engine, an event engine, and an NPC engine. Each part will be explained in depth in tutorials to come.

The battles: This is another part of the game that will require some extra work and thought. Are we going to use a turn based or realtime system? Are we going to allow multiple player controlled characters and/or multiple enemies? For this tutorial we will build a system where we have turn based fights and always one versus one.

With this basic information we can already begin writing parts of our RPG. Even though we dont have detail yet, we can put in the skeleton of the game. This skeleton will manage the game state (in menu, in game, in battle, etc), and have the necessary save and load code in place.

First of all, I would advise you read up on my code (given below) which can be used for your save game file which will be used in this tutorial.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
        Settings player1 = new Settings();

public class Settings
{
//All variables for use with this class
public Dictionary SettingVals = new Dictionary();
string Temp = "";
string[] Handle;
int checkLoop;
System.IO.StreamReader streamIN;
System.IO.StreamWriter streamOUT;
System.IO.FileStream fileStream;

//Load all our settings, unless the file we try to
//load from doesnt exist, then it just gives the
//defaults in Init.
public int LoadSettings(string FileName)
{
if (System.IO.File.Exists(FileName))
{
streamIN = new System.IO.StreamReader(FileName);
while (!streamIN.EndOfStream)
{
Temp = streamIN.ReadLine();
Handle = Temp.Split("="[0]);
SettingVals.Add(Handle[0], Handle[1]);
}
streamIN.Close();
streamIN.Dispose();
}
else
{
InitDefaults();
}
return 0;
}

//This method is called in the LoadSettings method
//if the load settings method fails to find the
//file name.
public int InitDefaults()
{
/**/ //Sample settings
SettingVals.Add("Resolution", "800x600");
SettingVals.Add("PlayerName", "edg3");
SettingVals.Add("ItemSlot1", "swrd1");
SettingVals.Add("ItemSlot2", "shld1");
SettingVals.Add("ItemSlot3", "SmallHealthPotion");
/**/

return 0;
}

//This method will first check if the save file
//exists, then if a backup exists, and handle
//things accordingly
public int SaveSettings(string FileName)
{
if (System.IO.File.Exists(FileName))
{
if (System.IO.File.Exists(FileName + ".BAK"))
{
System.IO.File.Delete(FileName + ".BAK");
}
System.IO.File.Copy(FileName, FileName + ".BAK");
}
System.IO.File.Delete(FileName);
fileStream = System.IO.File.Create(FileName);
fileStream.Close();
streamOUT = new System.IO.StreamWriter(FileName);
foreach (string forTemp in SettingVals.Keys)
{
streamOUT.WriteLine(forTemp + "=" + SettingVals[forTemp]);
}
streamOUT.Close();
streamOUT.Dispose();
return 0;
}

//This method is used to get your backup of your
//save file just incase something goes wrong
//during the saving process.
public int RetrieveBackup(string FileName)
{
if (!System.IO.File.Exists(FileName + ".BAK"))
{
//if you want you can still carry on if
//the backup doesnt exist
return 1;
}
System.IO.File.Delete(FileName);
System.IO.File.Copy(FileName + ".BAK", FileName);
return 0;
}

//This method sets a value, or creates it if it
//doesnt exists yet.
public int Set(string Key, string Value)
{
if (KeyExists(Key))
{
SettingVals[Key] = Value;
}
else
{
SettingVals.Add(Key, Value);
}
return 0;
}

//Checks if a key exists in our settings dictionary
//it is only a helper method for the Get() and Set()
public bool KeyExists(string key)
{
for (checkLoop = 0; checkLoop < SettingVals.Count - 1; checkLoop++)
{
if (SettingVals.Keys.ElementAt(checkLoop) == key)
{
return true;
}
}
return false;
}

//Get a value
public string Get(string Key)
{
if (KeyExists(Key))
{
return SettingVals[Key];
}
return "NoValue";
}

}

Feel free to use your own save code as this method allows the player to eaily cheat, we will at the final stage of our game make this save and load code use some of .NET’s built in encryption. Create a class in your project for the saving system code, and declare an instance of the class for use in all parts of the game.

Simple game state management

Now, as you have probably realised, somehow we will have to manage which part of the game we are in, and game state management is how we will do it. The easiest way is to use enums, and to split them into structures that make sense.

  1. Main game (ie. Menu, Playing, etc)
  2. In game (ie. RPG, RPGpaused, Battle, etc)

To handle our game state we just declare our enums and then use switch statements everywhere where the happenings will differ.

1
2
3
4
5
6
7
8
9
10
11
12
13
        enum GameState
{
Menu,
Playing
}
GameState gameState = GameState.Menu;
enum PlayState
{
RPG,
RPGpaused,
Battle
}
PlayState playState = PlayState.RPG;

Adding in game states (perhaps if you want to put in a state where you show a video, or a state where you can change game settings) when using enums is fairly easy, and will be infinitely easier then if you tried to code everything in one go.

Our code will now for updating look something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
        protected override void Update(GameTime gameTime)
{
// Allows the game to exit
//if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
//    this.Exit();

// TODO: Add your update logic here
switch (gameState)
{
case GameState.Menu:
//allows the game to exit, this will be changed at a later stage
if (Keyboard.GetState().IsKeyDown(Keys.Escape)) { this.Exit(); }
//menu update
break;
case GameState.Playing:
switch (playState)
{
case PlayState.RPG:
//rpg update
break;
case PlayState.RPGpaused:
//rpg pausemenu update
break;
case PlayState.Battle:
//battle update
break;
}
break;
}

base.Update(gameTime);
}

And similarly for the games draw().

Now, for each part of the game’s update we will pass the variables for game and play state so that if the user for isntance selects a menu uption from the menu, the menu will then be able to change the state from “Menu” to “Playing” and so on. We will also always pass the instance of the save class through to the update methods as we may need to know if we are going to resume game or if the player has enough gold to buy that item he/she really wants. For example:

1
menu.update(gameState, playState, mySave, ...);

And with this code, we now have managed our different states of gameplay, switching between them should be easy enough, and we can save settings and player data. The next tutorial (1.2) will handle the making of the main menu, and the game’s pause menu, as well as the keyboard/mouse handling that we want in our RPG.

Discuss this tutorial on the forum.

New theme: Simpler then I imagined

January 10th, 2010

While building a new theme for my site, I put it past people on Gui Station and got various comments on how to improve the look I was working on. After much work and irritation (human error being the main cause) I realised that the WordPress default theme and the PHPBB theme while different had pretty much the same visual style. So with a little tweaking here and there over the next few weeks (and a newly built front page and evengrand folder) the site will look 75~90% the same, and navigation will remain constant throughout the site for ease of access.

Site updates:

  • Blog: Updated WordPress to latest version
  • Blog: Added SEO plugin (to be configured soon)
  • Blog: Updated the CodeColourer plugin
  • Blog: Disabled comments
  • Blog: Removed links from the side column
  • Blog: Added site navigation to the header
  • Forum: Added site navigation to the header

While nothing spectacularly different has been introduced, hopefully this is a move in the correct direction for the user-friendliness of the site.

Discuss this entry on the forums.

Merry Christmas!

December 24th, 2009

It is indeed that time of the year, and as a year end blog post and a look at the plan for the next year I am going to give a brief look at what Im going to be doing:

Integrating the whole site as one
Introducing important news feeds
Continuing my python tutorials
Writing the tutorials I slacked off on and didnt do from an earlier blog post
Set myself a personal goal: one tutorial a month minimum on this blog for xna, I will tackle building an RPG engine with readers next year, amongst other things.

edg3

Input needed for new RealDev theme

December 17th, 2009

Im currently working on a new theme for the site, and Im looking for all the comments and criticism I can get before I go through the effort of making it into a phpbb style and a wordpress theme to integrate my whole site into one flowing site (as currently Im limiting the site to a few sections that you can get to in one direction, but not back to in the other).

The test page.

The forum is currently only phpbb3, but I will be modifying it to use a category system so that instead of millions of forums for each language there will be tags for your threads and peole can browse by tag.

Im hoping to at some stage move from just being a programming blog and forum, to also provide uploading space for projects and a pastebin for the users of this site, and when thats all in place get back to writing proper tutorials for XNA on my blog, and at the same time catering for other languages and such.