One of the first things I like to think through is how user input will be provided in a game, and how I want to manage that within my game code.
I've become fond of working at the higher abstraction level of "user actions" within the game code itself. I'd rather write my code to respond to a "main weapons fire" action than tie it directly to a certain key or mouse button press. This allows more flexibility in user control setup, and sometimes allows a block of response code to be written before the user control details are nailed down.
However, you can't get actions without working through how a system will read and report the lower level input. With this GDI-based library, I expect to be making smaller windowed games that use keyboard and mouse input. No need at this time to get gamepad/joystick support in place ... but I'll leave open some hooks to add it later, if needed.
Keyboard
Each update cycle, Nimble will grab the current state of all the keys on the keyboard and will do some calculations to handle situations such as "double hits" and "first time down". There will be some methods to test the current state of each key. But, primarily, these states will feed into the action system.
So far, I have not been able to find any built-in methods within the .Net framework to allow me to check the current state of any key on the keyboard. (If anyone knows how to do this in standard .Net, please point me in the right direction.) So, I will be using InterOp to tap into the same Windows API I used in the VB6 days to get the key states.
Mouse
Happily, .Net does have nice real-time mouse-handling methods available, including one to get the mouse position relative to the upper-left of any form or control you supply to it. And, the key state method mentioned above will also get the status of the mouse buttons. So, mouse buttons will be handled as if they were just a few more keyboard keys.
Once the X & Y of the mouse can be determined for the main screen object -- a picturebox control, in Nimble2D's case -- it then has to be translated to the corresponding position within the GameSpace being shown. So, the NimbleInput.Mouse object will have ScreenX, ScreenY, GameSpace, GameSpaceX, and GameSpaceY properties available (among others).
The ability to translation to GameSpace coordinates will rely on how GameSpaces, Layers, and Cameras are setup and used within Nimble2D. This means that I need to flesh-out the basic functions of those objects before I can implement the mouse-related input items. And, that sets up the next post nicely. Watch for "It's All About the Cameras" to explain how that piece all works.
Actions
As I mentioned at the start of this post, "user actions" are higher abstraction of the actual input being received. The game's code will be able to define typical actions needed in the game -- "run right", "jump", "fire main", "fire secondary", etc. -- and then ask NimbleInput if that action is currently "on".
Low-level input states are assigned to an action, which is what NimbleInput actually checks for to report whether an action is on or not. This will allow for flexibility in assigning user controls at run-time, and for allowing multiple keys to trigger the same action. For example, a game that needs a simple 4-key control method ("up", "down", "left", "right") could allow for both the traditional arrow keys, plus the W-A-S-D keys to provide that control ... or even to allow the user to select his/her own keys controls for each action needed.
Taking that example to a finer detail level ... The game code could define an action of "Up" and assign both the "Up Arrow" and "W" keys to that action. During the game loop, a request for the status of the "Up" action would have NimbleInput checking the states of both the assigned keys. If either key is currently down, then a "TRUE" value would be passed back to indicate that the action is currently on.
There will be different action assignment methods available to cover situations such as single key presses, double key presses ("double clicks"), absolute mouse locations and relative mouse locations. The mouse location assignments should make things easier for handling mouse-over of menu items or mouse-steering.
General Methods
A few basic general methods will also be provided, such as clearing all keys (makes them all read as "up" until they are pressed again later) and checking for "any key pressed".
More Details Coming
As I mentioned in the "mouse" section above, some of the basic graphical objects and features need to be put in place before we can work out the mouse location. So, once the GameSpaces, Layers, Main Screen, and Cameras are worked out, I'll come back with a more detailed look (including code) at NimbleInput.