Archived

This topic is now archived and is closed to further replies.

DirectX Action Mapping or other?

This topic is 5149 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Do developers generally use action mapping as explained in the SDK or do they go about input differently? I''m thinking about my input system and I quickly realize that the graphics engine will react to some user input, interface will react to some, character movement/actions will react to some, etc. Now, if I have an input manager that gets the state of the keyboard/mouse each frame then how do I translate that information into game functions? For instance, the character presses UP key to move forward. My input manager will record that UP is pressed this frame and so my code that moves the character over a frame should be called, but I''m not sure how. If the input manager is declared in WinMain and so is the graphicsManager then without making one completely accessible to the other, how do I translate the messages? Right now I can only think to create a global data structure that holds the current input for that frame. Then I will need a state manager to determine how the input in that global DS will be used. pseudocode if cStateManager.EnterTextMode() == true see what key was pressed this frame (taking into account relative key repeats, etc). else //we are in normal game mode so look at the inputDS and see what key/s were pressed if DIK_UP then cGraphicsManager.MoveCharOneFrame() if LEFT_BUTTON_CLICK && mouse pointer was over an icon then do action associated with clicking that icon (cast spell?) The above would require calling every possible function in the game to see if it''s bit was set from keyboard/mouse input. Is there some way that a signal can be sent directly to a function from the keyboard maybe through a function pointer of some sort? This way I would have a normal render loop but before rendering I get the keyboard state and for every button that was pressed I call ONLY the function tied to that button and then I do the actual rendering? As you can see in the pseudocode above, there would be an if statement for every possible key or key combination and each associated with a possible game function (which can actually be in one of many different class objects). Add to this the ability to change input settings (keyboard mapping) and you see the gore that is evolving. So, is there some standard way of organizing this? Any input is greatly appreciated. Webby

Share this post


Link to post
Share on other sites
I''m thinking something like this might work.

Every game loop I will gather input into a buffer which is nothing more than a flag for every keyboard key (or some way of representing this). Now, each game function knows what key code it has to look for. For instance, the game checks for character movement so it checks UP_ARROW, BACK_ARROW and if either of them are set then the character animates forward one frame. So instead of keyboard presses calling functions I have functions checking for input which I guess makes more sense now that I think about it. This way, I won''t have to check EVERY possible function, only those that apply at the moment.

Also, in regards to allowing players to change keyboard mappings I am thinking of something like this.
Originally the keyboard is setup such that UP_ARROW moves forward, BACK_ARROW moves back, etc. The game functions will check a the global input array to see what flags have been set (haven''t figured out multi-key commands yet). But anyway, if the user changes the keyboard settings then I am thinking of something like this. Each original setting has a reference to its own key. If the user decides he wants to move forward by pressing "A" then the reference under "A" will then point to UP_ARROW. So by pressing "A" he is still telling the program to set the UP_ARROW flag only indirectly. At the same time, I can either have UP_ARROW reference "A" so that the two keys now perform each others actions or I can NULL UP_ARROW until the player decides to set another function to it.

To represent this I am thinking of a window that has a listing of each function that the player can map (movement, camera tile, use potion, etc). Next to each listing is a text entry box that lists the current keyboard button/s associated with that action. The user can highlight this textbox and click ALTER followed by the key he wants to use there. The rest of the text boxes will update as necessary based on this decision so that keys can only be tied to a single function. Or I can introduce states so that certain keys perform certain tasks under during certain states (certainly a lot of uncertainty there).

Anyway, I''ll cut it off here and wait for opinions. This seems like it might work out though.

Thanks,
Webby

Share this post


Link to post
Share on other sites
No interest?
Sucks when you own hundreds of dollars or programming books and the best they offer on this subject is a DirectInput wrapper class that doesn''t do anything but show you how to PostQuitMessage which I already know how to do

..Webby

Share this post


Link to post
Share on other sites
I believe the observer pattern should solve this problem nicely. It's simple to implement and it'll detach your input and graphics systems elegantly.

edit: wrt action mapping, i wouldn't use it if i were you. It's a bit weird in the way it goes about things, stores settings in a sub directory of your windows directory and forces you to use its ugly key-binding application if you want to change the keys.

[edited by - sark on November 9, 2003 3:44:51 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by intrest86
I love DX Action Mapping, and you can write your own interface for binding keys, despite what the last poster said.


Hmm.. when doing my own research on it, I couldn''t find anything on writing your own interface. This was through managed directx though.

Share this post


Link to post
Share on other sites
Decided against DX Action Mapping mostly because I want a better understanding of how input is handled.

Considering that this is to be a client/server type of game I currently have these needs.
1) NetworkCore needs some way to tell what kind of packets need to be generated. For instance, if the user presses UP_ARROW then a CLIENT_MOVE_FORWARD packet is generated and sent. Actual graphics code doesn''t need to see this input since it cannot move the char until the server says so anyway. same goes for attacking, casting spells etc.

