[SOLVED!] Keyboard cursor control (re-opened for discussion)

Started by monkey0506, Sun 12/09/2004 01:52:49

Previous topic - Next topic

monkey0506

See lastest post for confession of my presumptious presumptions, and another not-really-that-important "problem".  :P

SEE THE LAST POST FOR LASTEST SCRIPT INFO.

In order to provide both keyboard and mouse cursor control, I have the following script:

Code: ags
#sectionstart on_eventÃ,  //DO NOT EDIT OR REMOVE THIS LINE
function on_event(int event, int data){
Ã,  if ((event==GUI_MDOWN) && (data==MAIN)){
Ã,  Ã,  if (GetGUIObjectAt(mouse.x, mouse.y)==1){
Ã,  Ã,  Ã,  SetMode(give);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1)Ã,  SetButtonPic(MAIN, 1, 1, 11);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 1, 1, 2);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==2){
Ã,  Ã,  Ã,  SetMode(open);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 2, 1, 12);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 2, 1, 3);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==3){
Ã,  Ã,  Ã,  SetMode(close);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 3, 1, 13);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 3, 1, 4);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==4){
Ã,  Ã,  Ã,  SetMode(pickup);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 4, 1, 14);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 4, 1, 5);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==5){
Ã,  Ã,  Ã,  SetMode(lookat);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 5, 1, 15);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 5, 1, 6);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==6){
Ã,  Ã,  Ã,  SetMode(talkto);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 6, 1, 16);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 6, 1, 7);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==7){
Ã,  Ã,  Ã,  SetMode(use);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 7, 1, 17);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 7, 1, 8);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==8){
Ã,  Ã,  Ã,  SetMode(push);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 8, 1, 18);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 8, 1, 9);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (GetGUIObjectAt(mouse.x, mouse.y)==9){
Ã,  Ã,  Ã,  SetMode(pull);
Ã,  Ã,  Ã,  if (IsKeyPressed(keyenter)==1) SetButtonPic(MAIN, 9, 1, 19);
Ã,  Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) SetButtonPic(MAIN, 9, 1, 10);
Ã,  Ã,  Ã,  }
Ã,  Ã,  }
Ã,  else if ((event==GUI_MUP) && (data==MAIN)){
Ã,  Ã,  SetButtonPic(MAIN, 1, 1, 2);
Ã,  Ã,  SetButtonPic(MAIN, 2, 1, 3);
Ã,  Ã,  SetButtonPic(MAIN, 3, 1, 4);
Ã,  Ã,  SetButtonPic(MAIN, 4, 1, 5);
Ã,  Ã,  SetButtonPic(MAIN, 5, 1, 6);
Ã,  Ã,  SetButtonPic(MAIN, 6, 1, 7);
Ã,  Ã,  SetButtonPic(MAIN, 7, 1, 8);
Ã,  Ã,  SetButtonPic(MAIN, 8, 1, 9);
Ã,  Ã,  SetButtonPic(MAIN, 9, 1, 10);
Ã,  Ã,  }
Ã,  }
#sectionend on_eventÃ,  //DO NOT EDIT OR REMOVE THIS LINE

function KeyControls(){
Ã,  if (IsKeyPressed(keyg)==1) SetMode(give);
Ã,  if (IsKeyPressed(keyo)==1) SetMode(open);
Ã,  if (IsKeyPressed(keyc)==1) SetMode(close);
Ã,  if (IsKeyPressed(keyl)==1) SetMode(lookat);
Ã,  if (IsKeyPressed(keyp)==1) SetMode(pickup);
Ã,  if (IsKeyPressed(keyt)==1) SetMode(talkto);
Ã,  if (IsKeyPressed(keyu)==1) SetMode(use);
Ã,  if (IsKeyPressed(keys)==1) SetMode(push);
Ã,  if (IsKeyPressed(keyy)==1){
/*Ã,  Ã,  if (IsGUIOn(WIN)==1){
Ã,  Ã,  Ã,  //script for win
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (IsGUIOn(QUIT)==1){
Ã,  Ã,  Ã,  //script for quit
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if (IsGUIOn(RESTART)==1){
Ã,  Ã,  Ã,  //script for restart
Ã,  Ã,  Ã,  }
Ã,  Ã,  else{*/
Ã,  Ã,  Ã,  SetMode(pull);
//Ã,  Ã,  Ã,  }
Ã,  Ã,  }
Ã,  if (IsKeyPressed(keyup)==1) SetMousePosition(mouse.x, mouse.y-2);
Ã,  if (IsKeyPressed(keydown)==1) SetMousePosition(mouse.x, mouse.y+2);
Ã,  if (IsKeyPressed(keyleft)==1) SetMousePosition(mouse.x-2, mouse.y);
Ã,  if (IsKeyPressed(keyright)==1) SetMousePosition(mouse.x+2, mouse.y);
Ã,  if (GetGUIAt(mouse.x, mouse.y)!=-1){
Ã,  Ã,  if (IsKeyPressed(keyenter)==1) on_event(GUI_MDOWN, MAIN);
Ã,  Ã,  else if (IsKeyPressed(keyenter)==0) on_event(GUI_MUP, MAIN);
Ã,  Ã,  }
Ã,  }


