AGS Awards votes close at 13:59 BST on Wednesday 07 March 2018. You've already voted, so you've got 13 days and 10 hours left to wait before voting closes!

Author Topic: Clicking a hotspot behind an object without making said object unclickable  (Read 212 times)

Hello, everyone. Continuing with my previous post about making an isometric game... I've got almost everything resolved. Instead of trying to explain how it works and what my problem is, here is a demo game:

Isometric test game

As you can see, the walls become transparent when the player is inside the building (I know there are some minor issues, but I can solve them in the near future). The thing is, that I want to click the hotspots behind those walls (like, for example, the outside chair behind the western wall). If I make the wall unclickable as well as transparent, my whole code goes through the toilet, because it needs the player to be colliding with the wall, so if I make the wall unclickable, no collision occurs, and then the wall just blinks from on to off indefinitely.

Tl;dr: I need to be able to click a hotspot behind a transparent object (wall) without making said object unclickable. Or make it unclickable, but without ruining the rest of the code. I've been a couple hours at it and I can't think of a solution.

Thanks in advance for any kind of help or insight.

I haven't checked your test game but can't you just check the mouse click on the hotspot manually like this:

Code: Adventure Game Studio
  1. if (mouse.IsButtonDown(eMouseLeft)) // or right
  2. {
  3.   if (Hotspot.GetAtScreenXY(mouse.x, mouse.y) == hSomething)
  4.   {
  5.     // Do stuff
  6.   }
  7. }
  8.  

This should ignore the object in front of the hotspot.

Yeah, Matti, that's what I wound up doing. Forgot to post "solved", lol. While I've got your attention, though... Is there a way to check what object is behind another object? Specifically when my char is behind the western wall, where it overlaps with the southern wall, the game just detects the southern wall as being in player.x, player.y, because the southern wall is closer in the z-order. I'm trying to figure this out at the moment, but maybe you or someone else already knows and can save me some hours of thinking (yeah, I'm that slow). Thanks!

Vincent

  • Jump back into the pond
    • I can help with play testing
    •  
    • I can help with scripting
    •  
    • I can help with translating
    •  
Is there a way to check what object is behind another object?

I believe so, I think you can try with object[ID].Baseline.

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
Ok, if I understood that right, you want to be able to find a second object behind the first one, but cannot simply do that with GetAtScreenXY, since first object overlaps and does not let click through?

One method that comes to mind is this:
1) You get an object from GetAtScreenXY.
2) Set object.Clickable = false;
3) Immediately call GetAtScreenXY again. If another object is found at the same place - repeat the cycle.
4) If no more objects found, go back, restoring object.Clickable value for every object.

You would need to have an array of Object pointers, where you will remember the objects you met this way. Every time you meet new object, you store it in the next array slot.
After you found there is no more objects, you simply iterate through all array and do Clickable = true for each object there.


PS. lastly, if you need to do something more complicated, you can always directly iterate through all objects in the room using "object" global array:
Code: Adventure Game Studio
  1. for (int i = 0; i < Room.ObjectCount; i++)
  2. {
  3.     Object *o = object[i];
  4.     // Measure object's position, size and Z-order (baseline) here, and do some stuff
  5. }
  6.  
« Last Edit: 04 Feb 2018, 13:04 by Crimson Wizard »

CW: I thought of that, But if I set the object.Clickable to false, even for a frame, it makes that wall visible again (because my function makes the wall transparent when it's colliding with my player), even if it's for a frame. Visually, it's unpleasant. At least, if I understood what you want me to do correctly. No worries, I'm sure I'm gonna figure this out on my own eventually, it's not a real problem. Even if I fail, I can always make the 2 walls to become transparent together, even though it's not my ideal solution.

What's reaaaally puzzling me now is how to make a coordinate system for an iso grid. I read a few guides online (not for AGS, but in general). It seems I need to convert cartesian coordinates into isometric ones using a couple formulas. Since you're so knowledgeable, maybe you can point me in the right direction.
And to think I thought it was a piece of cake, lol :-D

Crimson Wizard

  • AGS Project Tracker Admins
    • Best Innovation Award Winner 2013, for spearheading the AGS 3.3.0 project
    •  
    • Lifetime Achievement Award Winner
    •  
    • Crimson Wizard worked on a game that was nominated for an AGS Award!
CW: I thought of that, But if I set the object.Clickable to false, even for a frame, it makes that wall visible again (because my function makes the wall transparent when it's colliding with my player), even if it's for a frame.

But the point is to not leave it changed even for a frame. The idea was to do all processing during single frame. The game is not supposed to get redrawn while you do that.


The example of script (not tested in real game)
Code: Adventure Game Studio
  1. Object *remember_objects[10];
  2. int last_object;
  3.  
  4. for (Object *o = Object.GetAtScreenXY(x, y); o != null; o = Object.GetAtScreenXY(x, y))
  5. {
  6.     // do something with object
  7.  
  8.    
  9.     // set non-clickable and remember it
  10.     o.Clickable = false;
  11.     remembered_objects[last_object] = o;
  12.     last_object++;
  13. }
  14.  
  15. // Restore all objects
  16. for (int i = 0; i < last_object; i++)
  17. {
  18.     remembered_objects[i].Clickable = true;
  19. }
  20.  


What's reaaaally puzzling me now is how to make a coordinate system for an iso grid. I read a few guides online (not for AGS, but in general). It seems I need to convert cartesian coordinates into isometric ones using a couple formulas. Since you're so knowledgeable, maybe you can point me in the right direction.
If you read guides, you should probably use these, IDK how else to help here.
E.g. this: http://clintbellanger.net/articles/isometric_math/
Looks not very complicated.
« Last Edit: 05 Feb 2018, 00:18 by Crimson Wizard »

Thanks, CW! That sounds like it should work, I'll be testing it as soon as I finish with some other stuff. As for the iso guide, I've been reading it a lot, but I still can't figure out how to translate it to AGS. Luckily, I'm getting help via PM, so no problems there. Even if I can't figure it out eventually, this grid is not essential for my game. Cheers!