Setting object visible on distance

Started by The creature, Sat 27/06/2020 02:43:44

Previous topic - Next topic

The creature

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
  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

Crimson Wizard

#1
The distance formula is:

Code: ags
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)

Matti

You could probably also use a region and its walk on/off-functions.

The creature

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
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.


Crimson Wizard

I forgot to cast ints to floats, AGS requires to do this explicitly:
Code: ags

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

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

The creature

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? :(

Crimson Wizard

#6
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

  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.

The creature

#7
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
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

Khris

You can optimize it a bit:
Code: ags
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
void SearchSpot_Reveal(int threshold, Character* spot) {
  int distance = player.DistFromCharacter(spot);
  spot.Clickable = distance < threshold;
  spot.Transparency = (distance >= threshold) * 100;
}

SMF spam blocked by CleanTalk