Jibble

Author Topic: MODULE: ShowInteractiveAreas - to help Point & Click amateurs  (Read 5491 times)

Billbis

  • R, what else?
    • I can help with translating
    • Billbis worked on one or more games that was nominated for an AGS Award!
1.General presentation and Download
2.Installation
3.Optionnal configurations
4.F.A.Q.
5.Module Script
6.Alternative Edition

General presentation and Download
ShowInteractiveAreas.zip
(zip file, host by dropbox, 6,84 ko)

On most modern Point & Click, there is an keyboard key that enlights all interactive areas to player. Of course, hard core point&clicker like us hate such an options.  ;)
This module is my attempt to implement such a function in AGS project. While a key is pressed (default: space bar), a sprite (by default, yours interact and talk to mouse cursor sprites) is display on each interactive areas present at screen (visible & clickable objects, enable hotspots and clickable characters).
Before player presses space bar:

And while player presses space bar:


This is my first module. If you have any idea about how to improve it, either on the code or on the help files, please tell me.

Installation

Unzip ShowInteractiveAreas.zip
Open your AGS project
Right clic on "Scripts"
Clic on "Import script..."
Open "ShowInteractiveAreas.scm"
Done!

Optionnal configurations

sia_HOTSPOT_LIMIT might be leave as it is or be adjust to your highest Hotspot number to optimize (a very little bit) calculation time.

sia_SHOOTING_POINT_N is the number of points that will be randomly shot at screen to determine hotspot coordinates. Empirically determined by me. Increasing this number will improve accruacy, decreasing this number will improve calculation time. You may decrease this number if your game resolution is smaller than 1024*768.

Two bools are available, sia_CheatEnable and sia_EnableHere to set up this moduleas optional and to deactivate it in certain rooms or situations.

Other customizations are possible by editing ShowInteractiveArea.asc directly.
 
F.A.Q.

I have an object / hotpsot / character I do not want to be shown as active by this module. How to do that?
Spoiler: ShowHide
Several way of doing that. You may take advantage of the IsInteractionAvailable function, or create a "siaVisible" custom property that apply to objects / hotspots / character and set it true by default, and false on inactive areas. I recommend the second approach. Ask if you want more details.


Cursor is not properly positioned on fragmented hotspots.
Spoiler: ShowHide
Consider dividing your fragmented hotspots into individual non fragmented hotpots. Alternatively, you may also manually indicates hotspot coordinates in these situations (for example, in custom properties). Ask if you want more details.
Alternatively, you can use the *Alternative Edition* of this module.


On apparently random and very rare occasions, no cursor is drawn on my tiniest hotpsots.
Spoiler: ShowHide
It is not a bug, it is a feature. :D
Alternatively, you can use the *Alternative Edition* of this module.


Module Script

