🔒 Locked
Processing keystrokes
Advertisement
Original Post
Hi, i'm having a bit of trouble, hope someone can help me. I'm currently doing a piece of coursework for uni using Peter Walsh's zen game engine, c++ .net directx8, what i'm getting stuck on is trying to let the user change their control buttons in a game option menu. The question is, is there anyway (excluding event listening) to read a keypressed. As in if the letter 'a' is press there is a function i can do like char letterPressed = letterPressed(); obviously i don't care if its the int value returned or not because all it does is a compare later on. I've taken a look at stuff like getche() and all that but don't know if i'm coding it wrong or it just doesn't apply to this. any help is greatly appreicated
Are you wanting an answer in terms of your particular engine, or just a general answer?
Typically a windows-based game will use one of two ways to get keyboard entry:
1. Windows messages (WM_KEYPRESS etc..)
2. DirectInput
For the most part the former is simple and straightforward.
hth
Jack
Typically a windows-based game will use one of two ways to get keyboard entry:
1. Windows messages (WM_KEYPRESS etc..)
2. DirectInput
For the most part the former is simple and straightforward.
hth
Jack
well a general answer, as long as it works really
currently the movement runs like this
bool PlayerMove(char direction[]) {
if (direction == "up") { if (keyboard_state[DIK_UP]) { return true; } else { return false; } }
else if (direction == "down") { if (keyboard_state[DIK_DOWN]) { return true; } else { return false; } }
else if (direction == "left") { if (keyboard_state[DIK_LEFT]) { return true; } else { return false; } }
else if (direction == "right") { if (keyboard_state[DIK_RIGHT]) { return true; } else { return false; } }
else { return false; }
}
but instead of having say keyboard_state[DIK_RIGHT], i would like
keyboard_state being "lpdikey->GetDeviceState(256, (LPVOID)keyboard_state);"
if userInput() == rightMovement
were userInput is the keystroke pressed and rightMovement is a pre-defined variable for what the keystroke must be to move in that direction
currently the movement runs like this
bool PlayerMove(char direction[]) {
if (direction == "up") { if (keyboard_state[DIK_UP]) { return true; } else { return false; } }
else if (direction == "down") { if (keyboard_state[DIK_DOWN]) { return true; } else { return false; } }
else if (direction == "left") { if (keyboard_state[DIK_LEFT]) { return true; } else { return false; } }
else if (direction == "right") { if (keyboard_state[DIK_RIGHT]) { return true; } else { return false; } }
else { return false; }
}
but instead of having say keyboard_state[DIK_RIGHT], i would like
keyboard_state being "lpdikey->GetDeviceState(256, (LPVOID)keyboard_state);"
if userInput() == rightMovement
were userInput is the keystroke pressed and rightMovement is a pre-defined variable for what the keystroke must be to move in that direction
I think you are right though WM_KEYPRESS/KEYUP/KEYDOWN is the answer
when defining the keys i can use cin as it doesnt matter if it pauses, as it would be "Please enter a key" - wait for a reply - set key to this, but for the movement check it would need to be WM_* probably something like
if ( message = WM_KEYDOWN )
keyPress = WM_KEYDOWN;
if ( message = WM_KEYUP )
keyPress = null;
but what does WM_KEYDOWN pass, as far as i can see it's some sort of scan code but im not to sure how to convert that to ascii or basic hex, any ideas
when defining the keys i can use cin as it doesnt matter if it pauses, as it would be "Please enter a key" - wait for a reply - set key to this, but for the movement check it would need to be WM_* probably something like
if ( message = WM_KEYDOWN )
keyPress = WM_KEYDOWN;
if ( message = WM_KEYUP )
keyPress = null;
but what does WM_KEYDOWN pass, as far as i can see it's some sort of scan code but im not to sure how to convert that to ascii or basic hex, any ideas
Have you got your standard Win32 message pump up and running? They don't work through the standard input/output (std::cin and std::cout)...
You need the wParam and lParam values to go with the message to decode any specific details. Check this page out.
hth
Jack
You need the wParam and lParam values to go with the message to decode any specific details. Check this page out.
hth
Jack
actually got it working, still needs some tweaking to allow 2 button control
I'm pretty damn pleased at getting that as i only started writing in c++ and directx 2-3 days ago
[Edited by - Muhammad Haggag on December 9, 2005 4:43:53 AM]
int keyPressed;int keyPressed2;int player1_Up=87;int player1_Down=83;int player1_Left=65;int player1_Right=68;long CALLBACK WndProc( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam ){ switch( uMessage ) { case WM_CREATE: { return 0; } case WM_PAINT: { ValidateRect( hWnd, NULL ); return 0; } case WM_KEYDOWN: { keyPressed = wParam; if(keyPressed != wParam){ keyPressed2 = wParam; } return 0; } case WM_KEYUP: { if(keyPressed==wParam){ keyReleased=wParam; keyPressed = NULL; } if(keyPressed2==wParam){ keyReleased2=wParam; keyPressed2 = NULL; } return 0; } case WM_CHAR: { if(wParam>96 && wParam<123){ keyPressed = wParam - 32; if(keyPressed != wParam){ keyPressed2 = wParam - 32; } } else { keyPressed = wParam; if(keyPressed != wParam){ keyPressed2 = wParam; } } return 0; } case WM_DESTROY: { PostQuitMessage( 0 ); return 0; } default: { return DefWindowProc( hWnd, uMessage, wParam, lParam ); } }}/*direction function here*/bool PlayerMove(char direction[]) { if (direction == "up") { if (keyPressed==player1_Up || keyPressed2==player1_Up) { return true; } else { return false; } } else if (direction == "down") { if (keyPressed==player1_Down || keyPressed2==player1_Down) { return true; } else { return false; } } else if (direction == "left") { if (keyPressed==player1_Left || keyPressed2==player1_Left) { return true; } else { return false; } } else if (direction == "right") { if (keyPressed==player1_Right || keyPressed2==player1_Right) { return true; } else { return false; } } else { return false; }}I'm pretty damn pleased at getting that as i only started writing in c++ and directx 2-3 days ago
[Edited by - Muhammad Haggag on December 9, 2005 4:43:53 AM]
Muhammad's gonna be mad.. put that code in source tags. And if you don't know what that means, read the forum FAQ.
Well, besides your input code being rather.. erm, abstract.. an easier way to allow for customizable user input would be to use the method you were using before (that is, polling the keyboard with DirectInput), then loop through the keys array until you find one that's pressed. Then use that index as the customized key. You could do it like so:
I figured I might as well expand upon what I mean by your input code being abstract. I assume you're doing something like this:
While it looks pretty, it's pretty foolish as well. You're doing a string compare for every single direction (and probably for every action). I take it you're doing it this way to add a level of indirection for the player input - that is, so you're not hard-coding the tests for keys pressed into the logic of moving the player, which is a good thing. However, it'd be much more efficient to use an enum to define the player's actions, like so:
Well, besides your input code being rather.. erm, abstract.. an easier way to allow for customizable user input would be to use the method you were using before (that is, polling the keyboard with DirectInput), then loop through the keys array until you find one that's pressed. Then use that index as the customized key. You could do it like so:
int UpKey;...while(1){ // Process windows messages here lpdikey->GetDeviceState(256, (LPVOID)keyboard_state); for(int i = 0; i < 256; i++) if(keyboard_state & 0x80) { UpKey = i; break; } // Render your UI here}I figured I might as well expand upon what I mean by your input code being abstract. I assume you're doing something like this:
if(PlayerMove("up")) // move player upif(PlayerMove("down")) // move player downWhile it looks pretty, it's pretty foolish as well. You're doing a string compare for every single direction (and probably for every action). I take it you're doing it this way to add a level of indirection for the player input - that is, so you're not hard-coding the tests for keys pressed into the logic of moving the player, which is a good thing. However, it'd be much more efficient to use an enum to define the player's actions, like so:
enum{ PlayerMoveUp, PlayerMoveDown, PlayerMoveLeft, PlayerMoveRight};...bool PlayerMove(int direction){ switch(direction) { case PlayerMoveUp: if(keyboard_state[UpKey]) return true; else return false; case PlayerMoveDown: if(keyboard_state[DownKey]) return true; else return false; // etc.. }}...if(PlayerMove(PlayerMoveUp)) // Move player upif(PlayerMove(PlayerMoveDown)) // Move player downQuote:
Original post by Drakex
Muhammad's gonna be mad.. put that code in source tags. And if you don't know what that means, read the forum FAQ.
I seem to be building quite the reputation, here [grin]. Seriously: GDNet Forums FAQ, Forum FAQ, Want to post? Read this first. 2005-11-07.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement