Jump to content

Display distance to a zone


ThePacman

Recommended Posts

I'm currently working on a "reverse geocache" cartridge, and I obviously need to display "Distance to GZ" on the screen.

I'm very comfortable building cartridges (I use Urwigo atm), but have never used lua code (am quite happy to use it if necessary, as I assume as there is no such standard functionality in Urwigo that I've seen).

I'm quite happy to use lua as well if necessary - just need some pointers on what sort of code I could use to get and display the distance, if anyone could please advise.

Link to comment

I'm currently working on a "reverse geocache" cartridge, and I obviously need to display "Distance to GZ" on the screen.

I'm very comfortable building cartridges (I use Urwigo atm), but have never used lua code (am quite happy to use it if necessary, as I assume as there is no such standard functionality in Urwigo that I've seen).

I'm quite happy to use lua as well if necessary - just need some pointers on what sort of code I could use to get and display the distance, if anyone could please advise.

 

I've been working on a reverse geocache cartridge myself, and have used Urwigo to implement that feature. Unfortunately my laptop is currently being repaired, however, I remember using the "distance to zone" feature. The only issue I have encountered is that the iPhone Wherigo player can't seem to calculate distance in miles. Everything else seems to work fine though!

Link to comment

This is very simple, nearly as simple as "hello world" B)

 

Create the invisible targetzone and an item. With an item command now check for distance to the target zone with the urwigo element "distance to a zone". You can show a message or (better) change the item description.

Use a numeric operation "multiply" with 1 and rounding 0 decimal places. So you get 183 meters and not 183,43645974051537 meters. After each check you increase a variable, which shows the nimber of tries.

 

reverse.JPG

Link to comment

I just created a reverse geocache Wherigo that randomizes the invisible target so it is different each and every time a person plays.

 

Mysterious Box

 

If any are interested in how I did that let me know.

 

Thanks for posting the static method, that will be very helpful for my next project I am working on as it is a much easier way to do the reverse cache concept.

Link to comment

I have tried (and failed) to replicate the above using the Earwigo builder, can anyone help?

I used the code exactly as Jonny65 has it (with Urwigo) - worked perfectly. Created a cache http://coord.info/GC5BMC9 (Black Box type cache, but you can only take a reading every 1 hour). It's a popular cache - 20 finds, 17 favourites.

I haven't tried Earwigo recently, so not sure how the "distance from a zone" would be displayed there.

Edited by ThePacman
Link to comment

I have got it working by adding a function to the Author Script part of Earwigo.

 

function getDistanceBearing(input)

 current = Player.ObjectLocation;
 distance, bearing = Wherigo.VectorToZone(current,input);

 feet = distance:GetValue"ft";
 feet = math.floor(feet);
 degrees = math.floor(bearing);

 if # Player.InsideOfZones > 0 then 
   varZone = "You are inside the zone"
 else
   varZone = "The next zone is " .. feet .. " feet away on a bearing of " .. degrees .. " degrees.";
 end

 return varZone;

end

 

This works fine when passing a 'Zone' for the parameter named 'input', however so the code can be reused I would like to pass in a variable which is set to the zone name, however when I do this I get an error of 'Second argument must be a Zone object.' which makes sense as I am passing in a string variable, but I cannot see anyway of converting it to a Zone object.

Edited by gaz_zippy
Link to comment

Why not just pass the zone object itself? If you can't do that, then you're going to have to iterate through an array of zones so you can match zone names with your string. I would try to avoid string comparisons when at all possible.

 

