Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: iamlowlikeyou on Wed 19/01/2011 10:00:01

Title: GUI buttons and InventoryWindow KEYBOARD CONTROL [SOLVED]
Post by: iamlowlikeyou on Wed 19/01/2011 10:00:01
I am working on a game that has only keyboard control, no mouse at all.

I need a control panel for save/load/exit functions, and an inventory window.
I want to make them as "popups" that are made visible by press key.
So far so good...

Now I'm in search of ideas for how to make them controllable.
Basically both controls have to be a line of icons that appear at the edge of the screen, and then switched between by the cursor keys.

I am thinking that the control panel could be done with 6 images, one for each control selected and unselected, and then it could be written as "if this selected and cursor left, then deselect and select that"... I don't know if that's a "clumsy" method - perhaps there's a most much more elegant way to do it?
Anyway my greatest problem is how to do the inventory, because the icons in the inventory will not be arranged the same way every time in the nature of an inventory... But of course there is a way, I just haven't thought of it yet :)
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: barefoot on Wed 19/01/2011 10:41:05
Hi

check the manual and here  for GUI customising.

You can completely customise any new/or old GUI's in which to do what you are looking for.

barefoot
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: iamlowlikeyou on Wed 19/01/2011 10:54:31
Thanks!
Sorry, I didn't think keyboard control of gui was in the manual :S

I'll check it, and remember to check next time before posting.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: Khris on Wed 19/01/2011 15:48:36
Disregard barefoot's comment, it isn't in the manual.

I'll get back to you.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: Khris on Thu 20/01/2011 00:03:50
Double-post to bump this.

How do you want the save/load system to be handled?
Because I was thinking that naming savegames using the keyboard is fine for a keyboard controlled game obviously, but to my mind, keyboard control is just the first step to make the game gamepad controlled (via JoyToKey or the plugin (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=41658.0)).
It's going to be pretty annoying to have to put down the pad and enter the save game name using the keyboard.
With console games you usually just select a slot that indicates time of play and/or location, without the possibility to name them.
This is a bit harder to do in AGS but possible and would be much more streamlined.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: iamlowlikeyou on Thu 20/01/2011 15:50:09
Didn't see the last comments until now...

@Khris: Well, this is for the same interface you already helped me so much with, so the game is keyboard controlled. And at least to begin with I'll keep it like that...
What I want is just a simple popup GUI in top of screen (like the one in the default game, except this one should become visible at key press and not mouse move to top of screen).
Then I suppose it should be made with buttons containing normal graphics and mouse-over graphics.
A default button is highlighted (that is set to mouse-over graphic) when the GUI becomes visible, and then by pressing left- or right-key player can switch between the buttons.
The buttons should probably just be "save", "load" and "quit" I think.

Save and load both opens a new GUI, controlled in the same way - except switching up and down instead of left and right, and then player just custom name the savegames like standard (this is basically a standard adventure game story-wise, so it makes more sense to name the savegames instead of automatically naming them time and date).
Quit just opens a "yes" or "no" GUI.

And that's it.
BTW I want my Inventory window to be the same way, just in the bottom of the screen...

----------

EDIT:

I came up with this code trying to make at least the switches available (the mouse.SetBounds values are the button areas - perhaps the method is a little (or very) clumsy, but it was the best I could come up with at the moment)... I put it in the function on_key_press(eKeyCode keycode) section of the globalscript.


  bool SaveGameButtonActive = false;
  bool LoadGameButtonActive = false;
  bool QuitGameButtonActive = false;
 
  if (keycode == eKeyEscape){
    if (gIconbar.Visible == false){
      gIconbar.Visible = true;
      PauseGame();
      mouse.SetBounds(200, 10, 210, 20);
      SaveGameButtonActive = true;
    }
    else if (gIconbar.Visible == true){
      gIconbar.Visible = false;
      UnPauseGame();
    }
  }
 
  if (keycode == eKeyLeftArrow){
    if (SaveGameButtonActive == true){
      mouse.SetBounds(260, 10, 270, 20);
      SaveGameButtonActive = false;
      QuitGameButtonActive = true;
      }
      else if (LoadGameButtonActive == true){
        mouse.SetBounds(200, 10, 210, 20);
        LoadGameButtonActive = false;
        SaveGameButtonActive = true;
      }
      else if (QuitGameButtonActive == true){
        mouse.SetBounds(230, 10, 250, 20);
        QuitGameButtonActive = false;
        LoadGameButtonActive = true;
      }
      else {}
  }
  if (keycode == eKeyRightArrow){
    if (SaveGameButtonActive == true){
      mouse.SetBounds(230, 10, 250, 20);
      SaveGameButtonActive = false;
      LoadGameButtonActive = true;
    }
    else if (LoadGameButtonActive == true){
      mouse.SetBounds(260, 10, 270, 20);
      LoadGameButtonActive = false;
      QuitGameButtonActive = true;
    }
    else if (QuitGameButtonActive == true){
      mouse.SetBounds(200, 10, 210, 20);
      QuitGameButtonActive = false;
      SaveGameButtonActive = true;
    }
    else {}
  }


It doesn't work however. I can't figure out why...
It doesn't respond to arrow key press at all. I don't know if I'm using the bools correctly?
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: Khris on Thu 20/01/2011 17:19:41
You need to move the three bool lines at the top to the outside, above "function on_key_press(..."
If they are defined inside the function, they are re-initialized i.e. start out as false every time the function is run again i.e. every time a key is pressed.
They only retain their value if they are defined outside any function.

You don't need to initialize them as false btw, bools are false by default.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: iamlowlikeyou on Thu 20/01/2011 17:23:29
Ah, I see. Thank you!

