Build a Location Guessing Game with Google Maps JavaScript API
content:
Creating an engaging location-based game requires precise map interactions and feedback systems. After analyzing this developer’s implementation, I’ve distilled the most effective techniques for building a double-click guessing game with distance reporting using Google Maps JavaScript API.
Essential Setup and Map Configuration
Begin by initializing a map in a strategically positioned container. Use CSS to overlay it in the bottom-right corner:
#map {
position: absolute;
height: 45vh;
width: 35vw;
top: 50%;
left: 62%;
z-index: 100;
}
Critical configuration details from the video:
- Set initial zoom to
1with a global view (e.g., coordinates[0, 0]) - Disable unnecessary controls:
const mapOptions = {
streetViewControl: false,
mapTypeControl: false,
minZoom: 1,
maxZoom: 18,
restriction: {
latLngBounds: {north: 85, south: -85, east: 180, west: -180},
strictBounds: true
}
};
Pro Tip: Test pan/zoom restrictions early. Unexpected behavior often stems from misplaced commas or incorrect coordinate boundaries.
Implementing Double-Click Guessing
Attach an event listener to capture user guesses:
google.maps.event.addListener(map, 'dblclick', (event) => {
if (played) return; // Prevent multiple guesses
const guessLatLng = event.latLng;
placeGuessMarker(guessLatLng);
calculateDistance(guessLatLng, targetLatLng);
});
Key considerations:
- Use
event.latLngfor precise coordinates - Declare markers outside handlers (avoid
varscoping issues) - Custom markers improve UX:
new google.maps.Marker({
position: targetLatLng,
map: map,
icon: {
url: 'target.png',
scaledSize: new google.maps.Size(30, 30),
anchor: new google.maps.Point(15, 15)
}
});
Distance Calculation and Feedback
Implement the Haversine formula for accuracy:
function toRadians(degrees) {
return degrees * Math.PI / 180;
}
function calculateDistance(guess, target) {
const R = 6371; // Earth's radius in km
const φ1 = toRadians(guess.lat());
const φ2 = toRadians(target.lat());
const Δφ = toRadians(target.lat()-guess.lat());
const Δλ = toRadians(target.lng()-guess.lng());
const a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
Display results dynamically:
- Update InfoWindows with rounded distance:
infoWindow.setContent(`You're ${distance.toFixed(1)} km away!`);
infoWindow.open(map, guessMarker);
- Draw polylines between points:
const linePath = new google.maps.Polyline({
path: [guessLatLng, targetLatLng],
geodesic: true,
strokeColor: "#FF0000",
strokeOpacity: 1.0,
strokeWeight: 2
});
linePath.setMap(map);
Game State Management
Control flow with these mechanics:
- Initialize
let played = falseglobally - Toggle UI elements post-guess:
function showHideMap() {
const mapDiv = document.getElementById('map');
mapDiv.style.display = mapDiv.style.display === 'none' ? 'block' : 'none';
}
// In double-click handler:
played = true;
document.getElementById('game-btn').onclick = playAgain;
- Reset functionality:
function playAgain() {
played = false;
document.getElementById('game-btn').innerHTML = "Show/Hide Map";
document.getElementById('game-btn').onclick = showHideMap;
initGame(); // Reinitialize map/new location
}
Advanced Implementation Tips
Location Management:
- Start with 5-10 familiar locations for easier debugging
- Store coordinates in a 2D array:
const locations = [
{name: "Edinburgh", coords: [55.9533, -3.1883]},
{name: "Auckland", coords: [-36.8485, 174.7633]}
];
- Use
Math.random()to select targets
Debugging Strategies:
- Check console for capitalization errors (e.g.,
LatLngvslatLng) - Verify CSS positioning percentages
- Test event listeners with simple
console.logbefore complex logic
Recommended Resources
- Google Maps JavaScript API Documentation - Official references with live samples
- Geospatial Formulas Explained - Interactive Haversine calculator
- OpenStreetMap - For finding precise coordinates
Final Thought: When implementing this, which component—map positioning, event listeners, or distance calculation—do you anticipate being most challenging? Share your experience in the comments!
Pro Insight: Based on testing similar implementations, I recommend using SVG markers instead of PNGs for scalability. Also consider adding difficulty levels through zoom restrictions—beginner (zoom 5-10), expert (zoom 1-15).