I do not suggest doing it this way (besides, the code isn't tested):

function getDistanceBearing(input, zoneName)

 local zone = GetZoneByName(zoneName)
 if zone == nil then
   return nil
 end

 local d,degrees = Wherigo.VectorToPoint(Player.ObjectLocation, zone.OriginalPoint)
 local feet = d("ft")
 local varZone  

 if feet <= 20 then 
   varZone = "You are inside the zone"
 else
   varZone = "The next zone is " .. feet .. " feet away on a bearing of " .. degrees .. " degrees."
 end

 return varZone

end

function GetZoneByName(name)
 local zone = nil
 for _,z in ipairs(insertYourCartridgeObjectNameHere:GetAllOfType('Zone')) do
   if z.Name == zoneName then
     return z
   end
 end

 return nil
end

 

I have a bunch of ready-made utility functions at the end of my Battleship cartridge: LineUpZones, ZonesWithinDistance, DistanceFromZone, MoveZonePoint, CreateTask, ToggleZoneStates, SetZoneLocation, CenterZoneOnPoint, MoveZoneToRandom, and CreateNewZone. These are all documented within the cartridge. Just copy and paste into your own cartridge's author script.

Link to comment

This is my first attempt at branching out from what the Earwigo menu options allow me to do, so I may be making it a bit long winded.

 

If I pass the zone object itself it all works fine, I have tried to explain what I have done so far below:

 

I have the function above in my Author Script, I then have an Earwigo function that calls this function and stores the distance/bearing string in a variable. The player has an item that sits in their inventory named Distance Checker, this item has an event attached to it named Show Distance, the user clicks this button which calls the above Earwigo function, passing the zone name (currently hard coded to the zone object), it then shows a message that simply shows the value of the variable, this does exactly what I want.

 

However the cartridge has multiple zones which only one will be active at any time (but not visible) so I was hoping that I could assign the next zone into a variable so I could reuse the above code by simply passing the variable.

 

I guess I could do more within the Author Script itself, but only just getting to grips with the syntax.

 

For me to view the functions you have written in your battleship cartridge do I simply download it and open it up in a text editor?

 

Thanks for all your help so far, much appreciated.

Link to comment

You could test against a zone's active property to discover which zone you need to use so long as you only have one active zone at a time.

 

As for Battleship, yes, just open it in a text editor and look for the line -- #Author Functions Go Here# --. As opposed to Whack-A-Lackey, Battleship is better organized and commented. As with all open source cartridges you download, you might want to play it through in the emulator before you look at the code. It's much better having an idea as to what the cartridge is doing before you look at its code.

 

In my opinion, it's much easier to learn Wherigo if you have an existing cartridge and sane code to play with.

Link to comment

I have managed to get my Distance / Bearing code to work by testing against the Active Zone, I am happy that this is working fine having tested it within the emulator and all is working fine.

 

I have created my gwz file and uploaded it to Wherigo.com and downloaded a copy of the cartridge for my Oregon 450 and also downloaded a PocketPC file via the Wherigo app on the iPhone, this is where odd things now happen:

 

The first active and visible zone has the distance range set to 25 feet as I don't want this visible until the player is in close proximity to the zone, on the Oregon this is what is happening, the zone is not visible until then, but on the iPhone I can see the zone despite not being anywhere near the required 25 feet away.

 

Another issue is with my Distance Checker, in the emulator this works as expected, showing the distance in feet and bearing in degrees to the next active zone, this also works on the Oregon, on the iPhone however I simply get an error message of 'Wherigo VectorToZone not found' followed by 'Lua Alert - Don't know how to call <null>', this message fires twice before I get the message which should show the distance and bearing, however both values are zero.

 

Has anyone else came across such an error message?

Link to comment

In my Distance / Bearing code I was using Wherigo.VectorToZone, I have now changed this to Wherigo VectorToPoint, this small change means that the code now works in the Groundspeak Emulator, the WebWigo Emulator and playing the cartridge on the Garmin Oregon and also the iPhone. Now to work out why zones that should not be visible are visible on the iPhone.

Link to comment

.... Now to work out why zones that should not be visible are visible on the iPhone.

 

Not sure why this is happening in your code, but I always add a few extra/redundant "make zone active/visible" statements to make sure my code is executed.

Add them at start of cartridge, on first active zone etc. and it may help with debugging too.

The thing is, with event-driven programming, if your "On start" event is triggered at the same time as the "On enter" of your first active zone, it is not 100% guaranteed if all the code will be executed - specially if there are different dialogs in both.

I've had different behaviour in the emulator and then in the field while testing, so I just add these additional set-statements for the zone status, and I use additional boolean switches in the initial stages of the cartridge too to execute code eg. [if #start-code-executed - false do ..... set #start-code-executed = true].

Link to comment

By the way, we're familiar with an issue regarding the iOS app's Wherigo.VectorToPoint function not returning a precise measurement. The reason behind this is it's more expensive to run the precise calculation than it is to do a shorthand calculation. The error starts showing up when you use Wherigo.VectorToPoint on longer distances, particularly when you use move all zones within a cartridge to around the user's current location, most notably to create a type of Play Anywhere cartridge. In this example, if the distance between the original cartridge's start position and the user's current position is 700 miles (1100 km), you might end up with a cartridge where the zones are around 100 miles (160 km) away.

 

As I noted, we're aware of this and have a good idea how to fix it. I do not have an estimated date when the iOS app will be updated.

 

On a side note, if you move a zone, it must be reactivated for the new coordinates to take effect.

Link to comment

 

Not sure why this is happening in your code, but I always add a few extra/redundant "make zone active/visible" statements to make sure my code is executed.

 

No code involved as such here, I simply set the zone distance property value to be 25 (feet), rather than the default value of -1 (always visible). As I understand it the zone should then only be visible when the player is within 25 feet of it. To remove device specific issues I have decided to make these zones invisible all of the time, it won't affect the player.

 

By the way, we're familiar with an issue regarding the iOS app's Wherigo.VectorToPoint function not returning a precise measurement. The reason behind this is it's more expensive to run the precise calculation than it is to do a shorthand calculation. The error starts showing up when you use Wherigo.VectorToPoint on longer distances, particularly when you use move all zones within a cartridge to around the user's current location, most notably to create a type of Play Anywhere cartridge. In this example, if the distance between the original cartridge's start position and the user's current position is 700 miles (1100 km), you might end up with a cartridge where the zones are around 100 miles (160 km) away.

 

As I noted, we're aware of this and have a good idea how to fix it. I do not have an estimated date when the iOS app will be updated.

 

On a side note, if you move a zone, it must be reactivated for the new coordinates to take effect.

 

Thanks for this, I have not planned on moving zones around, or making the cartridge play anywhere, but this information is good to know before I come across it in the future :)

Link to comment

function getDistanceBearing(input)

 current = Player.ObjectLocation;
 distance, bearing = Wherigo.VectorToZone(current,input);

 feet = distance:GetValue"ft";
 feet = math.floor(feet);
 degrees = math.floor(bearing);

 if # Player.InsideOfZones > 0 then 
   varZone = "You are inside the zone"
 else
   varZone = "The next zone is " .. feet .. " feet away on a bearing of " .. degrees .. " degrees.";
 end

 return varZone;

end

 

I know the default value of the distance object returned from Wherigo.VectorToZone is meters. And I know "ft" works for feet. But does anyone anywhere know what other units options that are available?

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...