mouse double-clicks

Started by fanton, Fri 05/03/2004 14:25:51

Previous topic - Next topic

fanton

Is it possible to use double click in AGS?
I checked the manual but I haven't found anything. Should I re-look? :P

I am trying to use a left single click for walk and left double click for look.

SSH

You'll need some scripting...

add this code to your on_mouse_click global function:

int double_click;

if (button==LEFT) {
SetMouseCursor(GetCursorMode()); // stops wait cursor appearing
double_click = WaitMouseKey(DELAY_TIMEOUT)*IsButtonDown(LEFT);
SetDefaultCursor();
if (double_click) {
ProcessClick(mouse.x, mouse.y, MODE_LOOK );
} else {
ProcessClick(mouse.x, mouse.y,  MODE_WALK);
}
}

if you want the same functionality in a custom inventory, then you'll need to add the same under a (button==LEFTINV) bit, too.


12

Tutano

I have a question... if I need that this double-click change the mouse icon(look, walk, talk, iventory-iten, interact), and one click active the action(look, walk, talk, i...)How I do this???

SSH

#3
tutano, here's your answer:

int double_click;

if (button==LEFT) {
  SetMouseCursor(GetCursorMode()); // stops wait cursor appearing
  double_click = WaitMouseKey(DELAY_TIMEOUT)*IsButtonDown(LEFT);
  SetDefaultCursor();
  if (double_click) {
    SetNextCursorMode();
  } else {
    ProcessClick(mouse.x, mouse.y,  GetCursorMode());
  }
}


12


strazer

#5
I wasn't quite satisfied with the WaitMouseKey thing, so here's a "non-blocking" way:
Global script

// top of script

int doubleclick=-1; // stores mouse double-click status

// end of script

export doubleclick; // export variable for import in script header

Script header

import int doubleclick; // make double-click status available to room scripts as well

on_mouse_click

// top of function preferrably

  if (IsTimerExpired(TIMERNUMBERHERE)) // user failed to click twice within the specified timeframe
   doubleclick = 0; // register single click
  else { // user clicked twice within the specified timeframe
   if (doubleclick == 0) // only if preceded by a single click (remove this if you want)
      doubleclick = 1; // register double click
  }
  SetTimer(TIMERNUMBERHERE, GetGameSpeed()/4); // set timer to wait 250ms for second click

Replace TIMERNUMBERHERE with the number of the timer you want to use as the double-click timeout timer, for example 1 if you don't use that already.

