Change Curser on Edges [SOLVED]

Started by 10o, Mon 17/10/2011 17:51:37

Previous topic - Next topic

10o

Yes I've used the Search Engine and only found this (outdated) Thread:
http://www.adventuregamestudio.co.uk/yabb/index.php?topic=25762.0


Since there isn't a normal solution in AGS fot that yet I've tried something.

I use a GUI with Leftclick Walk/Talk/Interact , Rightclick Walk/Look.

The Curser changes to the wanted Symbol, that problem is solved to.

I've managed it this way:
Code: ags

function repeatedly_execute() {

  
 if (GetLocationType(mouse.x, mouse.y)==eLocationCharacter)
   {
    mouse.Mode = eModeTalkto;
    }
 else if (GetLocationType(mouse.x, mouse.y)==eLocationObject)
   {
    mouse.Mode = eModeInteract;
   }
 else if (GetLocationType(mouse.x, mouse.y)==eLocationHotspot)
   {
    mouse.Mode = eModeInteract;
   }  
 else 
  {
    mouse.Mode = eModeWalkto;
  }
  
  if (IsGamePaused() == 1) return;

}


I've added a new Curser called eModeArrowR and placed a Hotspot (called hAusgangR) in the Edge Area where the player changes rooms.

I've added this to my room script:
Code: ags

function hAusgangR_MouseMove()
{

   mouse.Mode = eModeArrowR;

}


It kind of "works", when I get the curso over the hostspot it changes short to the Arrow Cursor but fast back to the Interact Cursor.

As far as I understand it, it gets directly overwritten of the function repeatedly_execute(), so my Question is:

Is it possible to stop this function as long as my Curser is on this special area?
Or maybe another way to solve this problem?






Khris

I wouldn't recommend adding a cursor mode for each direction; it's much cleaner and easier to keep eModeWalkto but change the mode's graphic.

To actually use the edges to change the cursor, you could do this:

Code: ags
// in repeatedly_execute

  int new_sprite = mouse.GetModeGraphic(eModeWalkto); // default

  if (mouse.mode == eModeWalkto && GetWalkableAreaAt(mouse.x, mouse.y) > 0) {

    if (mouse.x > Room.RightEdge) new_sprite = 123; // sprite slot of right arrow
    if (mouse.x < Room.LeftEdge) new_sprite = 456;
    ...

    mouse.ChangeModeGraphic(eModeWalkto, new_sprite);
  }


Another way is to use hotspots and custom properties:
http://www.adventuregamestudio.co.uk/yabb/index.php?topic=41759.msg553607#msg553607

10o

Quote from: LeKhris on Mon 17/10/2011 18:39:17
I wouldn't recommend adding a cursor mode for each direction; it's much cleaner and easier to keep eModeWalkto but change the mode's graphic.

To actually use the edges to change the cursor, you could do this:

Code: ags
// in repeatedly_execute

  int new_sprite = mouse.GetModeGraphic(eModeWalkto); // default

  if (mouse.mode == eModeWalkto && GetWalkableAreaAt(mouse.x, mouse.y) > 0) {

    if (mouse.x > Room.RightEdge) new_sprite = 123; // sprite slot of right arrow
    if (mouse.x < Room.LeftEdge) new_sprite = 456;
    ...

    mouse.ChangeModeGraphic(eModeWalkto, new_sprite);
  }


It will change the Sprite if I reach the Edge, right?
But if I have only a small path on the right where the Arraow Cusrer appears I need a Hotspot for that, right?


Ok I've tried a little bit around and to a not so clean solution

A Must condition for my Solution is, that there isn't any other Hotspot directly connected to the change room hotspot.

Ive added a global var named int wechsel = 0

I have changed in my room script:
Code: ags

function hAusgangR_MouseMove()
{
  if(Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hAusgangR)
  {
  wechsel = 1;
  }
  
}




Changed in the global script:
Code: ags

