Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: The creature on Sat 27/06/2020 02:43:44

Title: Setting object visible on distance
Post by: The creature on Sat 27/06/2020 02:43:44
Hi

I'm a bit stuck with something that I know is probably easy. I want an object to become visible when the players gets within a set distance of it. Googling it, someone did ask a similar question and presented their code:

Code (ags) Select
  if (player.x - oTest.X <30 && player.y - oTest.Y <30)
  {
    oTest.Visible=true;
  }
  else oTest.Visible=false;


The problem is it doesn't really work, if he player is obviously approaching from the left side of the object it will be visible. Is there something simple I'm missing, or is this more complicated?

Kind Regards
C
Title: Re: Setting object visible on distance
Post by: Crimson Wizard on Sat 27/06/2020 03:09:28
The distance formula is:

Code (ags) Select
float dist = Maths.Sqrt((player.x - oTest.X)*(player.x - oTest.X) + (player.y - oTest.Y)*(player.y - oTest.Y));
if (dist < 30.0) ...


dist is guaranteed to be absolute value (>= 0)
Title: Re: Setting object visible on distance
Post by: Matti on Sat 27/06/2020 12:38:10
You could probably also use a region and its walk on/off-functions.
Title: Re: Setting object visible on distance
Post by: The creature on Sun 28/06/2020 00:49:34
I'm using regions for other things actually, otherwise that would be a good option otherwise.

I tried your code CW and I'm getting a mismatch: cannot convert 'int' to 'float' error?

Code (ags) Select
function room_RepExec()
{
  float dist = Maths.Sqrt((player.x - oTest.X)*(player.x - oTest.X) + (player.y - oTest.Y)*(player.y - oTest.Y));
  if (dist < 30.0)
     {
      oTest.Visible=true;
      }
}


I'm sure it's me and I just dont quite understand the usage of the formula.

Title: Re: Setting object visible on distance
Post by: Crimson Wizard on Sun 28/06/2020 01:58:02
I forgot to cast ints to floats, AGS requires to do this explicitly:
Code (ags) Select

float dist = Maths.Sqrt(IntToFloat(player.x - oTest.X)*IntToFloat(player.x - oTest.X) + IntToFloat(player.y - oTest.Y)*IntToFloat(player.y - oTest.Y));


or, to optimise and make it more clear:
Code (ags) Select

float x = IntToFloat(player.x - oTest.X);
float y = IntToFloat(player.y - oTest.Y);
float dist = Maths.Sqrt(x*x + y*y);
Title: Re: Setting object visible on distance
Post by: The creature on Mon 06/07/2020 02:49:08
I have been busy so, only just been able to get on and try this....and I do apologise for my ineptness in simple coding...but I can not seem to get it to work :(

function room_RepExec()
{
  float x = IntToFloat(player.x - oTest.Y);
  float y = IntToFloat(player.y - oTest.X);
  float dist = Maths.Sqrt(x*x + y*y);
  if (dist < 4.0)
  {
    oTest.Visible=true;
  }
}

I don't seem to produce any errors but when I stand by the object it doesn't appear :( I was actually also thinking of switching to characters for the objects as I'll need so many (that should be easy enough to do once the script is working). Do you have any ideas why it might not be working? :(
Title: Re: Setting object visible on distance
Post by: Crimson Wizard on Mon 06/07/2020 02:55:30
Quote from: The creature on Mon 06/07/2020 02:49:08
  float x = IntToFloat(player.x - oTest.Y);
  float y = IntToFloat(player.y - oTest.X);

You messed up X and Y here :). X should be subtracted from X and Y from Y.
Code (ags) Select

  float x = IntToFloat(player.x - oTest.X);
  float y = IntToFloat(player.y - oTest.Y);


EDIT: Other than that, 4.0 is 4 pixels, is this what you really wanted? asking to be certain.
Title: Re: Setting object visible on distance
Post by: The creature on Mon 06/07/2020 03:24:24
And that's why coding at 3am is a bad idea....

Thank you CW <3

I'm using this a lot of times so I thought it would be wise to capture the distance amount:

Code (ags) Select
function SearchSpot_Reveal(float distance)
{
  float Dist=distance;
 
  float x1 = IntToFloat(player.x - cSearchSpot1.x);
  float y1 = IntToFloat(player.y - cSearchSpot1.y);
  float dist1 = Maths.Sqrt(x1*x1 + y1*y1);
  if (dist1 < Dist)
  {
    cSearchSpot1.Clickable=true;
    cSearchSpot1.Transparency=0;
  }
   if (dist1 > Dist)
  {
    cSearchSpot1.Clickable=false;
    cSearchSpot1.Transparency=100;
  }


Works great
Title: Re: Setting object visible on distance
Post by: Khris on Mon 06/07/2020 10:05:11
You can optimize it a bit:
Code (ags) Select
int DistFromCharacter(this Character*, Character* other) {
  float dx = IntToFloat(this.x - other.x);
  float dy = IntToFloat(this.y - other.y);
  return FloatToInt(Maths.Sqrt(dx*dx + dy*dy);
}


Now you can do:
Code (ags) Select
void SearchSpot_Reveal(int threshold, Character* spot) {
  int distance = player.DistFromCharacter(spot);
  spot.Clickable = distance < threshold;
  spot.Transparency = (distance >= threshold) * 100;
}