Jibble

Author Topic: Re-define the keys.  (Read 1180 times)

RetroJay

  • Posts: 537
  • Frankly, my dear, I'm a Kerbal and Proud of it.
    • RetroJay worked on a game that was nominated for an AGS Award!
Re-define the keys.
« on: 20 Nov 2014, 05:30 »
Hi all.

I hope someone can help me out here.
I have been scouring the forums and searching for a solution but, alas, have not found the answer.

The game I am working on is all controlled with the keyboard, I am using the built in 'KeyboardMovement' Module, AGS 3.2.1.
Everything is going well... However...

I would love for the player to be able to re-define the controls.
The keys that I would like for them to be able to change are the movement keys, these are set on the arrow keys, at the moment.
Also Examine and Use inventory item, I have these set on A and Z, for now.

Is there a way of accomplishing what I would like to do?
If anyone could give me a few pointers, it would be much appreciated.

Yours.
Jay.
  Master Decorator

Crimson Wizard

  • Posts: 8,794
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Lifetime Achievement Award Winner
    • Crimson Wizard worked on a game that won an AGS Award!
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
Re: Re-define the keys.
« Reply #1 on: 20 Nov 2014, 08:42 »
Step One.

Make a variable of type eKeyCode per each control key.
Init them with default keys (arrows).
In on_key_press check for these variables instead of key constants.

Example:
Code: Adventure Game Studio
  1. eKeyCode KeyMoveUp;
  2. eKeyCode KeyMoveDown;
  3. eKeyCode KeyMoveLeft;
  4. eKeyCode KeyMoveRight;
  5.  
  6. function game_start()
  7. {
  8.     KeyMoveUp = eKeyUpArrow;
  9.     KeyMoveDown = eKeyDownArrow;
  10.     KeyMoveLeft = eKeyLeftArrow;
  11.     KeyMoveRight = eKeyRightArrow;
  12. }
  13.  
  14. function on_key_press(eKeyCode keycode)
  15. {
  16.     <...>
  17.     if (keycode == KeyMoveUp)
  18.         ... move up
  19.     else if (keycode == KeyMoveDown)
  20.         ... move down
  21.     etc
  22.     <...>
  23. }
  24.  

Step Two.

I guess there are many different ways to implement keys setup, but the most primitive is to let player press them all in the order.
In the sake of experiment, make a GUI with a label, and print something like "Press a key for 'Left'" on the label, scan player's key press, then move to the next key until all keys are recorded.


Example:
Code: Adventure Game Studio
  1. int KeySetupStep;
  2.  
  3. void NextKeySetupStep()
  4. {
  5.     KeySetupStep++;
  6.  
  7.     if (KeySetupStep > 4)
  8.     {
  9.         // all keys were recorded
  10.         gKeySetupGUI.Visible = false;
  11.         return;
  12.     }
  13.  
  14.     String hint = "Press a key for ";
  15.     String cmd_name;
  16.     if (KeySetupStep == 1)
  17.         cmd_name = "Up";
  18.     else if (KeySetupStep == 2)
  19.         cmd_name = "Down";
  20.  
  21.     // other keys
  22.  
  23.     lblKeySetupHint.Text = hint.Append(cmd_name);
  24. }
  25.  
  26. void StartKeySetup()
  27. {
  28.     gKeySetupGUI.Visible = true;
  29.     KeySetupStep = 0;
  30.     NextKeySetupStep();
  31. }
  32.  
  33. void RecordSetupKey(eKeyCode keycode)
  34. {
  35.     if (KeySetupStep == 1)
  36.         KeyMoveUp = keycode;
  37.     else if (KeySetupStep == 2)
  38.         KeyMoveDown = keycode;
  39.  
  40.     // other keys
  41.  
  42.     NextKeySetupStep();
  43. }
  44.  
  45. function on_key_press(eKeyCode keycode)
  46. {
  47.     if (gKeySetupGUI.Visible)
  48.     {
  49.         RecordSetupKey(keycode);
  50.         return; // do not do anything else this time
  51.     }
  52.     <... other code...>
  53. }
  54.  
  55. // Start key setup by pressing some button in the menu
  56. function DoKeySetupButton_OnClick(GUIControl *control, MouseButton button)
  57. {
  58.     StartKeySetup();
  59. }
  60.  