and:

Code: ags
#sectionstart repeatedly_executeÃ,  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute(){
Ã,  // put anything you want to happen every game cycle here
Ã,  UpdateLabelBar();
Ã,  KeyControls();
Ã,  }
#sectionend repeatedly_executeÃ,  // DO NOT EDIT OR REMOVE THIS LINE


The script works fine, with one small problem. I can move the mouse cursor with both the arrow buttons and the mouse, and I can click on my GUI's buttons with both the mouse and the enter key. The problem: If I hold enter down, and move the mouse cursor (by either method), it selects (highlights) multiple buttons, and then returns them to normal when enter is released, and stops changing the cursor mode (with each button the cursor is moved over while enter is pressed, it changes the cursor mode). So, how can I tell the game that if you press enter while the cursor is over a button, to change the cursor mode, if enter is held, to leave the button highlighted, and when enter is release to restore the button pictures UNLESS the cursor is moved OFF the button that enter is initially pressed over. I know this sounds very confusing (at least to me), but that's why I'm asking for help...Ã,  :P

Edwin Xie

Wow, it sounds really confusing. Selects multiple buttons? Change cursor mode? Oh, you mean the iconbar. Happens to me. I posted for help on that in the beginner technical forum. So, you mean.....nevermind. I don't know what you were talking about.
Moving at superhigh speed getting to the planet called Earth. But it is boxed in white......thing.....

monkey0506

In order to give the buttons the appearance that they are pressed (even though they are not) when you press enter while the cursor is over a button, I changed the normal button picture. But my script doesn't set the button picture back to normal when the cursor is moved off of the button. I kind of know why, but my attempts keep messing it up even worse and worse. My latest attempt now sets the cursor mode as soon as the mouse moves over the button irregardless of whether enter is pressed or not, and highlights the button, and the highlight (pushed image) only goes away when you press enter, and if you don't move the cursor while enter is pressed, the button will revert to the pushed image again...

Pumaman

When enter is pressed down over a button, save the button number into a variable, and check it again next time. For example

if (pressedOnButton != GetGUIObjectAt(mouse.x, mouse.y)) {
  SetButtonPic(MAIN, pressedOnButton, 1, pressedOnButton + 1);
}

pressedOnButton = GetGUIObjectAt(mouse.x, mouse.y);

assuming you declare 'int pressedOnButton' at the top of the global script. Something along these lines, which remembers the last button pressed and then resets its image if the cursor is no longer over the button, should do the trick.


Oh, Edwin Xie, please don't post in this forum unless you have something useful to add to a thread.

monkey0506