ShowInteractiveAreas.ash
Spoiler: ShowHide
Code: Adventure Game Studio
  1. // Script header for module 'ShowInteractiveAreas', v1.3
  2. //
  3. // Author: Billbis
  4. //
  5. // Abstract:
  6. //
  7. //   While Space Bar is pressed, this module displays a mouse cursor over each
  8. //   interactive areas. This function is present in most modern Point & Click. It helps
  9. //   players not to miss an object / hotspot / character. Ojects, characters and hotspots
  10. //   coordinates are automtically determined.
  11. //
  12. // Dependencies:
  13. //
  14. //   AGS version required:  build for AGS 3.2.1, not sure if it works with older versions.
  15. //
  16. //   AGS setting required: No particular configuration is needed.
  17. //
  18. // Configuration:
  19. //
  20. //   Optional:
  21. //
  22. //     sia_HOTSPOT_LIMIT might be leave as it is or be adjust to your highest Hotspot number
  23. //     to optimize (a very little bit) calculation time.
  24. //
  25. //     sia_SHOOTING_POINT_N is the number of points that will be randomly shot at screen to
  26. //     determine hotspot coordinates. Empirically determined by me. Increasing this number will
  27. //     improve accruacy, decreasing this number will improve calculation time. You may decrease
  28. //     this number if your game resolution is smaller than 1024*768.
  29. //
  30. //     Two bools are available, sia_CheatEnable and sia_EnableHere to set up this module
  31. //     as optional and to deactivate it in certain rooms or situations.
  32. //
  33. //     Other customizations are possible by editing ShowInteractiveArea.asc directly.
  34. //
  35. // Caveats:
  36. //
  37. //   This module uses ONE overlay, which can perturb your game if you already use 20
  38. //   of them at some point in your game (20 Overlays max display at a same time,
  39. //   AGS limitation).
  40. //
  41. //   Due to probabilistic determination of hotspots coordinates, very small hotspots might not
  42. //   be correctly detected. For sia_SHOOTING_POINT_N = 10000 and 1024*768 resolutions, hotspots
  43. //   with a total area of 55 pixels will be miss half of the time on first key press. But only
  44. //   one time over four on second key press, etc. No problems with small objects or characters.  
  45. //
  46. //   Fragmented areas or weird shapes of hotspots / objects / characters can lead to bad cursor
  47. //   positionning.
  48. //
  49. // Revision history:
  50. //   version 1.3: 07/04/2013
  51. //      Non-enabled hotspots won't be display anymore.
  52. //   version 1.2: 07/04/2013
  53. //      Non-clickable objects won't be display anymore.
  54. //   version 1.1: 03/20/2013
  55. //      The module now works when player is moving.
  56. //   version 1.0: 11/30/2012
  57. //      Improve hotspot detection (algorythm now remember hotspots it previously found).
  58. //   version beta 0.2: 11/24/2012
  59. //      *NEW* Automatic detections of hotspot coordinates.
  60. //   version beta 0.1: 11/23/2012
  61. //      First release.
  62. //  
  63. // Licence:
  64. //
  65. //   ShowInteractiveAreas AGS script module is publish under the terms of the
  66. //   Do What The Fuck You Want To Public License, Version 2
  67. //
  68. // This program is free software. It comes without any warranty, to
  69. // the extent permitted by applicable law. You can redistribute it
  70. // and/or modify it under the terms of the Do What The Fuck You Want
  71. // To Public License, Version 2, as published by Sam Hocevar. See
  72. // http://sam.zoy.org/wtfpl/COPYING for more details.
  73. //
  74. // Thanks:
  75. //
  76. //   Pidem and Kitai
  77. //
  78. // Defines
  79. #define sia_HOTSPOT_LIMIT  50
  80. #define sia_SHOOTING_POINT_N 10000
  81. // Imports
  82. import bool sia_CheatEnable, sia_EnableHere;


