Showing posts with label Events. Show all posts
Showing posts with label Events. Show all posts

Saturday, July 9, 2011

Event handling done, and a bit about File I/O

Well, the bare-bones version of the event handling system is done. There are some improvements to make, and I only support a few keys and commands still, but the system is fairly robust and extensible. Plus, the key mappings are read from configuration files now, so they can be modified without recompiling.

The shape it has taken, in the end, is quite close to my original design. I created an Event Interpreter, which receives the system events and returns a command. In order to do this, it has a list of contexts where it searches for the event. Each context consists of a map, using events as the key.

The order of contexts is important, since an event can have different meanings in each. The contexts closer to the top have priority, however, and they override the commands in lower contexts. During the course of the program, the contexts may shift up and down, or even be removed completely and held in a holding stack in order to disable a set of commands at once.

In order to load the contexts in the begining, the program reads a text configuration file. The file is structured such that contexts are marked by curly braces ({}), and are composed of lines delimited by semi colons (;). Each line consists of an Event:Command pair, separated by a colon (:). The properties of each event and command, which identify them, are set apart by commas. So a simplex context would look like

{EventType, EventCode, : CommandType, CommandCode,;}

I'll probably end up adding an identifier for the Context. As it stands, I can comment anywhere between Contexts, but I have to be careful about what I write inside them. I should add a validation code of some kind. A missing file can hang the program right now.

I'm pretty happy about how the file reading code came out. String manipulation in C++ isn't trivial, whic is one of the reasons why everyone usually ends up rolling their own string class. I managed to deal with it fairly cleanly, though. I can't handle encodings other than ANSI (maybe UTF-8, haven't tested), but for a configuration file this shouldn't be a problem.

Now that this is done, however, I need to consider what else needs to be done. I think it's about time I gave the drawing code another look. I can work on other parts, but for testing purposes being able to see the effect of things in the screen would be a lot more useful. I'm hoping to be able to create assets in real time, which is one of the main drives in the project, and I need to be able to see the output ahead of everything else.

This means giving the resource caches another look as well. So I'll be having some fun.

Monday, July 4, 2011

Event Handling

So back to the matter of Events. These represent the interactions the player can have with the program. On the one hand, you have everything the player can do with the computer; pressing keys, moving the mouse, etc. On the other, you have the actions you can assign to one or more of these keys; moving the character, using items, shooting, etc.

The SFML already provides me with the player events. What I have to do is create the actions that correspond to them. I would then have a function that is fed an event and outputs the correct action. I'll start with the most basic event: a command to close the window and end the execution of the program. I'll provide the 'Esc' button for it.

After reading the events and generating the associated commands, I have to execute the command. For the most part, these commands are going to represent state changes in the game, and not so much actions themselves. In the case of a move forward command, pressing the 'move forward' key would toggle the entity's state to 'is moving forward', and releasing it would reset it to 'is stopped'. Then in the update loop the game would check if the player 'is moving forward' and if so advance it's position.

Of course, if I have each command execute itself from the event loop, I have to riddle the entity interface, and anything the player can interact with, with functions to access the members that define their state. Instead what I'll do is read the command, build a command queue for each target that might receive a command, and pass the stack to the target. That way the target (be it an entity, the window or whatever) can apply the commands internally.

I'll start with some basic commands: 'Esc' to close the game, and 'WASD' to move forward and back and strafe left and right. I'll use 'Esc' on press, meaning as soon as the key is pressed the program will end. The four keys will actually mean eight commands. Four to start and four to stop, on press and on release respectively. This allows to have several keys pressed at once, and if opposite keys are pressed, they can both be applied (it would result in no effect at all, but it wouldn't bother the game).

 My command class is going to mirror the structure of the event class provided by SFML. It will consist of an enumeration describing the kind of command it is, such as a window or movement command, and a union of structs that each describe the kind of command in detail.

The Commands are mapped to Events in structures called Contexts. Each context represents a set of Commands that are available. We do this because particular keys could have different meanings depending on the state of the game. For example, it could be that when the inventory is open, the movement commands are disabled. The contexts give the ability to remap keys and alter the available commands on the fly.

Well, this gives a bit of an overview of how I'll be handling user input. Next up, I'll be describing the process in more detail as I finish writing it up. I have the basic structures coded now, but I still need to assemble it all together.