#4
Um... There's a problem with your example. It repeatedly changes the pressed button to whichever button the cursor is over. It works ok, but I still have the same problem. Moving the cursor still allows for multiple pushed buttons at once...Ã,  :-[ ??? :-X :-\ :'( >:(

EDIT: The problem is that GetGUIObjectAt(mouse.x, mouse.y) is a repeatedly changing item. It shows the object that the mouse is over, so it has to be able to change. I need to find a way to say that once the mouse is clicked (with enter) to stop updating GetGUIObjectAt(mouse.x, mouse.y) until enter is released. So basically while (IsKeyPressed(keyenter)==1) StopUpdatingGetGUIObjectAt(); Something like that would work if I knew how to program a function that could do that...

Pumaman

Yeah, I was just providing some example code to point you in the right direction, I wouldn't expect it to completely solve the problem.

I'm afraid I haven't got time right now to load it all up into a game and try it out, which would be the best way to work out what your solution requires.

monkey0506

#6
Yes, of course. But still, I still don't know how to fix the problem. I feel honored that the great Pumaman has made an attempt to help, but does anyone else have any other ideas?

EDIT: I'm thinking something with SetGUIObjectEnabled... Ok, I've been working with it, and now I have something that's nearly perfect. I'm not done with all the buttons, just give with this new script, so I'll do this script for all the buttons, then post it...

EDIT: I didn't realize how long my global script is getting. I'll go back and pick out the scripts...

Following game_start():
Code: ags
function EnableGUIObject(int enabled){
  SetGUIObjectEnabled(MAIN, 1, 0);
  SetGUIObjectEnabled(MAIN, 2, 0);
  SetGUIObjectEnabled(MAIN, 3, 0);
  SetGUIObjectEnabled(MAIN, 4, 0);
  SetGUIObjectEnabled(MAIN, 5, 0);
  SetGUIObjectEnabled(MAIN, 6, 0);
  SetGUIObjectEnabled(MAIN, 7, 0);
  SetGUIObjectEnabled(MAIN, 8, 0);
  SetGUIObjectEnabled(MAIN, 9, 0);
  if (enabled==1) SetGUIObjectEnabled(MAIN, 1, 1);//enable give button
  else if (enabled==2) SetGUIObjectEnabled(MAIN, 2, 1);//enable open button
  else if (enabled==3) SetGUIObjectEnabled(MAIN, 3, 1);//enable close button
  else if (enabled==4) SetGUIObjectEnabled(MAIN, 4, 1);//enable pick up button
  else if (enabled==5) SetGUIObjectEnabled(MAIN, 5, 1);//enable look at button
  else if (enabled==6) SetGUIObjectEnabled(MAIN, 6, 1);//enable talk to button
  else if (enabled==7) SetGUIObjectEnabled(MAIN, 7, 1);//enable use button
  else if (enabled==8) SetGUIObjectEnabled(MAIN, 8, 1);//enable push button
  else if (enabled==9) SetGUIObjectEnabled(MAIN, 9, 1);//enable pull button
  else if (enabled==0) {}//leave all buttons disabled
  }

#sectionstart on_event  //DO NOT EDIT OR REMOVE THIS LINE
function on_event(int event, int data){
  if ((event==GUI_MDOWN) && (data==MAIN)){
    if (IsKeyPressed(keyenter)==1){
      PressedOnButton=EnabledGUIObject;
      if (PressedOnButton==1){
        SetMode(give);
        SetButtonPic(MAIN, 1, 1, 11);
        }
      else if (PressedOnButton==2){
        SetMode(open);
        SetButtonPic(MAIN, 2, 1, 12);
        }
      else if (PressedOnButton==3){
        SetMode(close);
        SetButtonPic(MAIN, 3, 1, 13);
        }
      else if (PressedOnButton==4){
        SetMode(pickup);
        SetButtonPic(MAIN, 4, 1, 14);
        }
      else if (PressedOnButton==5){
        SetMode(lookat);
        SetButtonPic(MAIN, 5, 1, 15);
        }
      else if (PressedOnButton==6){
        SetMode(talkto);
        SetButtonPic(MAIN, 6, 1, 16);
        }
      else if (PressedOnButton==7){
        SetMode(use);
        SetButtonPic(MAIN, 7, 1, 17);
        }
      else if (PressedOnButton==8){
        SetMode(push);
        SetButtonPic(MAIN, 8, 1, 18);
        }
      else if (PressedOnButton==9){
        SetMode(pull);
        SetButtonPic(MAIN, 9, 1, 19);
        }
      }
    }
  else if ((event==GUI_MUP) && (data==MAIN)){
    SetButtonPic(MAIN, 1, 1, 2);
    SetButtonPic(MAIN, 2, 1, 3);
    SetButtonPic(MAIN, 3, 1, 4);
    SetButtonPic(MAIN, 4, 1, 5);
    SetButtonPic(MAIN, 5, 1, 6);
    SetButtonPic(MAIN, 6, 1, 7);
    SetButtonPic(MAIN, 7, 1, 8);
    SetButtonPic(MAIN, 8, 1, 9);
    SetButtonPic(MAIN, 9, 1, 10);
    }
  }
#sectionend on_event  //DO NOT EDIT OR REMOVE THIS LINE

function KeyControls(){
  if (IsKeyPressed(keyup)==1) SetMousePosition(mouse.x, mouse.y-2);
  if (IsKeyPressed(keydown)==1) SetMousePosition(mouse.x, mouse.y+2);
  if (IsKeyPressed(keyleft)==1) SetMousePosition(mouse.x-2, mouse.y);
  if (IsKeyPressed(keyright)==1) SetMousePosition(mouse.x+2, mouse.y);
  if (PressedOnButton!=GetGUIObjectAt(mouse.x, mouse.y)) on_event(GUI_MUP, MAIN);
  }


repeatedly_execute():
Code: ags
#sectionstart repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute(){
  // put anything you want to happen every game cycle here
  if (GetGUIObjectAt(mouse.x, mouse.y)==-1) EnableGUIObject(0);
  else{
    EnableGUIObject(GetGUIObjectAt(mouse.x, mouse.y));
    EnabledGUIObject=GetGUIObjectAt(mouse.x, mouse.y);
    }
  UpdateLabelBar();
  KeyControls();
  if (IsKeyPressed(keyenter)==0) on_event(GUI_MUP, MAIN);
  }
#sectionend repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE


At the end of on_key_press(int keycode):
Code: ags
  if (keycode==keyenter) on_event(GUI_MDOWN, MAIN);


That's it. The script works, only, moving the mouse BACK over the pressed button doesn't re-highlight it... But I think that's ok... I'll declare this as solved now. Thanks for inspiring me to solve my own problems Pumaman!

monkey0506

#7
Although I said this problem was solved, please feel free (aka PLEASE) check over my script to check for redundancies and things like that. Thanks!Ã,  :P

EDIT: I found a bug in my script, well, I'm not sure that I found it, but I see it in the game. If you start moving the cursor in a straight line, then press and hold enter, it will press all the buttons in that line... Does anyone know why this is? Or more importantly, how to stop this?

Pumaman

As the cursor passes over each button if Enter is down, it presses it? Surely this is what you want?

monkey0506

EDIT: Please notice that the feature/problem numbering has changed.

No, that's not right. I'm sorry if I've been confusing. I want it to react like the mouse, so that if you press enter, it reacts like a left mouse button... I did at one point try using interface_click and on_mouse_click and on_key_press, but my scripts didn't work. I kept needing to re-arrange them, and eventually I couldn't get them to stop producing errors. Ok, so what I want to be able to do:

1. If the arrow key(s) are pressed, move the mouse cursor in the appropriate direction.
2. If the mouse is over a button, and enter is pressed, set the cursor to the appropriate mode, and highlight the button that enter was pressed over.
3. If the cursor leaves the GUI button, restore the normal button picture, but if enter is still held, and then the cursor is returned to the SAME button, re-highlight the button.
4. If enter is released, set the button pictures back to normal.
5. The cursor mode should only be set if the button (mouse or enter) is released over the GUI button it was originally pressed over.

So, no, I don't want it to highlight just any button. I just want to press the button that enter is initially pressed over. And I don't think you understood the problem. Here is how it is currently reacting:

1. If the arrow key(s) are pressed, it moves the mouse cursor in the appropriate direction. (this works)
2. If the mouse is over a button, and enter is pressed, it sets the cursor to the appropriate mode, and highlights the button that enter was pressed over. (this works)
3. If the cursor leaves the GUI button, it restores the normal button picture, but if enter is still held, and then the cursor is returned to the SAME button, it DOES NOT re-highlight the button. (this does not work)
4. If enter is released, it sets the button pictures back to normal. (this works)
5. The cursor mode is only set if the button (mouse or enter) is released over the GUI button it was originally pressed over. (this works)
6. If the mouse cursor is moving in a STRAIGHT line, and enter is pressed and held while the cursor is moving, it highlights all the buttons in that line, and sets the appropriate modes. It does return each button picture to normal as the cursor leaves the button. (this should not exsist)

As you can see, #3 does not work, and #6 shouldn't exsist. I hope I've made myself a little clearer as to the problem.

EDIT: #3 now works... I edited on_event and on_key_press by a little. In on_event, I removed the line (PressedOnButton=EnabledGUIObject;), and put it in brackets with the (if (keycode==keyenter) on_event(GUI_MDOWN, MAIN);) line, so it now reads:

Code: ags
if (keycode==keyenter){
Ã,  PressedOnButton=EnabledGUIObject;
Ã,  on_event(GUI_MDOWN, MAIN);
Ã,  }


In comparison to the previous scripts. Please notice that Problem #6, which should not exsist, is still exsistent. So #6 still needs to be fixed.

Scorpiorus

QuoteIf the mouse cursor is moving in a STRAIGHT line, and enter is pressed and held while the cursor is moving, it highlights all the buttons in that line, and sets the appropriate modes. It does return each button picture to normal as the cursor leaves the button. (this should not exsist)
Yes, that's because IsKeyPressed returns 1 when a key is being held down, not only when you press it. You could write a script to distinguish between the on key press, on key hold and on key release events. Here is an example for the enter key but the script can be generalized to use with any other key:

// maing global script

#define KS_NEUTRALÃ,  0
#define KS_PRESSEDÃ,  1
#define KS_HOLDÃ,  Ã,  Ã, 2
#define KS_RELEASED 3

int keycode = 13;
int enter_state = KS_NEUTRAL;

function repeatedly_execute() {

Ã,  Ã,  if (IsKeyPressed(keycode))
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  if (enter_state == KS_NEUTRAL) enter_state = KS_PRESSED;
Ã,  Ã,  Ã,  Ã,  else if (enter_state == KS_PRESSED) enter_state = KS_HOLD;
Ã,  Ã,  Ã,  Ã,  else if (enter_state == KS_HOLD) enter_state = KS_HOLD;
Ã,  Ã,  Ã,  Ã,  else if (enter_state == KS_RELEASED) enter_state = KS_PRESSED;
Ã,  Ã,  }
Ã,  Ã,  else
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  if (enter_state == KS_NEUTRAL) enter_state = KS_NEUTRAL;
Ã,  Ã,  Ã,  Ã,  else if (enter_state == KS_PRESSED) enter_state = KS_RELEASED;
Ã,  Ã,  Ã,  Ã,  else if (enter_state == KS_HOLD) enter_state = KS_RELEASED;
Ã,  Ã,  Ã,  Ã,  else if (enter_state == KS_RELEASED) enter_state = KS_NEUTRAL;
Ã,  Ã,  }

}

