🙋
It all started on a lazy Sunday afternoon.
I was playing GeoGuessr, guessing locations based on street views, when an idea hit me: "Why not build my own version?" I didn’t know where to start, but I was determined. Fast forward a few weeks, and I had a working prototype.
Here’s the story of how I made it happen.
As a developer, when I decided to create a GeoGuessr-like game, I knew the most important part would be the map generator. Without it, the game wouldn’t work.
I wanted to make something simple yet fun, where players could guess locations based on random street views.
In this article, I’ll walk you through how I built a custom map generator step by step. I’ll also share the full code so you can try it out yourself.
Step 1: Setting Up the Project
First, I created a new React project using Create React App. If you don’t have it installed, you can get it by running:
npx create-react-app geoguessr-clone
cd geoguessr-clone
This sets up a basic React project. Next, I installed the dependencies I needed:
npm install leaflet react-leaflet axios
- Leaflet and react-leaflet: For the map interface.
- Axios: For making API requests to Google Maps.
Step 2: Fetching Random Street Views
The core of the game is fetching random street views. Google Maps API doesn’t provide a direct way to get random locations, so I had to write a function to generate random coordinates.
Here’s how I did it:
const getRandomLocation = () => {
const lat = (Math.random() * 180 - 90).toFixed(6);
const lng = (Math.random() * 360 - 180).toFixed(6);
return { lat, lng };
};
This function generates random latitude and longitude values. However, not all coordinates have street views. To check if a location has a street view, I used the Google Street View Static API.
Here’s the code to fetch a street view image:
const API_KEY = 'YOUR_GOOGLE_MAPS_API_KEY'; // Replace with your API key
const fetchStreetView = async (lat, lng) => {
const url = `https://maps.googleapis.com/maps/api/streetview?size=600x400&location=${lat},${lng}&key=${API_KEY}`;
const response = await axios.get(url);
return response.request.responseURL; // Returns the image URL
};
Note: You’ll need a Google Maps API key to use this. You can get one from the Google Cloud Console. Be sure to enable the Street View Static API.
Step 3: Displaying the Map
Next, I used Leaflet.js to display the map. Leaflet is a lightweight library for interactive maps. Here’s how I set it up:
import { MapContainer, TileLayer, Marker } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
const Map = ({ lat, lng }) => {
return (
<MapContainer center={[lat, lng]} zoom={13} style={{ height: '400px', width: '100%' }}>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
<Marker position={[lat, lng]} />
</MapContainer>
);
};
This code creates a map with a marker at the specified latitude and longitude. I used OpenStreetMap tiles because they’re free and easy to use.
Step 4: Building the Game Logic
Now, let’s put everything together. Here’s the main game component:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Map from './Map';
const API_KEY = 'YOUR_GOOGLE_MAPS_API_KEY'; // Replace with your API key
const Game = () => {
const [streetViewUrl, setStreetViewUrl] = useState('');
const [location, setLocation] = useState({ lat: 0, lng: 0 });
const getRandomLocation = () => {
const lat = (Math.random() * 180 - 90).toFixed(6);
const lng = (Math.random() * 360 - 180).toFixed(6);
return { lat, lng };
};
const fetchStreetView = async (lat, lng) => {
const url = `https://maps.googleapis.com/maps/api/streetview?size=600x400&location=${lat},${lng}&key=${API_KEY}`;
const response = await axios.get(url);
return response.request.responseURL;
};
const startGame = async () => {
const { lat, lng } = getRandomLocation();
const imageUrl = await fetchStreetView(lat, lng);
setStreetViewUrl(imageUrl);
setLocation({ lat, lng });
};
useEffect(() => {
startGame();
}, []);
return (
<div>
<h1>Guess the Location</h1>
<img src={streetViewUrl} alt="Street View" style={{ width: '100%', height: '400px' }} />
<Map lat={location.lat} lng={location.lng} />
<button onClick={startGame}>Next Location</button>
</div>
);
};
export default Game;
Step 5: Adding User Interaction
To make the game interactive, I added a feature where players can guess the location by clicking on the map. Here’s how I did it:
const handleMapClick = (e) => {
const { lat, lng } = e.latlng;
const distance = calculateDistance(location.lat, location.lng, lat, lng);
alert(`You were ${distance.toFixed(2)} km away!`);
};
const calculateDistance = (lat1, lng1, lat2, lng2) => {
const R = 6371; // Earth's radius in km
const dLat = (lat2 - lat1) * (Math.PI / 180);
const dLng = (lng2 - lng1) * (Math.PI / 180);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * (Math.PI / 180)) * Math.cos(lat2 * (Math.PI / 180)) * Math.sin(dLng / 2) * Math.sin(dLng / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
};
This code calculates the distance between the guessed location and the actual location using the Haversine formula.
So, finally, if you have any questions or want to share your own experiences, drop a comment below. 👇👇👇
Top comments (0)