OSD600 – Lab 5: The Bridge Troll

Have you played mobile games like Ingress or PokemonGo? They’re augmented-reality games which the world is literally the stage. Pokemon or nodes appear on the map and – using your device’s GPS – you physically walk to the location to interact with it.

For this lab, we worked on something similar. Our professor developed a game called “Bridge Troll” which you can find on GitHub. Our task is to take a crash course in JavaScript and develop a “night mode” for the app. The goal is to make the app switch to a darker theme when the user is playing during the night.

“We start by drawing a circle…”

To point us in the right direction, he provided us some JavaScript libraries and a site with icons that would allow us to complete the lab. The Bridge Troll app uses map tiles provided by the Leaflet library, and icons from the Material Icon set. The SunCalc library is also used to help get the sunset and sunrise times that the app will use to determine when to switch between day and night modes.

Setting up the graphical part of the app was easy. It just takes changing variables:

FindTileSet
The original code.
SwitchTileSet
Changed the URL to point to a darker map.
TileSwappedTest
And the app loads the new map tiles!

The tricky part is coding the night mode.

I start by installing the SunCalc library – which is also available as an NPM package! So that was easy.

InstallSunCalc

I did initially have some trouble getting the getTimes() function to work, but it turns out I was using it incorrectly. Heh… I was reading off their tests to try an understand how their functions work and what they return. In their tests, they used array elements to get the times. Turns out that the times are stored as attributes (which the readme did explain).

Anyway, after I figured that out, I wrote out a bit of code that sets the tileUrl to the brighter tiles during day time. By default, tileUrl was set to the darker tiles.


//Get date and sunrise and sunset times. Compare current time against sunrise and sunset times. Set to night mode.
var date = new Date('2018-03-16T23:59:59.000Z');
var sunTimes = SunCalc.getTimes(date, lat, lng);
log.info('Current date and time is:' + date + '\nTime for sunset is:' + sunTimes.sunset);
if (date > sunTimes.sunriseEnd && date < sunTimes.sunset){
log.info('The sun is up.');
tileUrl = 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png'
}else{
log.info('The sun is down. Or error.');
}

“Now we draw the rest of the owl…”

Now that I got that bit working, I have to create a day/night mode module. This means taking that bit of code, moving it to the module, and rewrite it so that the module exposes functions that other modules can use.


'use strict';
const log = require('./log');
const SunCalc = require('suncalc');
var mode = 'day';
module.exports.setMode = (lat, lng) => {
var date = new Date();//'2018-03-16T23:59:59.000Z');
var sunTimes = SunCalc.getTimes(date, lat, lng);
log.info('Current date and time is:' + date + '\nTime for sunset is:' + sunTimes.sunset);
if (date > sunTimes.sunriseEnd && date < sunTimes.sunset){
mode = "day";
log.info('The sun is up.');
}else{
mode = "night";
log.info('The sun is down. Or error.');
}
return mode;
}
module.exports.getMode = () => {
return mode;
}

view raw

daynight.js

hosted with ❤ by GitHub

The module exposes two functions:

  • A function called setMode() that takes in the latitude and longitude as arguments and passes them as well as the date to SunCalc.getTime() to get sunrise and sunset times. If the sun is still up, set mode variable to day. If the sun is down, set mode to night. This function is used in map.js right inside the initializer function. This way, when the app loads it finds out the time right away.setModeCall.PNG
  • And the function getMode() that returns the current value of the mode variable in the module. This function is used in various parts of the code:
    setLockIcon
    Set lock icons based on time of day
    setSelfMarker
    Set current location marker based on time of day.
    setTileSet
    Set tileUrl based on time of day.

    setUnlockIcon
    Set unlocked icons based on time of day.

Final Result

And this is the end result!

endResult.PNG

Oversight

After all this, there was one thing I forgot to test, and that was the bridges. I never really thought about it because my neighbourhood and my usual commute to school don’t have many bridges. I just assumed that there were no bridges nearby at all, which is why they did don’t appear on the maps. But it might be that somehow the bridges are bugged? I should ask the next time  I get the chance.

Thank you for your time!

Leave a comment