ShowInteractiveAreas.asc
Spoiler: ShowHide
Code: Adventure Game Studio
  1. // ShowInteractiveAreas script
  2.  
  3. //General definitions
  4.  
  5. // Three arrays that will be needed to calculate Hotspot center coordinates.
  6. int siaHotspotX[];
  7. int siaHotspotY[];
  8. int siaHotspotN[];
  9.  
  10. bool sia_CheatEnable = true; // Use this bool if you want to create an option to set this module optional.
  11. bool sia_EnableHere = true; // Use this bool in situations or rooms you do not want this module to be active.
  12.  
  13. function on_event(EventType siaevent, int siadata) {
  14.   if (siaevent == eEventEnterRoomBeforeFadein) {
  15.       siaHotspotX = new int[sia_HOTSPOT_LIMIT]; //Each time player change room, this erase old hotspot coordinates.
  16.       siaHotspotY = new int[sia_HOTSPOT_LIMIT];
  17.       siaHotspotN = new int[sia_HOTSPOT_LIMIT];
  18.   }
  19. }
  20.  
  21. //When player hits SpaceBar
  22. function on_key_press(eKeyCode keycode) {
  23.   if (keycode == eKeySpace){//Change eKeySpace by the key you want to use.
  24.     if (sia_CheatEnable && sia_EnableHere && !IsGamePaused ()) {
  25.       PauseGame();
  26.     //Screening for Hotspots.
  27.       Hotspot *h;
  28.       int index = 0;
  29.       int x, y;
  30.       while (index < sia_SHOOTING_POINT_N) { //We randomly shoot sia_SHOOTING_POINT_N points, and calculate the barycenter of each point that fall on the same Hotspot.
  31.         x = Random(System.ViewportWidth - 1);
  32.         y = Random(System.ViewportHeight - 1);
  33.         h = Hotspot.GetAtScreenXY(x, y);
  34.         if (h.ID > 0) { //Hotspot 0 is not a hotspot.
  35.           siaHotspotX[h.ID] = (siaHotspotN[h.ID]*siaHotspotX[h.ID] + x + GetViewportX()) / (siaHotspotN[h.ID] + 1) + Random(1); //Barycenter calculation
  36.           siaHotspotY[h.ID] = (siaHotspotN[h.ID]*siaHotspotY[h.ID] + y + GetViewportY()) / (siaHotspotN[h.ID] + 1) + Random(1); //Random(1) corrects AGS int rounding
  37.           siaHotspotN[h.ID] = siaHotspotN[h.ID] + 1;
  38.         }
  39.         index++;
  40.       }    
  41.       DynamicSprite *siasprite = DynamicSprite.Create(System.ViewportWidth, System.ViewportHeight); // Technical stuff to create a drawing surface
  42.       DrawingSurface *siasurface = siasprite.GetDrawingSurface();      
  43.       index = 1; //Hotspot 0 is not a hotspot.
  44.       while (index < sia_HOTSPOT_LIMIT) {
  45.         if (siaHotspotX[index] !=0 && siaHotspotY[index] !=0 && hotspot[index].Enabled) {
  46.           //If an hotspot have coordinates, we draw a mouse cursor on it.
  47.           //Alternatively, you can repalce
  48.           //    Mouse.GetModeGraphic(eModeInteract)
  49.           //by
  50.           //    42
  51.           //to use your favourite sprite number 42.
  52.           siasurface.DrawImage(siaHotspotX[index] - GetViewportX(), siaHotspotY[index] - GetViewportY(), Mouse.GetModeGraphic(eModeInteract));
  53.         }
  54.         index++;
  55.       }
  56.       //Calclucalting Objects positions and drawing cursors.
  57.       if (Room.ObjectCount > 0) {
  58.         int siaObjectX,  siaObjectY;
  59.         Object *o;
  60.         index = 0;
  61.         while (index < Room.ObjectCount) {
  62.           o = object[index];
  63.           if (o.Visible && o.Clickable) {
  64.             siaObjectX = o.X + Game.SpriteWidth[o.Graphic]/2;
  65.             siaObjectY = o.Y - Game.SpriteHeight[o.Graphic]/2;
  66.             //If an object is Visible, we draw a mouse cursor on it.
  67.             //Alternatively, you can repalce
  68.             //    Mouse.GetModeGraphic(eModeInteract)
  69.             //by
  70.             //    42
  71.             //to use your favourite sprite number 42.
  72.             siasurface.DrawImage(siaObjectX - GetViewportX(), siaObjectY - GetViewportY(), Mouse.GetModeGraphic(eModeInteract));
  73.           }
  74.           index++;
  75.         }
  76.       }
  77.       //Calclucalting Characters positions and drawing cursors.
  78.       if (Game.CharacterCount > 0) {
  79.         int siaCharacterX,  siaCharacterY;
  80.         Character *c;
  81.         index = 0;
  82.         while (index < Game.CharacterCount) {
  83.           c = character[index];
  84.           if (c.Room == player.Room && c.Clickable) {
  85.             ViewFrame *siacharcatervf = Game.GetViewFrame(c.View, c.Loop, c.Frame);
  86.             siaCharacterX = c.x;
  87.             siaCharacterY = c.y - Game.SpriteHeight[siacharcatervf.Graphic]*c.Scaling/2*100;
  88.             //If a character is clickable, then we draw a mouse cursor on it
  89.             //Alternatively, you can repalce
  90.             //    Mouse.GetModeGraphic(eModeTalkto)
  91.             //by
  92.             //    42
  93.             //to use your favourite sprite number 42.
  94.             siasurface.DrawImage(siaCharacterX - GetViewportX(), siaCharacterY - GetViewportY(), Mouse.GetModeGraphic(eModeTalkto));
  95.           }
  96.           index++;
  97.         }
  98.       }
  99.       siasurface.Release();  // Technical stuff to display the beautiful overlay we have drawn.
  100.       Overlay *siaoverlay = Overlay.CreateGraphical(0, 0, siasprite.Graphic, true);
  101.       while (IsKeyPressed(eKeySpace)) Wait(1); //While Key is pressed, overlay is display.
  102.       siaoverlay.Remove(); //Cleaning a little bit behind us.
  103.       siasprite.Delete();
  104.       siaoverlay = null ;
  105.       UnPauseGame();
  106.     }
  107.   }
  108. }
  109.  
  110. export sia_CheatEnable, sia_EnableHere; //Do not forget to import these bools in global script header if you want to use them.


