That and pray for Max White to show up and take pity on me again, because nothing ever really changes.
I HAVE A LIFE YOU KNOW!
No, not really. Ok let's get this show on the road. I'll show you how I like to set up Libtcod with state pattern to make life easy for all involved.
Basically libtcod is a hunk of well running shit designed by a maths guy who liked numbers, rather than a programmer who designs things to be in any possible way usable. But, with just a little effort, we can make things a little easier for ourselves.
Firstly, it sounds like you already have the basics going, but just to make sure, and also for anybody at home who wants to bake their own:
After downloading the .net wrapper for Libtcod (And also a copy of the terminal.png, not included with the standard download for excuses) add a reference to libtcod-net.
Now to your project (Not as a reference) add libtcod-VS.dll, libtcod-net-unmanaged.dll, SDL.dll, zlib1.dll and terminal.png (Or what ever file format you have, I'm 80% sure others work)
Remember to select all the files you just added to your project and go down to your properties window. Change to 'Copy if newer'
For good measure, run that once, just so that it copies all the files and you will never have to think about it again.
Now onto the fun bit, the code! First, make a new class called 'Game' and give it a public void method with an empty signature called 'Run'. Should look like this.
class Game
{
public void Run()
{
}
}
Now back in your main, create a new game instance and call its run method. That is all for the main. Hopefully, for some time at least, you will never need to modify that. Anyway, before we can continue, we need a new abstract class.
Call this new class GameState and give it the methods 'internal abstract void Draw(TCODConsole console)' and 'internal abstract void Update(TCODKey input);'
Yes, I know we could be using partial classes right now to make the GameState part of the game DO NOT CARE RIGHT NOW. It is an indie game. The fact that we are using state pattern instead of a giant IF block already stinks of high class.
Anyway, code should look like this
abstract class GameState
{
internal abstract void Update(TCODKey input);
internal abstract void Draw(TCODConsole console);
}
Now you
are going to need to allow your GameState to see your Game, so add a protected attribute called game and also make a protected constructor taking a Game as a parameter.
abstract class GameState
{
protected Game game;
protected GameState(Game game)
{
this.game = game;
}
internal abstract void Update(TCODKey input);
internal abstract void Draw(TCODConsole console);
}
Ok, that is all we need for our GameState! Back to the game folks.
First, throw in a bool called 'quitting', an instance of a GameState called 'state' and two methods, one called 'Quit()' and another called 'SetState(GameState state)'. Have Quit() flag 'quitting' as true and SetState() reassign 'state'
class Game
{
private bool quitting;
private GameState state;
public void Run()
{
}
internal void Quit()
{
this.quitting = true;
}
internal void SetState(GameState state)
{
this.state = state;
}
}
Ok, now all we need to do is define a game state to actually run, and build the game loop. Let's start with the loop.
There are better ways to do this than hard coding, but let's start simple and call TCODConsole.initRoot(sizeX, sizeY, "NameOfGameHere");
Next, set quitting to false.
Now comment out what you are about to do, because you will need a class we haven't made yet, but call 'this.state = new MainMenuState(this);'
Ok, so as a little qwerk of what we are doing and how libtcod works, we want to clear, draw to and flush our console before we do anything else. Remember, you are drawing your game by calling state.Draw(TCODConsole.root)
Now start a loop with the condition !quitting. This is your main game loop.
Inside it, first call 'state.Update(TCODConsole.waitForKeypress(false))'
Then, just like you did before we entered the loop, clear, draw and flush. All in all, should look like this
public void Run()
{
TCODConsole.initRoot(120, 70, "Dicks");
this.quitting = false;
//this.state = new MainMenuState(this);
TCODConsole.root.clear();
this.state.Draw(TCODConsole.root);
TCODConsole.flush();
while (!quitting)
{
this.state.Update(TCODConsole.waitForKeypress(false);
TCODConsole.root.clear();
this.state.Draw(TCODConsole.root);
TCODConsole.flush();
}
}
We are
almost done!
Part II (Coming soon) will introduce you to
HOLY FUCK WE CAN DO THAT as well as actually starting to do the bit where it is your game.