Sort of a tiny finite-state machine :)


Thus if you need to catch the on enter key pressed event you put a condition, as follows:

if (enter_state == KS_PRESSED) {
...
}

monkey0506

Well, since I don't have time (and don't want) to update my script, I'm not going to log in... That may work. I don't know. I am doing my homework, while I'm typing this. Thanks either way! I think. I'm not sure what I'm doing...

monkey0506

Uh... It didn't work. All it did was made my problems worse. It deleted that last feature I noticed (now #5. The previous #5 is now #6). So, be prepared for a long post, this is the one with more scripts:

Following game_start():
Code: ags
#sectionstart on_eventÃ,  //DO NOT EDIT OR REMOVE THIS LINE
function on_event(int event, int data){
Ã,  if ((event==GUI_MDOWN) && (data==MAIN)){//only called when enter is pressed over a GUI button
Ã,  Ã,  if (IsKeyPressed(keyenter)==1){
Ã,  Ã,  Ã,  if (PressedOnButton==1) SetButtonPic(MAIN, 1, 1, 11);
Ã,  Ã,  Ã,  else if (PressedOnButton==2) SetButtonPic(MAIN, 2, 1, 12);
Ã,  Ã,  Ã,  else if (PressedOnButton==3) SetButtonPic(MAIN, 3, 1, 13);
Ã,  Ã,  Ã,  else if (PressedOnButton==4) SetButtonPic(MAIN, 4, 1, 14);
Ã,  Ã,  Ã,  else if (PressedOnButton==5) SetButtonPic(MAIN, 5, 1, 15);
Ã,  Ã,  Ã,  else if (PressedOnButton==6) SetButtonPic(MAIN, 6, 1, 16);
Ã,  Ã,  Ã,  else if (PressedOnButton==7) SetButtonPic(MAIN, 7, 1, 17);
Ã,  Ã,  Ã,  else if (PressedOnButton==8) SetButtonPic(MAIN, 8, 1, 18);
Ã,  Ã,  Ã,  else if (PressedOnButton==9) SetButtonPic(MAIN, 9, 1, 19);
Ã,  Ã,  Ã,  }
Ã,  Ã,  else if ((IsKeyPressed(keyenter)==0) && (PressedOnButton==GetGUIObjectAt(mouse.x, mouse.y))){
Ã,  Ã,  Ã,  if (PressedOnButton==1) SetMode(give);
Ã,  Ã,  Ã,  else if (PressedOnButton==2) SetMode(open);
Ã,  Ã,  Ã,  else if (PressedOnButton==3) SetMode(close);
Ã,  Ã,  Ã,  else if (PressedOnButton==4) SetMode(pickup);
Ã,  Ã,  Ã,  else if (PressedOnButton==5) SetMode(lookat);
Ã,  Ã,  Ã,  else if (PressedOnButton==6) SetMode(talkto);
Ã,  Ã,  Ã,  else if (PressedOnButton==7) SetMode(use);
Ã,  Ã,  Ã,  else if (PressedOnButton==8) SetMode(push);
Ã,  Ã,  Ã,  else if (PressedOnButton==9) SetMode(pull);
Ã,  Ã,  Ã,  }
Ã,  Ã,  }
Ã,  else if ((event==GUI_MUP) && (data==MAIN)){//release buttons back to their normal pictures
Ã,  Ã,  SetButtonPic(MAIN, 1, 1, 2);
Ã,  Ã,  SetButtonPic(MAIN, 2, 1, 3);
Ã,  Ã,  SetButtonPic(MAIN, 3, 1, 4);
Ã,  Ã,  SetButtonPic(MAIN, 4, 1, 5);
Ã,  Ã,  SetButtonPic(MAIN, 5, 1, 6);
Ã,  Ã,  SetButtonPic(MAIN, 6, 1, 7);
Ã,  Ã,  SetButtonPic(MAIN, 7, 1, 8);
Ã,  Ã,  SetButtonPic(MAIN, 8, 1, 9);
Ã,  Ã,  SetButtonPic(MAIN, 9, 1, 10);
Ã,  Ã,  }
Ã,  }
#sectionend on_eventÃ,  //DO NOT EDIT OR REMOVE THIS LINE