Alternative Edition
ShowInteractiveAreas *Alternative Edition*
(zip file, host by dropbox, 38.5 ko)

While standard edition of this module have the cool feature "automatic hotspot coordinates determinations", it comes with a few caveats that include:
-High calculation time (usually, a drop of ~1-2 FPS is observed on SpaceBar keypress, from 40 to 38). :smiley:
-Sometimes, it missed very tiny hotspot (<<1/1000 of screen surface). :smiley:
-Bad cursor positioning on hollow / fragmented hotspots.  :sad:
Alternative edition of ShowInteractiveAreas module correct those caveats, but come without the cool feature "automatic hotspot coordinates determinations". Indeed, it is replaced by a laborious "manual specification of each hotspot coordinates by user".
Alternative edition installation and usage is globally the same as standard edition, but few exceptions:
-You MUST creates 2 hotspots coordinates names exactly "sia_PropX" and "sia_PropY", with numeric values, a default value of -1, and that apply to Characters, Objects and Hotspots.

For each hotspot, you must feed these properties with actual room coordinates (TIPS: you can copy room coordinates from the editor by doing a middle click). No cursor will be drawn on hotspots with default value on these properties.
Characters and objects can be left with default values: there coordinates will be determine in real time. But you can specify some coordinates, in that case, cursor will be drawn at these room coordinates.

Module Script of *Alternative Edition*