2) GraphicsCore still needs access to the input because of situations like if a player clicks the game screen, the object under the mouse pointer should be selected. To do this I plan to gather current network info, update all objects for this frame and then decide where the user clicked on the screen. Interpret this somehow into 3D space and return the ID of whatever was clicked on (actual algorithm to be generated alter). Then, using this ID I have to create a request packet and send it to the server.

3) UserInterface and client only tasks. UserInterface code needs to know about input obviously. This won''t generally go through the server (things like adjusting screen gamma). OTOH if the user clicks to destroy an item from inventory then this has to generate a packet to the server.

Many other cases obviously but the above three I think are the main cases I need to handle.

What I''d like to not do is every frame, call EVERY possible function in the current state to see if input related to it was given. What I would like is a system where
If player hits DIK_UPARROW then a signal is sent to one function ONLY and proper actions are taken. This I cannot conceive how to do. Observer might help here if Source is keyState and ANYTIME keyState changes then is sends a signal to all observers. If the observers are other classes then each class needs to implement actions when Source doesn''t change(just do normal sit_there actions) and actions when Source does change(Was it my key that was pressed? If so, adjust me according to input).

Argh!!! Kudos to those who find this easy
I''m off to ponder some more,
Webby

Share this post


Link to post
Share on other sites
Action mapping has less to do with how you handle the input and more with how you translate input into more precise messages, so the things you listed off do not preclude Action Mapping.

Here is an MSDN technical article on Action Mapping: http://msdn.microsoft.com/library/default.asp?url=/nhp/default.asp?contentid=28000410

To create your own interface you will simply need to alter the data structures that are included and pass them into the functions.

Share this post


Link to post
Share on other sites
Back to this Observer pattern. Is this logic correct?

Need abstract classes cObserver and cSubject.
cSubject allows Attach and Detach
Now I will derive a cConcreteSubject which is an object that does everything related to say keyboard input. Each frame, if there is keyboard input then the cConcreteSubject will iterate through all of its cConcreteObservers and call their Update() function. Each one in turn will then check the keyboard data to see if the keypress related to them. If it does then they update themselves accordingly.

Now, after all Observers have been updated then I have the new current game state which I can render.

Based on this it seems like Observer can go a looooong way.
cPlayerObserver, cInterfaceObserver, etc all observe cKeyboardSubject and cMouseSubject and all update accordingly to the Subjects. In turn, cGraphics can observe cPlayerOvserver, cInterfaceObserver. If either changes then the cGraphics is updated with the current game state and can finally render the scene. Then the next frame continues.

This seems like it would quite nicely allow me a way of abstracting all parts of the engine from each other. Add to this a nice state manager that allows for Updates to only those currently available functions and this could be quite speedy.
I''m thinking that if the game is in say TEXT_ENTER state then the cPlayer observer doesn''t need to Update because the all keyboard input is going straight to the cInterfaceObserver only.
Likewise, if in GAME_MODE then cInterfaceObserver doesn''t need to be Updated because all keyboard input is causing game commands and not text letters. Of course, cStateObserver would have to update every time to make sure we switch from TEXT_MODE to GAME_MODE when the user presses "ENTER" or goes into certain menus.

I''m liking this if I''ve got the logic correct.
Thanks for the lead,
Webby

Share this post


Link to post
Share on other sites
Yeah, you got the general idea, but you only need one abstract class. I''m assuming this is the first time you''ve used the Observer pattern, forgive me if this is patronising:




abstract class IKeyboardListener
{
public:
void OnKeyDown(Key key);
void OnKeyUp(Key key);
}


class Keyboard
{
vector<IKeyboardListener> list;

public:
void AttachListener(IKeyboardListener listener)
{
list.Add(listener);
}


void DetachListener(IKeyboardListener listener)
{
list.Remove(listener);
}


void CheckForInput()
{
if ( key is found to be down )
{
foreach listener in list
{
list.OnKeyDown(key);
}
}
}
}





With this key event system in place, you could have a class that implements IKeyboardListener called NetworkManager, or something like that:





class NetworkManager : public IKeyboardListener
{
public:
void OnKeyDown(Key key)
{
// send a packet saying a key has been pressed

}
}




Then you just need to attach NetworkManager to your Keyboard class and you''re away, whilst your input system has absolutely no knowledge of your network system.

As for your game state management, then you may want to look into the State Pattern (or whatever it''s called, someone correct me if im wrong).

Share this post


Link to post
Share on other sites