[SOLVED] Detecting when a NPC, object or mouse is over a hotspot?

Started by Snake, Mon 12/05/2008 02:34:22

Previous topic - Next topic

Snake

I feel like a complete idiot. I used to know how to do this. I always did it when the mouse was over a certain hotspot and change the graphic.

How do I script if an object/character or mouse is over a hotspot?

If I remember right it's something like:
if (object[1].x==hPic.x) {code}//I know it's not that, but the idea is the same...

I've tried all sorts of different ways but I can't get it to work. I wish I could find my old discs with my old games on it.

I only need the code for an object, but I assume that it's the same with everything.

Thanks in advance and sorry for such a dumb question :-\


--Snake
Grim: "You're making me want to quit smoking... stop it!;)"
miguel: "I second Grim, stop this nonsense! I love my cigarettes!"

GarageGothic

#1
in repeatedly_execute:

Code: ags
Hotspot* myhotspot = Hotspot.GetAtScreenXY(mouse.x, mouse.y);
if (myhotspot != hotspot[0]) {  //if it's over a hotspot
   //do stuff
   }


Characters and Objects have similar GetAtScreenXY functions. Since you're only checking a point, not all pixels of the character/object, you will have to decide for yourself which point to check. For characters standing on a region, the basic centre point of its bottom line (character.x, character.y). But with objects it may make more sense to either check the middle of the bottom line or even the centre of the sprite.

skuttleman

Quote from: GarageGothic on Mon 12/05/2008 03:19:45
Characters and Objects have similar GetAtScreenXY functions.

Keep in mind that Characters and Objects use room coordinates, and the mouse uses screen coordinates, so if your room scrolls, you'd need to compensate for that.

Code: ags

Hotspot *myhotspot = Hotspot.GetAtScreenXY(object[1].X - GetViewportX(), object[1].Y - GetViewportY());

Snake

Thank you guys,

I've been going crazy trying to figure it out - although I don't remember doing it the way you guys have shown me, but I'll give it a shot as soon as I need it.

I improvised and did something else, which I like better.


--Snake
Grim: "You're making me want to quit smoking... stop it!;)"
miguel: "I second Grim, stop this nonsense! I love my cigarettes!"

Snake

Bump.

Alright, I had forgotten that I needed to do this.
This is similar to what I wanted before, which I had changed.

I have power-ups for a mini game that are placed on the "field" after a certain time has passed. Hotspot 8 is a bunch of areas where the player cannot go, rendering the power-ups to be inaccessible if they appear there.

The power-ups are randomly placed and so I need them to be randomly placed again, if landing on hotspot 8, so the player can always obtain them, if they'd like.

Here's the code:
Code: ags
  int pu = Random(2);
  if (pu==0) {
    object[9].Visible=true;//SPEED SHOES
    object[9].SetPosition(Random(200)+60,Random(803)+235);//used to be (300)+300
    gui[33].Visible=true;
  }
  if (pu==1) {
    object[10].Visible=true;//MORE TIME
    object[10].SetPosition(Random(200)+60,Random(803)+235);
    gui[34].Visible=true;
  }
  if (pu==2) {
    object[11].Visible=true;//INVINCIBILITY
    object[11].SetPosition(Random(200)+60,Random(803)+235);
    gui[35].Visible=true;
  }
}

//POWERSUPS LANDING OUT OF BOUNDS AND BEING PLACED ON FIELD
if (Hotspot.GetAtScreenXY(object[9].X, object[9].Y) == hhole) object[9].SetPosition(Random(200)+60,Random(803)+235);
if (Hotspot.GetAtScreenXY(object[10].X, object[10].Y) == hhole) object[10].SetPosition(Random(200)+60,Random(803)+235);
if (Hotspot.GetAtScreenXY(object[11].X, object[11].Y) == hhole) object[11].SetPosition(Random(200)+60,Random(803)+235);


I had gotten this code,if (Hotspot.GetAtScreenXY(object[9].X, object[9].Y) == hhole), from another thread here. This is the code I had used in the passed, I believe for changing the mouse cursor whilst over a hotspot.

What it's doing is ignoring the hotspot 8 code and placing them on it regardless.
So I tried, !=, instead, like GarageGothic had wrote and it works, but before the object is on the field, you can see it randomize where it's going - as if the object were "jumping around" so to speak.
Another thing that happens is that EGO doesn't even have to touch the power up, only be next to it, to collect it.