ShowInteractiveAreas.ash
Spoiler: ShowHide
Code: Adventure Game Studio
  1. // Script header for module 'ShowInteractiveAreas', v1.3 *Alternative Edition*
  2. //
  3. // Author: Billbis
  4. //
  5. // Abstract:
  6. //
  7. //   While Space Bar is pressed, this module displays a mouse cursor over each
  8. //   interactive areas. This function is present in most modern Point & Click. It helps
  9. //   players not to miss an object / hotspot / character. Ojects and characters coordinates
  10. //   are automtically determined. Hotspot coordinates must be entered via two custom properties.
  11. //
  12. // Dependencies:
  13. //
  14. //   AGS version required:  build for AGS 3.2.1, not sure if it works with older versions.
  15. //
  16. //   AGS setting required: You MUST creates two custom properties : sia_PropX and sia_PropY
  17. //   that aplied to Objects, Characters and Hostpots, with a numeric default value of -1.
  18. //   For each hotspot, you need to feed sia_PropX and sia_PropY with the room coordinates you want
  19. //   the cursor to be drawn.
  20. //
  21. // Configuration:
  22. //
  23. //   Optional:
  24. //
  25. //     sia_HOTSPOT_LIMIT might be leave as it is or be adjust to your highest Hotspot number
  26. //     to optimize (a very little bit) calculation time.
  27. //
  28. //     Two bools are available, sia_CheatEnable and sia_EnableHere to set up this module
  29. //     as optional and to deactivate it in certain rooms or situations.
  30. //
  31. //     You can feed sia_PropX and sia_PropY with the room coordinates for (imobile) chracter and
  32. //     object: cursor will be drawn at these positions in priority. If left to -1 (defalut value),
  33. //     objects and characters coordinates will be automaticly determined.
  34. //
  35. //     Other customizations are possible by editing ShowInteractiveArea.asc directly.
  36. //
  37. // Caveats:
  38. //
  39. //   This module uses ONE overlay, which can perturb your game if you already use 20
  40. //   of them at some point in your game (20 Overlays max display at a same time,
  41. //   AGS limitation).
  42. //  
  43. //   Fragmented areas or weird shapes of objects / characters can lead to bad cursor
  44. //   positionning.
  45. //
  46. // Revision history:
  47. //   version 1.3: 2013/07/04
  48. //      First release of SIA *alternative edition*.
  49. //  
  50. // Licence:
  51. //
  52. //   ShowInteractiveAreas AGS script module is publish under the terms of the
  53. //   Do What The Fuck You Want To Public License, Version 2
  54. //
  55. // This program is free software. It comes without any warranty, to
  56. // the extent permitted by applicable law. You can redistribute it
  57. // and/or modify it under the terms of the Do What The Fuck You Want
  58. // To Public License, Version 2, as published by Sam Hocevar. See
  59. // http://sam.zoy.org/wtfpl/COPYING for more details.
  60. //
  61. // Thanks:
  62. //
  63. //   Pidem and Kitai
  64. //
  65. // Defines
  66. #define sia_HOTSPOT_LIMIT  50
  67. // Imports
  68. import bool sia_CheatEnable, sia_EnableHere;