function KeyControls(){//for keyboard control of the mouse cursor
Ã,  //if the cursor is not over a GUI button, and enter is not pressed, there is no PressedOnButton
Ã,  if ((GetGUIObjectAt(mouse.x, mouse.y)<=0) && (IsKeyPressed(keyenter)==0)) PressedOnButton=0;
Ã,  if (IsKeyPressed(keyup)==1) SetMousePosition(mouse.x, mouse.y-2);//move cursor up
Ã,  if (IsKeyPressed(keydown)==1) SetMousePosition(mouse.x, mouse.y+2);//move cursor down
Ã,  if (IsKeyPressed(keyleft)==1) SetMousePosition(mouse.x-2, mouse.y);//move cursor left
Ã,  if (IsKeyPressed(keyright)==1) SetMousePosition(mouse.x+2, mouse.y);//move cursor right
Ã,  //if cursor is removed from GUI button that mouse button was pushed over, return button pic to normal
Ã,  if (PressedOnButton!=GetGUIObjectAt(mouse.x, mouse.y)) on_event(GUI_MUP, MAIN);
Ã,  else if ((PressedOnButton==GetGUIObjectAt(mouse.x, mouse.y)) && (GetGUIObjectAt(mouse.x, mouse.y)>0)) on_event(GUI_MDOWN, MAIN);
Ã,  if (IsKeyPressed(keyenter)==0) on_event(GUI_MUP, MAIN);//if enter is not currently pressed, return button pics to normal
Ã,  }