The variable doubleclick is now available throughout your game, so you can check it in all further scripts, including the rest of your on_mouse_click function for example:
on_mouse_click

  // script from above
  ...
  if (button == LEFT) {
   if (doubleclick) {
      // do double-click stuff here
   }
   else {
      // do single-click stuff, for example:
      ProcessClick(mouse.x,mouse.y,GetCursorMode());
   }
  ...

Drawbacks:
- the First Click of your entire game won't be registered as a double-click.  :o
- the first click of a double click is being registered as a single click :-\

SSH

Ummm... does this actually work? Surely this code means that you will first run the single-click code and then later run the double-click code?
12

strazer

#7
Ah yes, now I know what you mean.
Hm, yes, that could be a problem. Well, it worked for my game, so there you go.

And I have just noticed the game isn't even blocked when using WaitMouseKey. :P
It's just that my wait cursor is still appearing.
Do you have any shorter code than

int oldmode = GetCursorMode();
SetCursorMode(MODE_WAIT);
SetMouseCursor(oldmode);
doubleclick = WaitMouseKey(GetGameSpeed()/4)*IsButtonDown(LEFT);
SetCursorMode(MODE_WAIT);
SetDefaultCursor();
SetCursorMode(oldmode);

?
And I don't like the lag with a single click. How do other applications handle that I wonder?

Thanks

SSH

well, you coudl stick the code in a function to make it more readable in the on_mouse_click.

Unless you create some kind of undo-ability to the single-click function, or the double-click function is complementary to the single-click (e.g. increase the walking speed) then you have to block until you know  if it is a single or double click. In my game, that doesn't seem to onerous.
12

strazer

Yeah, logically, there's no way around it.
Yours is the one to do it.

Sorry for the intrusion, moderators, feel free to delete my posts.

Stickieee

I took SSH's double click code and modified it a bit to suit my needs.

        int double_click;
   if (button==LEFT) {
     MoveCharacter(EGO, mouse.x, mouse.y);
     SetMouseCursor(GetCursorMode());
     double_click = WaitMouseKey(8)*IsButtonDown(LEFT);
     SetDefaultCursor();

     if (double_click) {
          ProcessClick(mouse.x, mouse.y, 2);
     } else {
       ProcessClick(mouse.x, mouse.y,  0);
     }
   }

This bit works perfectly in my game. However, I've tried to do something else with the right button:
   
   if (button==RIGHT) {
      SetGUIPosition(2, mouse.x, mouse.y);
      GUIOn(2);
      int muuttuja = 1;
      while(IsButtonDown(RIGHT) && muuttuja==1) {
         WaitMouseKey(0);
         if (IsButtonDown(LEFT)) {
           muuttuja = 0;
         }
         
      }
      if (muuttuja == 0) ProcessClick(mouse.x, mouse.y, 0);
      GUIOff(2);
   }

Get the drift? A GUI is supposed to pop up and I should be able to click it's buttons etc. Interface is disabled so I can't press anything. I tried putting EnableInterface()s almost everywhere but didn't get any results.

So, HOW to do this correctly?
EXPLOSION

SSH

If you want your GUI to operate like a normal right-click menu, I suggest setting your repeatedly execute to check if IsButtonPressed(RIGHT) and if so set your GUI pos, set a global variable and turn gui on, else turn gui off.

Then, in on_event, check if the global variable is set and if the event is GUI_MUP (and the GUI is the right one). Then use GetGUIObjectAt(mouse.x, mouse.y) to find which button in the GUI was activated. Then do your stuff...


Clear?
12

Stickieee

#12
Thanks SSH, without your advice about using repeatedly_execute I'd still be smashing my screen with the keyboard.

EDIT: THE FOLLOWING DOESN'T WORK!! What the heck did I do to it, it worked yesterday. BUGGER!
2nd edit: It works again. Strangely, somehow, I had managed to move a } a paragraph too late. So, here's the revised code.

--

However, I didn't do what you told me to. Instead I did this:

function repeatedly_execute() {
 // put anything you want to happen every game cycle here
 if (IsButtonDown(RIGHT)) {
      if (IsGUIOn(2)==0) {
        SetGUIPosition(2, mouse.x-7, mouse.y-7);
        SetGlobalInt(120,mouse.x);
        SetGlobalInt(121,mouse.y);
        GUIOn(2);
      }
      
 }
 else {
   if (GetGUIAt(mouse.x, mouse.y) == 2) {
    if (GetGUIObjectAt(mouse.x, mouse.y)==0) {
      ProcessClick(GetGlobalInt(120), GetGlobalInt(121), 1);
    }
    if (GetGUIObjectAt(mouse.x, mouse.y)==1) {
      ProcessClick(GetGlobalInt(120), GetGlobalInt(121), 3);
    }
   }
    GUIOff(2);
 }

and nothing in on_event

And this works the way I want it to. A menu pops up when user pushes right button down and the menu is shown only as long as button is down. The cursor is moved over the wanted option and released - voilá, processclick with whatever action wanted takes place.

I thought I could share this code, in the (highly unexpected) case of someone wanting to do something exactly like this.
EXPLOSION

fanton

lol. nobody posted for a long time so i forgot about this. I WILL READ EVERYTHING!!!!

thank you very much everyone!!!!!!!

kadok

I,ve read this topic and I must ask

will I be able to make somethink like that:

>one click walk double click run
>double click on object a ladder for exaple and
  atomatically character walk up on
sorry for may english... it's not my native language so I may make some mistake's

SMF spam blocked by CleanTalk