ShowInteractiveAreas.asc
Spoiler: ShowHide
Code: Adventure Game Studio
  1. // ShowInteractiveAreas script
  2.  
  3. //General definitions
  4.  
  5. bool sia_CheatEnable = true; // Use this bool if you want to create an option to set this module optional.
  6. bool sia_EnableHere = true; // Use this bool in situations or rooms you do not want this module to be active.
  7.  
  8. //When player hits SpaceBar
  9. function on_key_press(eKeyCode keycode) {
  10.   if (keycode == eKeySpace){//Change eKeySpace by the key you want to use.
  11.     if (sia_CheatEnable && sia_EnableHere && !IsGamePaused ()) {
  12.       PauseGame();
  13.       DynamicSprite *siasprite = DynamicSprite.Create(System.ViewportWidth, System.ViewportHeight); // Technical stuff to create a drawing surface
  14.       DrawingSurface *siasurface = siasprite.GetDrawingSurface();
  15.       Hotspot *h;
  16.       int index = 1; //Hotspot 0 is not a hotspot.
  17.       while (index < sia_HOTSPOT_LIMIT) {
  18.         h = hotspot[index];
  19.         if (h.Enabled && h.GetProperty("sia_PropX") != -1 && h.GetProperty("sia_PropY") != -1) {
  20.           //If an hotspot have non default coordinates, we draw a mouse cursor on it.
  21.           //Alternatively, you can repalce
  22.           //    Mouse.GetModeGraphic(eModeInteract)
  23.           //by
  24.           //    42
  25.           //to use your favourite sprite number 42.
  26.           siasurface.DrawImage(h.GetProperty("sia_PropX") - GetViewportX(), h.GetProperty("sia_PropY") - GetViewportY(), Mouse.GetModeGraphic(eModeInteract));
  27.         }
  28.         index++;
  29.       }
  30.       //Calclucalting Objects positions and drawing cursors.
  31.       if (Room.ObjectCount > 0) {
  32.         int siaObjectX,  siaObjectY;
  33.         Object *o;
  34.         index = 0;
  35.         while (index < Room.ObjectCount) {
  36.           o = object[index];
  37.           if (o.Visible && o.Clickable) {
  38.             if (o.GetProperty("sia_PropX") != -1 && o.GetProperty("sia_PropY") != -1) {
  39.               siaObjectX = o.GetProperty("sia_PropX");
  40.               siaObjectY = o.GetProperty("sia_PropY");
  41.             } else {
  42.               siaObjectX = o.X + Game.SpriteWidth[o.Graphic]/2;
  43.               siaObjectY = o.Y - Game.SpriteHeight[o.Graphic]/2;
  44.             }
  45.             //If an object is Visible, we draw a mouse cursor on it.
  46.             //Alternatively, you can repalce
  47.             //    Mouse.GetModeGraphic(eModeInteract)
  48.             //by
  49.             //    42
  50.             //to use your favourite sprite number 42.
  51.             siasurface.DrawImage(siaObjectX - GetViewportX(), siaObjectY - GetViewportY(), Mouse.GetModeGraphic(eModeInteract));
  52.           }
  53.           index++;
  54.         }
  55.       }
  56.       //Calclucalting Characters positions and drawing cursors.
  57.       if (Game.CharacterCount > 0) {
  58.         int siaCharacterX,  siaCharacterY;
  59.         Character *c;
  60.         index = 0;
  61.         while (index < Game.CharacterCount) {
  62.           c = character[index];
  63.           if (c.Room == player.Room && c.Clickable) {
  64.             if (c.GetProperty("sia_PropX") != -1 && c.GetProperty("sia_PropY") != -1) {
  65.               siaCharacterX = c.GetProperty("sia_PropX");
  66.               siaCharacterY = c.GetProperty("sia_PropY");
  67.             } else {
  68.               ViewFrame *siacharcatervf = Game.GetViewFrame(c.View, c.Loop, c.Frame);
  69.               siaCharacterX = c.x;
  70.               siaCharacterY = c.y - Game.SpriteHeight[siacharcatervf.Graphic]*c.Scaling/2*100;
  71.             }
  72.             //If a character is clickable, then we draw a mouse cursor on it
  73.             //Alternatively, you can repalce
  74.             //    Mouse.GetModeGraphic(eModeTalkto)
  75.             //by
  76.             //    42
  77.             //to use your favourite sprite number 42.
  78.             siasurface.DrawImage(siaCharacterX - GetViewportX(), siaCharacterY - GetViewportY(), Mouse.GetModeGraphic(eModeTalkto));
  79.           }
  80.           index++;
  81.         }
  82.       }
  83.       siasurface.Release();  // Technical stuff to display the beautiful overlay we have drawn.
  84.       Overlay *siaoverlay = Overlay.CreateGraphical(0, 0, siasprite.Graphic, true);
  85.       while (IsKeyPressed(eKeySpace)) Wait(1); //While Key is pressed, overlay is display.
  86.       siaoverlay.Remove(); //Cleaning a little bit behind us.
  87.       siasprite.Delete();
  88.       siaoverlay = null ;
  89.       UnPauseGame();
  90.     }
  91.   }
  92. }
  93.  
  94. export sia_CheatEnable, sia_EnableHere; //Do not forget to import these bools in global script header if you want to use them.
« Last Edit: 05 Jul 2013, 21:24 by Billbis »

Snarky

  • Global Moderator
  • Global Moderator
  • Mittens Lord
  • Private Insultant
    • Best Innovation Award Winner 2018, for his numerous additions to the AGS open source ecosystem including the new Awards Ceremony client and modules
    • Snarky worked on one or more games that won an AGS Award!
    •  
    • Snarky worked on one or more games that was nominated for an AGS Award!