These are quick samples, the code may be organized differently. For instance, you may want to make an array of keys, instead of separate variables, and address elements of this array with integer constants (created as enum, or #define); also put key names in array too.
But this will give you some start.
« Last Edit: 20 Nov 2014, 08:49 by Crimson Wizard »

RetroJay

  • Posts: 537
  • Frankly, my dear, I'm a Kerbal and Proud of it.
    • RetroJay worked on a game that was nominated for an AGS Award!
Re: Re-define the keys.
« Reply #2 on: 20 Nov 2014, 09:33 »
Hi Crimson Wizard.

That looks... interesting.:P
I will definitely try this out, tonight.

Looking at your script I assume that all of this will be scripted within 'Global Script', yes?
I will let you know how thing go.

Thank you for your time.

Yours.
Jay.

 
  Master Decorator

RetroJay

  • Posts: 537
  • Frankly, my dear, I'm a Kerbal and Proud of it.
    • RetroJay worked on a game that was nominated for an AGS Award!
Re: Re-define the keys.
« Reply #3 on: 20 Nov 2014, 11:20 »
Hi Crimson Wizard.

I decided to attempt your code and...
I seem to be having problems with this section of script, from your first piece of code. ???
When I tried this I did set all of my keys up.

Code: Adventure Game Studio
  1. function on_key_press(eKeyCode keycode)
  2. {
  3.    <...>
  4. if (keycode == KeyMoveUp)
  5.     ... move up
  6. else if (keycode == KeyMoveDown)
  7.     ... move down
  8.     etc
  9.     <...>
  10. }
  11.  
  12.  

Where you have '... move up/down'. Am I supposed to put more lines of code there?
If so, then what? :-[ :-[ :-[

without this section my game plays and when I press the R key to redefine keys my GUI shows and asks me to press buttons for Up, Down, Left and Right.
Then the GUI closes and my game starts but the keys I have selected do nothing, the arrow keys still control my character.

Edit:-
I though that I would show you how my 'On_Key_Press' script is, at the moment.
Code: Adventure Game Studio
  1. function on_key_press(eKeyCode keycode) {
  2.   // called when a key is pressed. keycode holds the key's ASCII code.
  3.  
  4.   if (gKeySetupGUI.Visible) {
  5.     RecordSetupKey(keycode);
  6.     return; // do not do anything else this time
  7.   }
  8.  
  9.  
  10.   // THE S KEY (START GAME - FROM OPTION SCREEN).
  11.   // --------------------------------------------
  12.   if (IsKeyPressed(eKeyS) && gMansion_Map.Visible == false && gQuit_Dialog.Visible == false) {
  13.     if (cDan.Room == 2){
  14.       ResetRoom(3);
  15.       ResetRoom(4);
  16.       cDan.ChangeRoom(3, 624, 400, eDirectionLeft); // Pressing the S key starts game from the Options Screen.
  17.     }
  18.   }
  19.  
  20.  
  21.   // THE L KEY (RESTORE CHECKPOINT).
  22.   //--------------------------------
  23.   if (IsKeyPressed(eKeyL) && gMansion_Map.Visible == false && gQuit_Dialog.Visible == false) {
  24.     RestoreCheckpoint(); // Pressing the L key restores the Saved Checkpoint.
  25.   }
  26.  
  27.  
  28.   // THE Q KEY (SHOWS THE QUIT DIALOG) AND PRESSING KEYS Y=YES AND N=NO.
  29.   //--------------------------------------------------------------------
  30.   if (IsKeyPressed(eKeyQ) && gMansion_Map.Visible == false) {
  31.     gQuit_Dialog.Visible = true;
  32.   }
  33.  
  34.   if (gQuit_Dialog.Visible == true) {
  35.     if (cDan.Room == 2) {
  36.       if (IsKeyPressed(eKeyY)) {
  37.         QuitGame(0);
  38.       }
  39.     }
  40.   }
  41.  
  42.   if (gQuit_Dialog.Visible == true) {
  43.     if (cDan.Room == 2) {
  44.       if (IsKeyPressed(eKeyN)) {
  45.         gQuit_Dialog.Visible = false;
  46.       }
  47.     }
  48.   }
  49.  
  50.   if (gQuit_Dialog.Visible == true) {
  51.     if (cDan.Room == 3 || cDan.Room == 4) {
  52.       if (IsKeyPressed(eKeyY)) {
  53.         RestartGame();
  54.       }
  55.     }
  56.   }
  57.  
  58.   if (gQuit_Dialog.Visible == true) {
  59.     if (cDan.Room == 3 || cDan.Room == 4) {
  60.       if (IsKeyPressed(eKeyN)) {
  61.         gQuit_Dialog.Visible = false;
  62.       }
  63.     }
  64.   }
  65.  
  66.  
  67.   // THE R KEY (REDIFINE PLAYING KEYS).
  68.   //-----------------------------------
  69.   if (IsKeyPressed(eKeyR) && gMansion_Map.Visible == false && gQuit_Dialog.Visible == false) {
  70.     StartKeySetup();
  71.   }
  72.  
  73.  
  74.   // THE P KEY (MANSION PLANS).
  75.   //---------------------------
  76.   if (keycode == eKeyP) { // Pressing the P key (in game) show the Mansion Plans Screen.
  77.     if (gQuit_Dialog.Visible == false) {
  78.       if (gMansion_Map.Visible == true) gMansion_Map.Visible = false;
  79.       else gMansion_Map.Visible = true;
  80.       if (gInventory.Visible == true) gInventory.Visible = false;
  81.       else gInventory.Visible = true;
  82.       if (cDan.Room == 2) { // However, If the P key is pressed on the Options Screen...
  83.         gMansion_Map.Visible = false; // The Mansion Plans are not shown...
  84.         gInventory.Visible = false; // Neither is the Inventory Screen.
  85.       }
  86.     }
  87.   }
  88.  
  89.  
  90.   // THE M KEY (STOP OR START MUSIC).
  91.   //---------------------------------
  92.   if (IsKeyPressed(eKeyM)) {
  93.     if (Game.IsAudioPlaying(eAudioTypeMusic)) {
  94.       aThe_Builder.Stop();
  95.     }
  96.     else {
  97.       if (IsKeyPressed(eKeyM)) {
  98.         aThe_Builder.Play();
  99.       }
  100.     }
  101.   }
  102.    
  103.   if (IsGamePaused()) keycode = 0; // game paused, so don't react to keypresses.
  104. }  
  105. // END OF 'ON_KEY_PRESS' SCRIPT.
  106. // -----------------------------

Thank you for your help.

Yours.
Jay.
« Last Edit: 20 Nov 2014, 11:35 by RetroJay »
  Master Decorator

Crimson Wizard

  • Posts: 8,794
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Lifetime Achievement Award Winner
    • Crimson Wizard worked on a game that won an AGS Award!
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
Re: Re-define the keys.
« Reply #4 on: 20 Nov 2014, 11:34 »
Where you have '... move up/down'. Am I supposed to put more lines of code there?
Yes, you are :)

If so, then what? :-[ :-[ :-[
You said you are using KeyboardMovement module. You may just edit the "on_key_press" code there, replacing the use of key constants with variables.
If you do, you will also have to move variable declaration to that module.


EDIT: BTW KeyboardMovement module alredy has all variables declared!
Code: Adventure Game Studio
  1. // keycodes as variables for future key customization functions (static variables?):
  2. int KeyboardMovement_KeyDown = 380; // down arrow
  3. int KeyboardMovement_KeyLeft = 375; // left arrow
  4. int KeyboardMovement_KeyRight = 377; // right arrow
  5. int KeyboardMovement_KeyUp = 372; // up arrow
  6. int KeyboardMovement_KeyDownRight = 381; // PgDn (numpad)
  7. int KeyboardMovement_KeyUpRight = 373; // PgUp (numpad)
  8. int KeyboardMovement_KeyDownLeft = 379; // End (numpad)
  9. int KeyboardMovement_KeyUpLeft = 371; // Home (numpad)
  10. int KeyboardMovement_KeyStop = 376; // 5 (numpad)
  11.  

Just use these.
« Last Edit: 20 Nov 2014, 11:36 by Crimson Wizard »

RetroJay

  • Posts: 537
  • Frankly, my dear, I'm a Kerbal and Proud of it.
    • RetroJay worked on a game that was nominated for an AGS Award!
Re: Re-define the keys.
« Reply #5 on: 20 Nov 2014, 12:39 »
Hi Crimson Wizard.

I really do appreciate your help on this matter...However.
This, I'm afraid, has beaten me.>:(

I haven't got a clue what I'm doing nor do I understand what you are talking about.(sorry to be so dim).(laugh)
People will just have to use the keys I tell them to and like it.;)

Yours.
Jay.
  Master Decorator

Crimson Wizard

  • Posts: 8,794
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    • Lifetime Achievement Award Winner
    • Crimson Wizard worked on a game that won an AGS Award!
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
Re: Re-define the keys.
« Reply #6 on: 20 Nov 2014, 13:12 »
RetroJay, you give up way too early!!

As I wrote above, KeyboardMovement module already has everything set up.
All you need is to export its key variables and use them in your redefine code, which, as you said, is already working.

in KeyboardMovement.ash:
Code: Adventure Game Studio
  1. import int KeyboardMovement_KeyDown;
  2. import int KeyboardMovement_KeyLeft;
  3. import int KeyboardMovement_KeyRight;
  4. import int KeyboardMovement_KeyUp;
  5. import int KeyboardMovement_KeyDownRight;
  6. import int KeyboardMovement_KeyUpRight;
  7. import int KeyboardMovement_KeyDownLeft;
  8. import int KeyboardMovement_KeyUpLeft;
  9. import int KeyboardMovement_KeyStop;
  10.  
in KeyboardMovement.asc, beyond line 35:
Code: Adventure Game Studio
  1. export KeyboardMovement_KeyDown;
  2. export KeyboardMovement_KeyLeft;
  3. export KeyboardMovement_KeyRight;
  4. export KeyboardMovement_KeyUp;
  5. export KeyboardMovement_KeyDownRight;
  6. export KeyboardMovement_KeyUpRight;
  7. export KeyboardMovement_KeyDownLeft;
  8. export KeyboardMovement_KeyUpLeft;
  9. export KeyboardMovement_KeyStop;
  10.  

In GlobalScript, where you redefine keys, use the variables from KeyboardMovement module:
Code: Adventure Game Studio
  1. void RecordSetupKey(eKeyCode keycode)
  2. {
  3.     if (KeySetupStep == 1)
  4.         KeyboardMovement_KeyUp = keycode;
  5.     else if (KeySetupStep == 2)
  6.         KeyboardMovement_KeyDown = keycode;
  7.     ... etc
  8.     // other keys
  9.  
  10.     NextKeySetupStep();
  11. }
  12.  
« Last Edit: 20 Nov 2014, 13:16 by Crimson Wizard »

RetroJay

  • Posts: 537
  • Frankly, my dear, I'm a Kerbal and Proud of it.
    • RetroJay worked on a game that was nominated for an AGS Award!
Re: Re-define the keys.
« Reply #7 on: 20 Nov 2014, 14:39 »
Hi Crimson Wizard.

Ha...Haa!

I see it all now, some of it.
That works like a charm.;-D

Thank you ever so much for your help and patience.(roll)
I really do appreciate it.

All I want to do now is see if I can find a way of excluding some keys, Menu Keys, from being re-definable.
I will have a play and see if I can work that out myself before I trouble you again for your expertise.;)

Yours.
Jay.

  Master Decorator

Vincent

  • Posts: 338
    • I can help with play testing
    • I can help with scripting
    • I can help with translating
Re: Re-define the keys.
« Reply #8 on: 20 Nov 2014, 15:40 »
I'm out of topic here
But this Module is just AMAZING

http://www.adventuregamestudio.co.uk/forums/index.php?topic=42843.msg568552#msg568552


Key binding commands

KeyboardMovement.SetKey(eKMKey key, eKeyCode k);
Assigns ASCII code k to movement key key.
Example:  KeyboardMovement.SetKey(eKMKeyLeft, eKeyLeftArrow);