function repeatedly_execute() {

   if (GetLocationType(mouse.x, mouse.y)==eLocationCharacter)
   {
    mouse.Mode = eModeTalkto;
    wechsel = 0; 
    }
  else if (GetLocationType(mouse.x, mouse.y)==eLocationObject)
   {
    mouse.Mode = eModeInteract;
    wechsel = 0; 
   }
    else if (GetLocationType(mouse.x, mouse.y)==eLocationHotspot)
   {
     if(wechsel==0)
     {
      mouse.Mode = eModeInteract;
      wechsel = 0; 
     }
     else
     {
       mouse.Mode = eModeArrowR;
       
     }
   }  
  else 
  {
    mouse.Mode = eModeWalkto;
    wechsel = 0; 
  }
  
  if (IsGamePaused() == 1) return;

}




And at another place in the Global Script:
Code: ags

function on_mouse_click(MouseButton button) {
  // called when a mouse button is clicked. button is either LEFT or RIGHT
  if (IsGamePaused() == 1) {
    // Game is paused, so do nothing (ie. don't allow mouse click)
  }
  else if (button == eMouseLeft) {
 //   ProcessClick(mouse.x, mouse.y, mouse.Mode );
        int nm;
    if (GetLocationType(mouse.x, mouse.y) == eLocationCharacter)
    {
      nm= eModeTalkto;
    }
    else if (GetLocationType(mouse.x, mouse.y) == eLocationNothing)
    {
      nm= eModeWalkto;
    }
    else if (GetLocationType(mouse.x, mouse.y) == eLocationHotspot)
    {
      if(wechsel == 0)
      {
      nm=eModeInteract;
      }
      else
      {
      nm= eModeWalkto;
      }
    }
    else
    {
      nm=eModeInteract;
    }
    ProcessClick(mouse.x, mouse.y, nm);  
  }
}




I guess its not not the best solution, but it kind of works for me

Khris

It will change the sprite as soon as the mouse is a) over a walkable area and b) outside the edge line.

Not sure about your code there, the important thing is that you should never code global behavior like this on a per-hotspot basis.

If you look at the thread I linked you to, the code there constantly tracks the hotspot under the mouse and deals with both exiting a hotspot and moving over one, even if they are connected.

10o

Ok thanks, maybe I'll try your code from the other Thread you named, but at first I'll guess I'll stick with mine.


Quote from: LeKhris on Mon 17/10/2011 19:19:34
the important thing is that you should never code global behavior like this on a per-hotspot basis.
Whats the reason for that?

Khris

Well, it's about 50* times the work.
And if you ever wanted to change anything, you'd have to go through all your room scripts and change 50* code blocks.

(Assuming you have 50 hotspots.)

See, you're already doing the correct thing by using this:
Code: ags
if (GetLocationType(mouse.x, mouse.y)==eLocationCharacter)
   {
    mouse.Mode = eModeTalkto;
    wechsel = 0; 
    }


Imagine you'd have to tell AGS to switch to eModeTalkto separately for every character in the game instead.

10o

You're right about that, but in my case I guess I'll keep the overview with the hotspot thing.

I'll just add wechsel = 2 for left, 3 for down etc..

And it will always change back to 0 in other cases.


Khris

Ok, but in that case all you need is setting wechsel.

If you look at this:
Code: ags
function hAusgangR_MouseMove()
{
  if(Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hAusgangR)
  {
  wechsel = 1;
  }
  
}


Every time this is executed, the mouse has just been moved over hAusgangR, so the if condition will never be false.
To take it one step further, why not put the number signifying the exit's direction into a custom property instead of adding a function for every hotspot when all it does is set a variable? Which takes you right back to the exit code I linked you to.

Just a suggestion, wer nicht will, der hat schon :)

10o

Ich hab schon  ;D

No I guess I'll try out your suggestions, and I guess it might be the solution in my final game.
But before I'll start my final game I'll mess around with a test game first, so that I don't fuck up the final one.

When I've gained enough experience in my test game, than I'll start my real project.

SMF spam blocked by CleanTalk