//--EDIT--//
I fiddled with it a bit more and came up with this:
Code: ags

  int pu = Random(2);
  if (pu==0) {//SPEED SHOES
    object[9].SetPosition(Random(200)+60,Random(803)+235);
    if (Hotspot.GetAtScreenXY(object[9].X, object[9].Y) != hhole){
      gui[33].Visible=true;
      object[9].Visible=true;
      }
    else if (Hotspot.GetAtScreenXY(object[9].X, object[9].Y) == hhole) SetTimer(16, 100);
  }
  if (pu==1) {//MORE TIME
    object[10].SetPosition(Random(200)+60,Random(803)+235);
    if (Hotspot.GetAtScreenXY(object[10].X, object[10].Y) != hhole){
      gui[34].Visible=true;
      object[10].Visible=true;
      }
    else if (Hotspot.GetAtScreenXY(object[10].X, object[10].Y) == hhole) SetTimer(16, 100);
  }
  if (pu==2) {//INVINCIBILITY
    object[11].SetPosition(Random(200)+60,Random(803)+235);
    if (Hotspot.GetAtScreenXY(object[11].X, object[11].Y) != hhole){
      gui[35].Visible=true;
      object[11].Visible=true;
      }
    else if (Hotspot.GetAtScreenXY(object[11].X, object[11].Y) == hhole) SetTimer(16, 100);
  }

It seems to work pretty well, but the objects will still be placed on Hotspot 8, but not as often. But I don't want them on Hotspot 8 at all :(

Thanks in advance,

//--EDIT--//
Ah crap, sorry GarageGothic, not I get what you wrote. Hotspot zero isn't a hotspot.
Damn - I'm going to fiddle around with it a little more and see what I can do.


--Snake
Grim: "You're making me want to quit smoking... stop it!;)"
miguel: "I second Grim, stop this nonsense! I love my cigarettes!"

SSH

The problem is, your re-randomization can still put it on hhole:

Code: ags

function RandomPU(Object *what) {
  what.SetPosition(Random(200)+60,Random(803)+235);
  while (Hotspot.GetAtScreenXY(what.X, what.Y) == hhole) {
    what.SetPosition(Random(200)+60,Random(803)+235);
  }
}

...

if (pu==0) {
  RandomPU(object[9]);
  // etc...


 
12

Snake

Thanks for the code, SSH, but it still is placing the objects on hotspot 8.

Here's what I've done:
Global Script...
Code: ags

///////////////////////////////////////////////////////////////////
//FUNCTION FOR PUTTING POWER UPS BACK ON THE FIELD/////////////////
///////////////////////////////////////////////////////////////////
function RandomPU(Object *what) {                                //
  what.SetPosition(Random(200)+60,Random(803)+235);              //
  while (Hotspot.GetAtScreenXY(what.X, what.Y) == hotspot[8]) {  //
    what.SetPosition(Random(200)+60,Random(803)+235);            //
  }                                                              //
}                                                                //
///////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////

RepEx
Code: ags

  int pu = Random(2);
  if (pu==0) {//SPEED SHOES
    RandomPU(object[9]);   
    gui[33].Visible=true;
    object[9].Visible=true;
    }
  if (pu==1) {//MORE TIME
    RandomPU(object[10]);   
    gui[34].Visible=true;
    object[10].Visible=true;
    }
  if (pu==2) {//INVINCIBILITY
    RandomPU(object[11]);   
    gui[35].Visible=true;
    object[11].Visible=true;
    }
  }



--Snake
Grim: "You're making me want to quit smoking... stop it!;)"
miguel: "I second Grim, stop this nonsense! I love my cigarettes!"

SSH

How big are the powerups? Do you want that no part of them is over the hotspot?

Also, is it a scrolling room?
12

Snake

Yes, it is a scrolling room - 320x1100. I forgot to mention that :-X

The largest powerup is just about as big as the player (9x22), the other two are about half.
It doesn't matter to me that a powerup could land half on/off the edge, just as long as the player can touch them.

When they are on the hotspot, they are actually ON the hotspot, like way out there, they're not just half on/off. Like I said before, it's like Hotspot 8 doesn't exist or I have the wrong number, but I don't.


--Snake
Grim: "You're making me want to quit smoking... stop it!;)"
miguel: "I second Grim, stop this nonsense! I love my cigarettes!"

SSH

The problem is that Hotspot.GetAtScreenXY(what.X, what.Y) works on what is on the screen right now, not the whole background, so unless your hotspot is onscreen at the time, and you adjust by viewport, it won't work.

Is the hotspot just a rectangle, or is it a more complex shape? If it is acceptable to have the excluded area as a rectangle, then that makes the whole business a bit easier...
12

Snake

Blargh.

This is the BG:


Sorry it's so big.

The black and dark brown areas are the hole; Hotspot 8.


--Snake
Grim: "You're making me want to quit smoking... stop it!;)"
miguel: "I second Grim, stop this nonsense! I love my cigarettes!"

SSH

Is there any possibility that you can use a Region as well/instead of a hotpsot? Becuase Regions use Room co-ordinates for their getatxy function, not Screen...
12

Snake

SSH,

This seemed to work. I made region 1, fixed the code in the global script and play tested it a dozen times so far and not once did they appear outside the bounds.

I think you've licked the problem.

Thank you and I'll report back if there's a problem!


--Snake
Grim: "You're making me want to quit smoking... stop it!;)"
miguel: "I second Grim, stop this nonsense! I love my cigarettes!"

SMF spam blocked by CleanTalk