The function repeatedly_execute_always():
Code: ags
function repeatedly_execute_always(){Ã,  // put anything you want to happen every game cycle here
Ã,  on_event(GUI_MDOWN, MAIN);
Ã,  UpdateLabelBar();
Ã,  KeyControls();
Ã,  }


And, the last non-} line of on_key_press:
Code: ags
Ã,  if (keycode==keyenter) PressedOnButton=GetGUIObjectAt(mouse.x, mouse.y);//to prevent GetGUIObjectAt(mouse.x, mouse.y) from updating


Please notice that Scorpiorus's finite time machine quantum super computer hydrogen fueled car thing didn't work...

EDIT: Please notice that I haven't attempted regular mouse clicks with the enter button. I do plan to incorporate these, but I doubt that I will encounter any problems, as I should be able to do something like:

Code: ags
repeatedly_execute_always(){
//stuff
Ã,  if (IsKeyPressed(keyenter)==1){
Ã,  Ã,  if (GetGUIAt(mouse.x, mouse.y)<0){
Ã,  Ã,  Ã,  if (GetInvAt(mouse.x, mouse.y)>0) on_mouse_click(LEFTINV);
Ã,  Ã,  Ã,  else{on_mouse_click(LEFT);}
Ã,  Ã,  Ã,  }
Ã,  Ã,  //stuff
Ã,  Ã,  }
Ã,  }


Please note that this is similar to the script I will use for regular non-GUI mouse clicks controlled by the mouse button, not the final script.

EDIT: I had an idea for disabling the GUI buttons, but the idea didn't work, so I finally got around to getting rid of the excessive excessiveness.

Scorpiorus

Here is an example script:

Code: ags
// main global script file

#define KEY_UPÃ,  Ã,  372
#define KEY_DOWNÃ,  380
#define KEY_LEFTÃ,  375
#define KEY_RIGHT 377


#define KS_NEUTRALÃ,  0
#define KS_PRESSEDÃ,  1
#define KS_HOLDÃ,  Ã,  Ã, 2
#define KS_RELEASED 3

#define KEYS_MAX 400

int keys_states[KEYS_MAX];


function GetKeyState(int keycode) {
Ã,  
Ã,  Ã,  if ((keycode<0) || (keycode>=KEYS_MAX)) return KS_NEUTRAL;
Ã,  Ã,  
Ã,  Ã,  return keys_states[keycode];
}

function keys_Initialize() {

Ã,  Ã,  int keycode = 0;Ã,  
Ã,  Ã,  while (keycode < KEYS_MAX) 
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  keys_states[keycode] = KS_NEUTRAL;
Ã,  Ã,  Ã,  Ã,  keycode++;
Ã,  Ã,  }
}

