Need help with mouse cursor system script #SOLVED#

Started by Peder 🚀, Sat 24/02/2007 20:06:47

Previous topic - Next topic

Peder 🚀

Hi.

In my game when the mouse is over a certain hotspot the mouse function should change and then it will animate once.

I been looking in the manual, but havent found a way to animate a mouse cursors.
So I just wanted to ask if there is an easy way of animating a mouse cursor?

Also if anyone out there have made a script to make the mouse change function and such when it is over a certain object I would love to get some help with that to.


Peder.

Scorpiorus

#1
Quote from: Peder Johnsen on Sat 24/02/2007 20:06:47So I just wanted to ask if there is an easy way of animating a mouse cursor?

Yes, look it up in the Cursors section of the AGS manual.

QuoteAlso if anyone out there have made a script to make the mouse change function and such when it is over a certain object I would love to get some help with that to.

As an example, the following code will change the mouse cursor mode to the one corresponding to an object/hotspot interaction, the mouse cursor is over:

at the very top of the main global script:
Contains some code helpers to perform the task.
Code: ags

#define MAX_CURSOR_MODES 10

bool mode_registered[ MAX_CURSOR_MODES ];


void RegisterMode( CursorMode mode )
{
Ã,  Ã,  mode_registered[mode] = true;
}


CursorMode GetCursorModeForInteractionAt( int x, int y )
{
Ã,  Ã,  int i = 0;
Ã,  Ã,  while (i < MAX_CURSOR_MODES)
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  if ( mode_registered[i] && IsInteractionAvailable( x, y, i ) )
Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  return i;
Ã,  Ã,  Ã,  Ã,  }

Ã,  Ã,  Ã,  Ã,  i++;
Ã,  Ã,  }

Ã,  Ã,  return eModeWalkto; // default mode to return
}


on game start:
Use the RegisterMode() function to specify all the cursor modes that are processed by the script.
Code: ags

function game_start() {

Ã,  Ã,  int i = 0;
Ã,  Ã,  while (i < MAX_CURSOR_MODES)
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  mode_registered[i] = false;
Ã,  Ã,  Ã,  Ã,  i++;
Ã,  Ã,  }
Ã,  
Ã,  Ã,  RegisterMode( eModeInteract );
Ã,  Ã,  RegisterMode( eModeLookatÃ,  Ã, );
Ã,  Ã,  RegisterMode( eModeUseinvÃ,  Ã, );
Ã,  
}


global repeatedly execute:
An example of using the GetCursorModeForInteractionAt() function to get the cursor mode for any object/hotspot interaction at screen x, y co-ordinates.
Code: ags

if ( IsGamePaused() == 0 )
{

Ã,  Ã,  CursorMode new_mode = GetCursorModeForInteractionAt( mouse.x, mouse.y );

Ã,  Ã,  // do not change mode multiple times (only when needed)
Ã,  Ã,  if ( mouse.Mode != new_mode )
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  mouse.Mode = new_mode;
Ã,  Ã,  }

}

Peder 🚀

I know about that animation thing... BUT., the animation goes and goes, it dont animate only once.
and I need the grapich to be different depending on what hotspot/object the mouse is over...

So I just wondered if there was a way of animating the cursor by scripting..
What I probably will do is use one mouse cursor, then change its animation grapich depending on the hotspot/object it is over. and have right click allways be look and left click be a action depending on the hotspot/object.


I will check out the script you posted and see if I can use it somehow but right now I think I gonna go bed :P getting late.

Thanks for help..
And sorry if I was not clear enough in my first post.
But I hope this second explains a bit better.


Peder.

Scorpiorus

Ah yeah, you cannot make a cursor animation play once. A speedhack would be to set a delay of the last frame of animation to some really high value -- it will still repeat the cursor animation at later moment, though. Scripting it is certainly possible.

Let me know if the other script works.

Peder 🚀

#4
Ok so... I been reading this script.. reading in the manual.
Asking people in the IRC room.
And tried out a few things.

But not everything works yet.

The script I been trying out a bit now is this one:


At the top of the main global script:
Code: ags
Hotspot *mouseOverHotspot;
Object *mouseOverObject;
Character *mouseOverCharacter;



In repeatedly_execute:
Code: ags

Ã,  //Mouse Cursor System
Ã,  //mousemodeis, 0 = eModeNormal, 1 = eModeUse, 2 = eModeTalk, 3 = eModeWalk
Ã,  
Ã,  mouseOverHotspot = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
Ã,  mouseOverObject = Object.GetAtScreenXY(mouse.x, mouse.y);
Ã,  mouseOverCharacter = Character.GetAtScreenXY(mouse.x, mouse.y);
Ã,  
Ã,  //Hotspots
Ã,  if (mouseOverHotspot.GetProperty("mousemodeis") == 0) 
Ã,  { mouse.Mode = eModeNormal; mouse.ChangeModeGraphic(eModeNormal, 19); return; }

Ã,  if (mouseOverHotspot.GetProperty("mousemodeis") == 1)
Ã,  { mouse.Mode = eModeUse; mouse.ChangeModeGraphic(eModeUse, 83); return; }

Ã,  if (mouseOverHotspot.GetProperty("mousemodeis") == 2)
Ã,  { mouse.Mode = eModeWalk; mouse.ChangeModeGraphic(eModeWalk, 38); return; }

Ã,  //Objects
Ã,  if (mouseOverObject.GetProperty("mousemodeis") == 1)
Ã,  { mouse.Mode = eModeUse; mouse.ChangeModeGraphic(eModeUse, 83); return; }

Ã,  //Characters
Ã,  if (mouseOverCharacter.GetProperty("mousemodeis") == 3)
Ã,  { mouse.Mode = eModeTalk; mouse.ChangeModeGraphic(eModeTalk, 63); return; }


What I want the finished script to do is:
When mouse is over hotspot the script should check what the property "mousemodeis" is set to.
And then decide what mouse action to use and to animate the cursor once.
When removing the mouse from the hotspot again it should just look likeÃ,  the normal cursor sprite.

That is the hotspot part..

Character part should be that when mouse goes over and stays on a character it should choose the talk action and animate once with the right animation.

Object part should do the same only that it will use the use action and animation instead.


The script works in the way that it manage to find out the value of "mousemodeis" and choose the mouse action right.
Though, the mouse doesnt animate!

So thats what I need help with right now.

[Edit:]
Ops, I had removed some parts of the script...
It is added back now.

[Edit 2:]
I have now added the Characters and Objects parts to..
Though they dont work.
I think it has to do with this line:
Code: ags
Ã,  if (mouseOverHotspot.GetProperty("mousemodeis") == 0) 
Ã,  { mouse.Mode = eModeNormal; mouse.ChangeModeGraphic(eModeNormal, 19); return; }

but I aint sure.

Right now the script just change the cursor sprite, not animate it.
This works. but I would want it to animate!


Peder.

Scorpiorus

The code above won't work for objects and characters because only the hotspot part runs -- the return keyword then finishes repeatedly_execute and thus nothing more is processed.


The following example demonstrates having different animating cursors over different location types:

at the top of the script
Code: ags

int animation_timer = -1;
readonly int animation_lifetime = 20000;

repeatedly_execute:

Code: ags

readonly int mx = mouse.x; // a shortcut to mouse.x
readonly int my = mouse.y; // a shortcut to mouse.y

CursorMode mode = eModeWalkto; // default mode
int view = -1; // default view

LocationType type = GetLocationType( mx, my );

//
//Ã,  select cursor mode and cursor animation view 
//Ã,  depending on the location type
//
if ( type == eLocationHotspot )
{
Ã,  Ã,  Hotspot *theHotspot = Hotspot.GetAtScreenXY( mx, my );
Ã,  Ã,  mode = theHotspot.GetProperty("mousemodeis");
Ã,  Ã,  view = 1; // cursor animation view over hotspot (you can instead get it from some hotspot property)
}
else if ( type == eLocationObject )
{
Ã,  Ã,  Object *theObject = Object.GetAtScreenXY( mx, my );
Ã,  Ã,  mode = theObject.GetProperty("mousemodeis");
Ã,  Ã,  view = 2; // cursor animation view over object (you can instead get it from some object property)
}
else if ( type == eLocationCharacter )
{
Ã,  Ã,  Character *theCharacter = Character.GetAtScreenXY( mx, my );
Ã,  Ã,  mode = theCharacter.GetProperty("mousemodeis");
Ã,  Ã,  view = 3; // cursor animation view over character (you can instead get it from some character property)
}


//
//Ã,  apply selected mode and view and start animating
//
if ( mouse.Mode != mode )
{
Ã,  Ã,  mouse.Mode = mode;
Ã,  Ã,  mouse.ChangeModeView( mouse.Mode, view );
Ã,  Ã,  animation_timer = animation_lifetime;
}


//
//Ã,  stop animating after some time (ie. animation_lifetime)
//
if ( animation_timer > 0 )
{
Ã,  Ã,  animation_timer --;
}
else if ( animation_timer == 0 )
{
Ã,  Ã,  mouse.ChangeModeView( mouse.Mode, -1 ); // stop animating
Ã,  Ã,  animation_timer = -1;
}


First of all, the "mousemodeis" property values differ from yours:

0 - eModeWalkto
1 - eModeLookat
2 - eModeInteract

etc...

... basically they match those in the cursor pane of the AGS Editor. This makes code more compact.

As for animating, the code uses a hack I mentioned before. That is, you set up a view, and set the speed (SPD, in fact it's a delay btw) of the last frame to a very high value -- say 30000, for example (basically this value must be greater than animation_lifetime which is 20000).

How it works:

- animation starts when cursor is over some location;
- animation reaches the last frame and gets stuck there (because of high delay);
- 30000 game loops is about 12 minutes at default game speed so animation should repeat after that. Fortunately, the code itself forces animating to stop before that, i.e. after 20000 game loops;

So you can just put your cursor mode normal graphic as a last frame with high delay.

Peder 🚀

AWESOME!

It works perfect!!

(I had to edit it a little bit but not much to get it to work exactly the way I wanted it.)

Now I only got one more question!

How can I make the animation go a litle bit quicker? :P.

(it went a bit to slow..)



Peder.

Scorpiorus

QuoteHow can I make the animation go a litle bit quicker?

Ah yes, you cannot change overal cursor animating speed, unfortunately.

But then make sure SPD of all frames but the last one is set to 0 to make it reasonably fast. You can even put negative values to make it extremely fast -- that would require you to change each frame speed individually though. The good thing with using the built-in animation routine is that the engine is aware of it and you generally won't get some strange behaviour like you can with manual cursor animating if, for example, you try to change cursor mode while it's animating or accidently run both the built-in and the scripted animation mechanisms.


By the way, you can as well simulate cursor animation with the GUI button animation -- just make a transparent GUI with a button and use the Button.Animate() function. This method may give a little cursor moving lag effect, however.

You are to make the actual cursor transparent and update cursor-simulating GUI's coordinates repeatedly to make it follow the hidden mouse cursor:

Code: ags

gCursor.x = mouse.x;
gCursor.y = mouse.y;


where gCursor is the cursor-simulating GUI.

Peder 🚀

Oh!

Offcourse! I did not think about putting in negative value!
I will do that, it is not really that much extra work :P


Thanks again for all the help!!!!


Peder Johnsen.

Scorpiorus


SMF spam blocked by CleanTalk