Quote from: Khris on Thu 20/01/2011 17:19:41
You don't need to initialize them as false btw, bools are false by default.

Yeah, I actually thought so too, but I wrote it in to be absolutely sure ;)

Is there a more elegant way to make the mouse point on the buttons, or would you say this is an alright method?
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: monkey0506 on Thu 20/01/2011 17:44:38
I'd recommend using mouse.SetPosition instead of mouse.SetBounds. I don't understand the reason for your boolean variables either. If you're simply tracking which Button the mouse (which as you said is not in fact being controlled by the mouse) is over, I'd recommend using a Button* instead:

Button *mouseOverButton;

// ..Save button active
mouseOverButton = btnSave;

// ..Load button active
mouseOverButton = btnLoad;

// ..Quit button active
mouseOverButton = btnQuit;


Also, how are you handling processing the clicks on the GUIs/GUIControls? There's no way to generically simulate it, so I guess you're probably just calling the click event handlers manually?

@Khris: Regarding what you said about mapping the mouse functions to keyboard keys in order to use JoyToKey..that's not necessary. I'm not sure about the AGS-specific plugin, but the JoyToKey program supports changes in mouse position, mouse clicks, scrolling the mouse wheel, etc. as functions that can be mapped to joypad buttons, joysticks, triggers, etc. So that wouldn't be necessary to use the JoyToKey program for an AGS game. However, allowing total control via the keyboard is not unheard of. I'm not well versed in adventure games to be honest, but The Secret of Monkey Island on PC allowed total control of everything in the game via the keyboard.
 
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: iamlowlikeyou on Thu 20/01/2011 18:01:49
I'm still a newbie in scripting, so bear with me on this :)

I used mouse.SetPosition at first, but then the player would be able to move the mouse away from the button again. So I used the mouse.SetBound to "lock" the mouse to the buttons.

How does Button* work? I mean basically, because I have no idea what the * means.

Quote from: monkey_05_06 on Thu 20/01/2011 17:44:38
Also, how are you handling processing the clicks on the GUIs/GUIControls? There's no way to generically simulate it, so I guess you're probably just calling the click event handlers manually?  

I haven't gotten to the actual clicks yet, but I figured there must be a way to do something like "on key press push the button which mouse is over"?
Well, it's probably easier to just use the bools here also... (or the button*, when I understand that ;))
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: Khris on Thu 20/01/2011 18:15:12
iamlowlikeyou:
It works just like "Hotspot*h;", the * has to be used if you're declaring a Pointer, as opposed to e.g. an int or bool.
It doesn't matter if you write "Button* b" or "Button *b" or "Button*b", the asterisk has to be there though.

You can set the mouse coordinates directly. (mouse.x = 100;)
The thing is, I wouldn't use the mouse at all, I'd use gCursor. If the menu GUI's visibility is set to "Pause game when shown", NoMouse's rep_ex won't steal the cursor since it doesn't run when the game is paused.
Basically, set gCursor's position to the button's, like this:

GUIControl*gc_active;

void PointAt(GUIControl*gc) {
  bMode.NormalGraphic = mouse.GetModeGraphic(eModePointer);
  int x = gc.OwningGui.x + gc.x + 10;
  int y = gc.OwningGui.y + gc.y + 10;
  gCursor.SetPosition(x, y);
  gc_active = gc;
}


I was thinking of a way how to implement keyboard driven menus quickly and easily; I didn't get around to actually coding it yet though. I'd assign four direction properties to each control, e.g. the save button's "left" property would point to the quit button. So on a left arrow press, AGS would read the current control's left property and move the cursor to that.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: monkey0506 on Thu 20/01/2011 18:27:40
Look up pointers in the manual for more information on what the * means.

Khris, what is the +10 for? If you were using -10 then I could assume that it was half the graphic's width, but I can't seem to grasp why you'd be using +10.

Also, if it is for offsetting based on the graphic's width, you could use (Game.SpriteWidth[bMode.NormalGraphic] / 2) instead to make it generic.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: iamlowlikeyou on Thu 20/01/2011 18:35:13
To be honest I can't get my head around this right now.
I'll try to read it again tomorror, and perhaps I'll understand it then...
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: Khris on Thu 20/01/2011 19:34:34
monkey:
gCursor is a GUI we're using with a button (bMode) at 0,0.
Thus if we put the Pointer graphic (hotspot: 0,0) on that button and the GUI at 10,10 of the button we're pointing at, the tip of the pointer arrow is at the button's 10,10.
To make it generic, I'd have to use half the dimensions of the button it's pointing at.

It's not perfect, it was just to get iamlowlikeyou started.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: monkey0506 on Thu 20/01/2011 21:57:18
Perhaps this isn't the place for this discussion, but the purpose of generics is so that it doesn't matter if, for example iamlowlikeyou only creates a button that is 8x8 instead of 10x10.

It wouldn't be difficult to simply use (bMode.Width / 2) or (Game.SpriteWidth[bMode.NormalGraphic] / 2) to make it completely generic so that regardless of the width of the button that iamlowlike you (or any other user) might create, the code will still work.

IMO it's not helpful or beneficial to use arbitrary values without explaining why they're there, or what setup it is inherently reliant upon to work. Generics avoid that type of problem.
Title: Re: GUI buttons and InventoryWindow KEYBOARD CONTROL
Post by: Khris on Thu 20/01/2011 22:52:23
I'm perfectly aware of all this, the thing is that I'm currently more or less building the whole game mechanics for iamlowlikeyou and adding a keyboard controlled GUI is already on my plate.
The code was intended as a temporary solution so he can focus on other aspects in case it takes me longer as I think to get 'round to coding that.