Very useful module! But... firing random points at the screen to check for clickable stuff? Is that really the best solution to the problem? Isn't there a way to iterate through the hotspots+objects+characters+GUIs on screen and work out where they are? Then you wouldn't risk ever missing any, either.

Billbis

  • R, what else?
    • I can help with translating
    • Billbis worked on one or more games that was nominated for an AGS Award!
Ok, that's a fair enough question.
To clarify things, I just want to say that current version of this module (v1.0):
-does not care about GUI. Players never know if a tree is interactive in point & click, but let's admit he/she is smart enough to know that GUI buttons are clickable.
-perfectly detects object and characters, no matter how small they are. Simply by using object.X() and character.x().
-does perform a stochastic determination of hotspot coordinates, which is efficient (we will discuss about that).

Hotspot detection raises quite a long discussion on the French AGS forum.
It appears that to our knowledge, there is no hotspot.x() function or equivalent. This is quite understandable due to the very nature of hotspot, which is drawn by game maker and never move.
In such a situation, we explored three different approaches:
1- Create a hotspot.x() function, or an equivalent. But such a function needs to be feed with coordinates. So it was just two hotspot custom properties siaHotspotX and siaHotspotY. Game devellopers have to fill this custom properties for each hotspot in there game. The first version (dropbox link, <6ko) of the module was based on this. This a (very) laborious solution, but it is perfectly accurate and efficient. But come on, we can do better.  :smiley:
2- Screen screen (:)) for hotspots, pixel by pixel. Note that for 1024 x 768 games, that will require an noloopcheck. You immediatly feel that this is not a sustainable solution: it takes to long to be performed each time player press the key. You may want to do it on eEventEnterRoomBeforeFadein, so only once per room. But then you will have to do it not for each pixel at screen, but for each pixel present on the room ! Room size can be very different, so computation time will depend on room size. Even if you can admit that wider rooms need longer loading time, you do not expect any loading time in an adventure game. Furthermore, the future is made of HD, 4K and other retina display. So that clearly not a sustainable solution.
You might think that instead of screening each pixel individually, you can screen only 1 over 2 pixel. That is still a lot. So lets say one pixel over 16. That seems reasonable -but wait we will miss small and misplace hotspots!
3- That why I came to stochastic determination of hotspot coordinates. Which is reasonably fast and reasonably accurate. Perfect mix between the two first solution. :-D
I admit it is disturbing to know that your algorithm is not perfect and might do mistakes, but lets consider the advantages:
It is independent of game resolution, but only dependent of the relative size of your hotspot and your screen area, so quite adapted for a module.
It is accurate. Yes, it is. Let assume that your hotspot area is 1/1000 of your screen area. Which is ridiculously small for a hostpot.
The gray area is 1/1000 of the surface:

Then, on first space bar pressed, it will be missed only (999/1000)^10000 = 0.005 % percent of the time. And if it is not found on fist pressure, there is more than 99,9 % chance that it will be detect on second pressure. Module remembers previously found hotspots and will not forget them until player leaves the room.
So, basically, even if it is possible, hotspot will not be missed. Try it, you will see.  ;)
Let finished by saying that:
-Game will not crash if the module do not detect a hotspot. And player can still click on that hotspot or press space bar again. It is not a big deal.
-If you have very small hotspots and want to use my module:  make bigger hotspot, or draw an object on it, or use custom properties to enter hotspots coordinates.
-If there is an efficient and accurate way to detect hotspot, please tell me.  :-*
-You can modify and redistribute this module freely.  (nod)
And not showing small hotspots to player is a good feature to do easter eggs!
« Last Edit: 04 Dec 2012, 19:07 by Billbis »

Snarky

  • Global Moderator
  • Global Moderator
  • Mittens Lord
  • Private Insultant
    • Best Innovation Award Winner 2018, for his numerous additions to the AGS open source ecosystem including the new Awards Ceremony client and modules
    • Snarky worked on one or more games that won an AGS Award!
    •  
    • Snarky worked on one or more games that was nominated for an AGS Award!