function keys_UpdateState() {

Ã,  Ã,  int keycode = 0;
Ã,  Ã,  while (keycode < KEYS_MAX) 
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  int key_state = keys_states[keycode];
Ã,  Ã,  Ã,  
Ã,  Ã,  Ã,  Ã,  if (IsKeyPressed(keycode))
Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  ifÃ,  Ã,  Ã,  (key_state == KS_NEUTRAL)Ã,  keys_states[keycode] = KS_PRESSED;
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  else if (key_state == KS_PRESSED)Ã,  keys_states[keycode] = KS_HOLD;
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  else if (key_state == KS_HOLD)Ã,  Ã,  Ã, keys_states[keycode] = KS_HOLD;
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  else if (key_state == KS_RELEASED) keys_states[keycode] = KS_PRESSED;
Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  Ã,  Ã,  else
Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  ifÃ,  Ã,  Ã,  (key_state == KS_NEUTRAL)Ã,  keys_states[keycode] = KS_NEUTRAL;
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  else if (key_state == KS_PRESSED)Ã,  keys_states[keycode] = KS_RELEASED;
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  else if (key_state == KS_HOLD)Ã,  Ã,  Ã, keys_states[keycode] = KS_RELEASED;
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  else if (key_state == KS_RELEASED) keys_states[keycode] = KS_NEUTRAL;
Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã, 
Ã,  Ã,  Ã,  Ã,  keycode++;
Ã,  Ã,  }
}





#sectionstart game_startÃ,  // DO NOT EDIT OR REMOVE THIS LINE
function game_start() {
Ã,  // called when the game starts, before the first room is loaded
Ã,  
Ã,  keys_Initialize();
Ã,  
}
#sectionend game_startÃ,  // DO NOT EDIT OR REMOVE THIS LINE



function GetGUIObjectPic(int lgui, int lobj, int lwhich) {
Ã,  
Ã,  //if (<gui's obj> == BUTTON)
Ã,  Ã,  Ã,  return GetButtonPic(lgui, lobj, lwhich);
Ã,  //else return -1;
}


int buttonPic_MouseOver = -1;

int gui = -1;
int obj = -1;


#sectionstart repeatedly_executeÃ,  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
Ã,  // put anything you want to happen every game cycle here
Ã,  
Ã,  keys_UpdateState();
Ã,  
Ã,  // move move cursor:
Ã,  if (GetKeyState(KEY_UP)Ã,  Ã,  == KS_HOLD) SetMousePosition(mouse.x, mouse.y-5);
Ã,  if (GetKeyState(KEY_DOWN)Ã,  == KS_HOLD) SetMousePosition(mouse.x, mouse.y+5);
Ã,  if (GetKeyState(KEY_LEFT)Ã,  == KS_HOLD) SetMousePosition(mouse.x-5, mouse.y);
Ã,  if (GetKeyState(KEY_RIGHT) == KS_HOLD) SetMousePosition(mouse.x+5, mouse.y);
Ã,  
Ã,  
Ã,  // process clicking (enter key):
Ã,  int enter_state = GetKeyState(13);
Ã,  
Ã,  if (enter_state == KS_PRESSED)
Ã,  {
Ã,  Ã,  Ã,  gui = GetGUIAt(mouse.x, mouse.y);
Ã,  Ã,  Ã,  
Ã,  Ã,  Ã,  if (gui != -1)
Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  
Ã,  Ã,  Ã,  Ã,  Ã,  obj = GetGUIObjectAt(mouse.x, mouse.y);
Ã,  Ã,  Ã,  
Ã,  Ã,  Ã,  Ã,  Ã,  if (obj != -1)
Ã,  Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  buttonPic_MouseOver = GetGUIObjectPic(gui, obj, 2);
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  if (buttonPic_MouseOver > 0)
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, Ã,  Ã,  Ã, SetButtonPic(gui, obj, 2, GetGUIObjectPic(gui, obj, 3));
Ã,  Ã,  Ã,  Ã,  
Ã,  Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  Ã,  Ã,  Ã,  else if (GetInvAt(mouse.x, mouse.y) != -1) on_mouse_click(LEFTINV);
Ã,  Ã,  Ã,  }Ã,  
Ã,  Ã,  Ã,  else if (gui == -1) on_mouse_click(LEFT);
 
Ã,  }
Ã,  else if (enter_state == KS_RELEASED) 
Ã,  {
Ã,  Ã,  Ã,  if (obj != -1)
Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  if (buttonPic_MouseOver > 0) SetButtonPic(gui, obj, 2, buttonPic_MouseOver);
Ã,  Ã,  Ã,  Ã,  Ã,  if (GetGUIObjectAt(mouse.x, mouse.y) == obj) interface_click(gui, obj);
Ã,  Ã,  Ã,  Ã,  Ã,  obj = -1;
Ã,  Ã,  Ã,  Ã,  Ã,  gui = -1;
Ã,  Ã,  Ã,  }
Ã,  Ã,  
Ã,  }
Ã,  
Ã,  
Ã,  
Ã,  
}
#sectionend repeatedly_executeÃ,  // DO NOT EDIT OR REMOVE THIS LINE


It has some drawbacks, such as, since it's not currently possible to get if a GUI object is a button or not at run-time, the engine aborts if enter is pressed while a cursor is over a GUI object other than a button. A workaround is to manually add checking within GetGUIObjectPic:

function GetGUIObjectPic(int lgui, int lobj, int lwhich) {
Ã, 
Ã,  Ã,  if (lgui == INVENTORY)
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  if ((lobj == 0) || (lobj == 1)) return GetButtonPic(lgui, lobj, lwhich);
Ã,  Ã,  }
Ã,  Ã,  else return -1; // if it's not a button return -1;
}

I used a beta version where GetButtonPic is added. For other versions button pictures have to be returned explicitly.

Hope it will be of some help :)

monkey0506

That appears to just be a combination of your finite machine and my script. I don't have time to really check or to test it. Did you actually do much more than combine my script and the finite machine?

Scorpiorus

The main thingy there is that I distinguished between enter pressed and enter released events thus eliminating problem #6:

QuoteIf the mouse cursor is moving in a STRAIGHT line, and enter is pressed and held while the cursor is moving, it highlights all the buttons in that line, and sets the appropriate modes. It does return each button picture to normal as the cursor leaves the button. (this should not exsist)

monkey0506

Hmmm... I realized that I was being over presumptious about the buttons. I truly thought that the buttons were only hightlighted while pressed, but this is, in fact, not the case. The buttons should have a mouseover image, which, doesn't need any of my scripts. Now I have:

Code: ags
function KeyControls(){//for keyboard control of the mouse cursor
  if (IsKeyPressed(keyup)==1) SetMousePosition(mouse.x, mouse.y-2);//move cursor up
  if (IsKeyPressed(keydown)==1) SetMousePosition(mouse.x, mouse.y+2);//move cursor down
  if (IsKeyPressed(keyleft)==1) SetMousePosition(mouse.x-2, mouse.y);//move cursor left
  if (IsKeyPressed(keyright)==1) SetMousePosition(mouse.x+2, mouse.y);//move cursor right
  //Script for Enter left-clicks
  if (IsKeyPressed(keyenter)==1) on_mouse_click(LEFT);
  }


So that if enter is pressed, it runs on_mouse_click. And in on_mouse_click I have:

Code: ags
 else if (button==LEFT){
    if (GetGUIAt(mouse.x, mouse.y)==MAIN) interface_click(GetGUIAt(mouse.x, mouse.y), GetGUIObjectAt(mouse.x, mouse.y));//for keyboard controled left mouse clicks
    }


So that when I program my left clicks, it will process them, and if there is a clickable GUI at the cursor, it will run interface_click. Nice and simple. But there is still a problem. I have now realized, upon checking it against the source (The Secret of Monkey Island(TM) CD), that the keyboard control is actually more authentic than the mouse (yes, I'm too picky... Just watch...). The cursor mode should be set IMMEDIATELY upon a mouse click, but if you use the mouse, it waits until the mouse button is released to set the cursor mode (see, I told you). I'll post this as solved, but I won't be truly happy until someone tells me how to correct the mouse, so that it works like the keyboard. [isn't it ironic? first I wanted the keyboard to act like the mouse, now I want the mouse to act like the keyboard, lol.]

Scorpiorus

Personally, I prefere the default behaviour but to achieve that you can check IsButtonDown in repeatedly_execute:

Code: ags
int left_pressed = 0;
int right_pressed = 0;

function repeatedly_execute() {

Ã,  Ã,  if (IsButtonDown(LEFT))
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  if (left_pressed == 0)
Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  on_mouse_click(LEFT);
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  left_pressed = 1;
Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  }
Ã,  Ã,  else left_pressed = 0;


Ã,  Ã,  if (IsButtonDown(RIGHT))
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  if (right_pressed == 0)
Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  on_mouse_click(RIGHT);
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  right_pressed = 1;
Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  }
Ã,  Ã,  else right_pressed = 0;

}

function on_mouse_click(int button) {

Ã,  Ã,  if ((left_pressed==0) && (right_pressed==0))
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  ...
Ã,  Ã,  Ã,  Ã,  ...
Ã,  Ã,  Ã,  Ã,  ...
Ã,  Ã,  }

}



monkey0506

Awesome! Thanks! Ah... It doesn't work. It still reacts the same way. Thanks for trying...

Scorpiorus

Hehe, to make it work with GUIs you can have:

function on_mouse_click(int button) {

Ã,  Ã,  if ((left_pressed==0) && (right_pressed==0))
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  ...
Ã,  Ã,  Ã,  Ã,  if (button == LEFT) interface_click(...);
Ã,  Ã,  Ã,  Ã,  ...
Ã,  Ã,  }

}

EDIT: BTW, in order to avoid interfering with the AGS engine's processing clicks via on_mouse_click and interface_click I'd suggest making a separate versions of the functions (such as my_interface_click and my_on_mouse_click) and call them instead.

SMF spam blocked by CleanTalk