The engine can submit a code by itself once the player has reached a given spot on the ground. The points are defined in the “Level script”, and the checking happens in the player's browser using geolocation data.
Important: geolocation only starts with the player's permission — the browser asks the first time it is used. If the player refuses, the points will never fire, so always leave a fallback way through the level (a plain code, a hint that gives the answer away).
Just call gps_start() in the “Level script” field. The engine loads the geolocation library only when it finds that name in the script — nothing else has to be switched on.
gps_start();
From that moment the browser starts watching the player's coordinates (watchPosition with high accuracy) and recalculates all the defined points every time they are updated.
Points are put into the g_targets array. Each point is an object with coordinates, a radius and actions:
gps_start(); window.target_lat1 = 51.5211367; // Latitude of the point window.target_lon1 = -0.10723867; // Longitude of the point g_targets.push({ 'lat': window.target_lat1, 'lon': window.target_lon1, 'r': 30, // Radius in METRES 'action_inside': "enter_silent('finish_code_123')", 'action_outside': "$('#distance_to').text(gps_distance(window.target_lat1, window.target_lon1).toFixed(0))" });
lat, lon — the coordinates of the point.r — the trigger radius in metres.action_inside — a string of JavaScript, executed while the player is inside the radius.action_outside — a string of JavaScript, executed while the player is outside the radius.
There can be as many points as you like — just push several objects into g_targets.
The actions run on every coordinate update, not once when the player enters the zone. As long as the player stands inside the radius,action_insidewill fire again and again. For submitting a code that is harmless:enter()andenter_silent()send a code only once. Showing a message or playing a sound, however, is better guarded with a flag of your own:
'action_inside': "if (!window.was_inside) { window.was_inside = 1; play_sound('limit'); }"
The function gps_distance(latitude, longitude) returns the distance from the player's current position to the given point in metres. It is usually shown to the player so they can tell whether they are getting warmer or colder:
<p>Distance to the point: <span id="distance_to">???</span> m.</p>
The function can only be called once the first coordinates have arrived — before that the player's position is unknown. The easiest way is to call it from action_outside, as in the example above: the engine will run it itself as soon as the coordinates appear.
If you need more than a radius check — drawing a map or your own indicator, say — override the on_update_position() function: the engine calls it every time new coordinates arrive. The current position is in g_position (the lat and lon fields):
gps_start(); on_update_position = function () { $('#my_coords').text(g_position.lat.toFixed(5) + ', ' + g_position.lon.toFixed(5)); };
The engine does not load any mapping libraries — the author adds the map to the task text personally. The example below uses the free Leaflet with OpenStreetMap tiles: the library's CSS and JS are included, a map container is created, and a marker moves along with the player's coordinates.
Keep in mind that the task is redrawn on every auto-refresh, so it is convenient to keep the state of the map (centre, zoom, the map object) in window, so that it is not created anew and does not jump around under the player.
Testing a GPS level by running around the street is not much fun. There is a service function init_debug_map(latitude, longitude, zoom): it draws a map with your points and radii on it and puts down a draggable player marker. Wherever you drag the marker is where the engine will believe the player to be, so a point can be checked without leaving home.
The function works on Google Maps and expects a <div id=“debug_map”> container on the page. The engine does not load the Google Maps library — you have to add it to the task text yourself, with your own API key.
If the plot only needs to send the player to a spot rather than check that they arrived, an ordinary link is enough. Insert it in “Source” mode:
<a href="geo:?q=59.249,37.465">59.249, 37.465</a>
The geo: scheme opens the coordinates in whatever navigation app is installed on the phone. For desktop browsers, which have no such scheme, a link to a map service will do:
<a href="https://www.google.com/maps/search/?api=1&query=49.940333,36.39305" target="_blank">49.940333, 36.39305</a>
Example of submitting a code by coordinates | Example with a map | Example of links to coordinates