Good answer. Thanks!

If this is a module that is supposed to be bundled with game project anyway, won't it be better to define Tip's x/y position for hotspots in hotspot's Custom Properties?

E: Ah, sorry, you mention this too, saying it's too labourous. Hmm, well, ok.
« Last Edit: 12 Dec 2012, 08:32 by Crimson Wizard »

Billbis

  • R, what else?
    • I can help with translating
    • Billbis worked on one or more games that was nominated for an AGS Award!
If one thinks he is a hard worker person, he can use the beta 0.1 version of this module, which do exactly that: require two hotspot custom properties wich contain there approximate middle point corrdinates. You can found it here (<6 ko):wink:
However, let me insist again on the fact that last version of this module will not miss reasonnably big hotspots (i.e. >= 1/1000 of screen surface).
EDIT: The irony is that on the french forum, when I first presented this module, they asked for an automatic detection of hotspot coordinates.  :P

EDIT 2013/07/05: I now recommend alternative edition v1.3 of the module, and no more beta 0.1, see first post.
« Last Edit: 05 Jul 2013, 21:25 by Billbis »

There's a function in plugin interface that returns a room mask from the engine:
Code: C++
  1. BITMAP *IAGSEngine::GetRoomMask (int32 index)
  2.  
So it is possible to get a Hotspot mask for a room, and draw it as an overlay, while the key is pressed, or something like that, similarly like walkable areas could be shown in game's Debug mode.

Never tried plugins myself though. But may be you could check that possibility out?

Billbis

  • R, what else?
    • I can help with translating
    • Billbis worked on one or more games that was nominated for an AGS Award!
Well, I am note a coder. Plugins and C++ are far to much complicated for my current skills.  :-\ But thank you for the advice.
I do not want to appear closed to optimisations, but still: do you encouter a problem with this module? Does it miss hotspots? It perfectly works with my projects (but I need more testers). We had a proverb in french: "Le mieux est l'ennemi du bien." (Better is the enemy of good.)
« Last Edit: 04 Jan 2013, 21:03 by Billbis »

No, I was just thinking about other possibilities.

This proverb is international, I guess :).

I coded a module that did the same thing a few years ago, and for hotspot detection I iterated through every third pixel horizontally and vertically and calculated the average of all x and y coords of each hotspot to get their center position.
This detects 100% of hotspots on the first try, provided that they are at least 3x3 pixels big, shows the icon at the actual center, and is very fast, too.
(And in theory allows hiding one pixel easter egg hotspots simply by placing them on coordinates where one of them isn't a multiple of 3 :))

It used a very convoluted way of displaying the icons though and I haven't released a proper, current version yet.

One suggestion I had: add the name of the hotspot next to the icon.
Fail at Floaty Rog' now!  still having to deal with what games are going through

Billbis

  • R, what else?
    • I can help with translating
    • Billbis worked on one or more games that was nominated for an AGS Award!
2013/03/20: new version (1.1).
Opening post was updated.
The module now works even if player is moving (it pauses the game while space bar is pressed).
Also I RTFM and change all the System.ScreenWidth() by System.ViewportWidth(). It's cleaner, and more efficient for hotspot detection.

2013/07/04: new minor version (v1.2).
Opening post was updated.
Non clickable objects won't be display anymore by the module.
« Last Edit: 04 Jul 2013, 20:30 by Billbis »

Billbis

  • R, what else?
    • I can help with translating
    • Billbis worked on one or more games that was nominated for an AGS Award!
Allow me to bump another time this topic:
-New minor version v1.3: Small code cleaning + non enabled hotspot won't be display anymore.
-New *Alternative edition* without automatic detection of hotspot coordinates, which is replaced by manual specification of hotspot coordinates by user on two custom properties.
See first post for details & downloads.
Side note: Thanks to PuNKKoMmANDO77, this module (and I by the same occasion) is now famous:wink: