mouse over object or character.

Started by Icey, Sat 29/01/2011 23:54:37

Previous topic - Next topic

Icey

Is there a way I can have something done when the mouse is over a object or character?

I want a gui to be shown then if the mouse moves off the obj or the chr the gui is becomes invisible.
Code: ags

if(mouse.over == true){
//What will be done.
}


If I cant get the gui to become invisible then I will just have the info on the gui change when over the the obj or the chr.

monkey0506

#1
To check if the mouse is over an Object or Character you would use, respectively, Object.GetAtScreenXY and Character.GetAtScreenXY, both of which return null if there is nothing (of that type) beneath the mouse at the specified coordinates.

To make a GUI visible (or not) you can use the GUI.Visible property, which can be set to true or false.

To put it together, you would probably want to put something in repeatedly_execute such as this:

Code: ags
function repeatedly_execute()
{
  Character *cat = Character.GetAtScreenXY(mouse.x, mouse.y);
  Object *oat = Object.GetAtScreenXY(mouse.x, mouse.y);
  gOver.Visible = ((cat != null) || (oat != null)); // where gOver is the name of the GUI you want to have turned on or off
}


I stored the items beneath the cursor in case you want to do something with them. If you're not doing anything else with those, then you could just shorten it down to one line. Also some would say that I overuse parenthesis, but that's a matter of personal preference. To me it makes it better organized, clearer what you are doing, and less likely to cause problems (particularly when working with other operators, such as arithmetic operators).

Khris

For reference, there's also Game.GetLocationType().

Code: ags
  int lt = Game.GetLocationType(mouse.x, mouse.y);
  if (lt == eLocationObject || lt == eLocationCharacter) {
    ...
  }


It is a good idea to read the complete command reference once to get an idea where to look for a command and what AGS can do in general.

Icey


poc301

Thats awesome..  I can't wait to upgrade from 2.7 once I finish this damn game.  The engine has come such a long way.

-Bill

Icey

#5
Also is there away to set which object it is over? I plan to use this a lot in the game but not always over the same obj...or chr?

Khris

Do you mean placing the mouse at specific coords?
Just set mouse.x and mouse.y.

Icey

Ok. But does that mean it has to be directly over that spot?

monkey0506

@poc301: The scripting for this hasn't changed at all from 2.7. Everything in this thread (so far) is relevant for all versions of AGS 2.7 and higher.

@Khris: Per the manual, mouse.x and mouse.y are supposed to be read-only. I don't know if you can set them directly, but the manual says that you're not supposed to do so. The proper way of doing this is to use mouse.SetPosition(x, y).

@Studio3: What do you mean? Directly over what spot? If you're moving the mouse to be over specific Objects or Characters then you can just use Object.X, Object.Y, Character.x, and Character.y to determine the coordinates you need. The case matters here as well (Character uses lower-case for these variables), so make sure you keep that in mind.

Icey

#9
Oh so that's why I couldn't get mouse.x & mouse.y to work right.

Yet I am still confused. This is what I need this to work for & what I have so far.

Code: ags

//bomb 1
{
// Character *cat = Character.GetAtScreenXY(mouse.x, mouse.y);
  Object *cat = Object.GetAtScreenXY(mouse.x, mouse.y);
  Object *oat = Object.GetAtScreenXY(mouse.x, mouse.y);
 // enemyHP.Visible = ((cat != null) || (oat != null)); // where gOver is the name of the GUI you want to have turned on or off
if(mouse.x){
  if(mouse.y){
    
  enemyHP.Visible = ((cat != null) || (oat != null)); // where gOver is the name of the GUI you want to have turned on or off0
  
  //note: This code is from before the last post.
}
}


In the pic when the Cursor is over the mouse it will display a gui in the bottom right corner. & when is taken off the obj the gui is not visible anymore(Then this goes right back to pic 1)



I am going to start bookmarking my BTQ threads so I can study them more.

Icey

                                                ^updated. ^

monkey0506

You specifically mentioned both Characters and Objects, but then explicitly modified the code provided you so that now it not only uses only Objects, but in fact duplicates some of the code and function calls.

You also added what seems to be rather superfluous checks on mouse.x and mouse.y because the condition would be true for any other position on the screen other than (0,0) (the top-left corner of the screen). You also aren't telling us what function you've put the code into which is important because that determines when the code would actually be executed.

..hmm..all that aside so long as the Objects in question are in fact only Objects and not ever Characters at all and the code has actually been pasted into an actually relevant function (such as repeatedly_execute (for room scripts, room_RepExec) or a function directly called therein)..the code should presumably still be functioning as you have described.

Edit: You double posted to indicate that something had been updated, but I don't actually see any changes from what I was responding to at all..so..

Icey

#12
The code is were you told me to put it(repeatedly_execute)

As of now I want it to work only over the obj's because the chr's in the room are not enemy's there for they dont need that gui.

The code comes before your post on correcting Khris,me, & poc301.

now every thing works except the fact that I plan on using this in other rooms of the game but It will have different enemy's like I may want to fight a bat & a turtle but I dont want the menu showing up displaying info for only the bat even though I moved it over the turtle.

Until I can get it working were I have the choice to specify the area the enemy(obj or chr)  is in and what is displayed in the gui when it becomes visible then this problem will be not solved :(

Khris

The problem here is that you're always coding specific situations, not general solutions.
What you should do is code a battle engine and underlying data structures so that in the end all you need to do is set the enemies and the background picture and the game then loads that into a single battle room.

This requires planning and advanced scripting but is way more convenient in the long run.
For instance, adding random battles to a game map is only a matter of a few additional lines then.

Here's a random snippet from an RPG battle engine I'm working on from time to time:

Code: ags
struct fighter {
  String Name;
  bool isEnemy;
  int stat;
  int str, def, agi;
  int hp, hpc;
  int pow;
  int pos_x, pos_y;
  int View;
  String DefendFrames;
  Character*ch;
  int agi_cnt;
  bool dead;
};


And here's the top of the main battle function:

Code: ags
void StartBattle(battlespot bs, EnemyType a, EnemyType b, EnemyType c, EnemyType d, EnemyType e) {
  if (bs == eBattleBeach) {
  }
  if (bs == eBattleJungle) {
    battle_background_slot = 42;
    battle_foreground_slot = 43;
  }


Just to give you an idea what's required to do.

Icey

oh-ok.

So I can put that in my game?

Icey

BTW my game is online so I cant use random battles or change the background.

I wanted to have it were the player changes into another room but the problem was getting him back in that same spot if I used random battles.

I want every one in the same room at times so people can help each other in battle.

Icey

I dont mean to sound like I am complaining but I really need help with this. :-\

I think it's the last part.

I just need to know what to code for when the mouse goes over a SPECIFIC object.

I have a few icon's & text on the gui and every time I move it over a obj I get the same info. I basically want to have the choice to change the icons/text depending on the enemy.

monkey0506

I don't mean to sound like I am complaining, but within less than 24 hours you have triple posted pretty well demanding at this point (at least that's how it comes across with the frequency of your posting) that we help you, without providing any indication what steps you have taken to actually utilize the most recent help offered to you.

If you had, within the past 24 hours, actually properly taken the time to read Khris' post, you might have seen the part where he said that his code snippets were provided only "to give you an idea what's required to do". The code would not work as-is for you in a game, because the struct that Khris has defined would never have any instances of it defined if you just literally copied and pasted that code, and you'd be missing the enum definitions referenced in his second snippet (not to mention the function is incomplete (without a closing brace).

As for your question, you can update the GUI using things like GUI.BackgroundGraphic, Button.NormalGraphic, Label.Text, etc. Look it up in the manual..

As for determining what type of Object the mouse is over, you might want to consider using custom properties. You could create an int property, call it something like "EnemyType", and make it applicable to Characters and Objects. You could then create an enum in the script to simplify keeping track of which values correspond to which enemy type:

Code: ags
enum EnemyType
{
  eEnemyNone = 0, // used to indicate that the Character or Object does not represent an enemy
  eEnemyBat = 1,
  eEnemyTurtle = 2,
  eEnemyFlameball = 3,
  // ..etc.
};


You would want to put that in a script header, above any script that needs to use it. If you set any of the properties using the Properties Editor (in the Character or Object's properties pane) then you would have to manually specify a value (you can't use the enumerated values). This is the reason I specifically set values for each of the enums. Ordinarily you wouldn't have to manually set a value for each one, but if the order gets changed (meaning, for example, if you add a new value at the top of the list instead of the bottom) then you would also have to update any values set in the Properties Editor. For this reason it's simplest to just manually set values for each of the enums, and if the list changes in any way, just keep the existing values in-place.

Then you could do something like this:

Code: ags
// GlobalScript.asc

function repeatedly_execute()
{
  LocationType locType = GetLocationType();
  if (locType == eLocationCharacter)
  {
    Character *cat = Character.GetAtScreenXY(mouse.x, mouse.y);
    EnemyType enemyType = cat.GetProperty("EnemyType");
    enemyHP.Visible = (enemyType != eEnemyNone); // if the Character is an enemy, show the GUI
    // update enemy display picture and other items here..
    if (enemyType == eEnemyBat)
    {
      btnEnemy.NormalGraphic = ENEMY_BAT_SPRITE_SLOT;
      // ...
    }
    else if (enemyType == eEnemyTurtle)
    {
      btnEnemy.NormalGraphic = ENEMY_TURTLE_SPRITE_SLOT;
      // ...
    }
  }
  else if (locType == eLocationObject)
  {
    Object *oat = Object.GetAtScreenXY(mouse.x, mouse.y);
    EnemyType enemyType = oat.GetProperty("EnemyType");
    enemyHP.Visible = (enemyType != eEnemyNone;
    // update enemy display picture and other items here..
    if (enemyType == eEnemyFireball)
    {
      btnEnemy.NormalGraphic = ENEMY_FIREBALL_SPRITE_SLOT;
      // ...
    }
  }
  else enemyHP.Visible = false;
}


The reason Khris posted the code snippets that he did is because you're going to need to keep track of a fair amount of data regarding the enemies if you're planning to make a full RPG.

Icey

I thought I figured out a way to do it but I didn't & I didn't know how to keep asking with out sounding like a baby who needs attention. But I guess now with this I may need to switch some thing around but it will help me alot later on.

monkey0506

Quote from: Studio3 on Mon 31/01/2011 22:27:21I didn't know how to keep asking

That was somewhat my point. It was less than 24 hours. We are real people with our own lives and endeavours. We aren't here to bend over backwards to your every whim, to jump at your every beck and call, just because you want your Greatest RPG Game Ever Made In Any Game Engine Ever Because I Made It Entirely By Myself 2011!!2 to be delivered a day sooner.

I don't mean to sound harsh here, but seriously, calm down. It was one day.

SMF spam blocked by CleanTalk