Pokemon Go Example by using Google Maps

pokemon_go.jpg?w=2924

I was wondering how to do the map display just like Pokemon Go! Game does. Let’s check how it looks from the below screenshot.

pokemongo.png
Pokemon Go Screenshot

You can see Google Maps in this game is not vertical. It uses a bearing angle to display the map. Let’s see what I’ve done now.

screenshot_1559141427.png

Hey, what do you think? It looks very similar. I use Github office’s Latlng as the center point. So, you can see the Github building marker point in the center part of the whole screen. Then, the next question is, how do I show the map with an angle. Talk is cheap, show me the code.

Let’s check the UI layout first. As you can see, there’re two parts of the screen. The top part is the cloud background, it’s pretty obvious, just an ImageView. The bottom part is the MapFragment.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="170dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/sky"/>
</RelativeLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
</RelativeLayout>

</LinearLayout>

It would be a little bit weird if we directly separate the screen into two different parts. It would look like this.

screenshot_1559141772.png

Uh-hmm, it’s not what we thought. (Let’s ignore the map angle and focus on the layout first.) We’re going to do more in our layout file. Let’s add some drawables to make it better.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="170dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="@drawable/sky"/>
<View
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_alignParentBottom="true"
android:background="@drawable/toppart"/>
</RelativeLayout>

<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
tools:context=".MapsActivity"
android:name="com.google.android.gms.maps.SupportMapFragment"/>
<View
android:layout_width="match_parent"
android:layout_height="20dp"
android:background="@drawable/bottompart"/>

</RelativeLayout>

</LinearLayout>

I add two drawable resources to display the border between ImageView and MapFragment.

toppart.xml

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="90"
android:startColor="#ffffff"
android:endColor="#00ffffff" />
</shape>

bottompart.xml

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="270"
android:startColor="#ffffff"
android:endColor="#00ffffff" />
</shape>

It’s much better now. You can merge toppart.xml and bottompart.xml into one drawable cause we use gradient here.

screenshot_1559141804.png

Then, if you want, you can also add an overlay on top of the map, just like this.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
...

<RelativeLayout
...
</RelativeLayout>

<RelativeLayout
...
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#2200ffee"/>
...
</RelativeLayout>

</LinearLayout>

So, the final layout would look like this.

screenshot_1559141817.png

Then, here comes the second question, how do we let GoogleMap tilt to different angles? GoogleMaps SDK already provides that function for us.

1
2
3
4
5
6
7
val cameraPosition = CameraPosition.Builder()
.target(LatLng(37.782198, -122.391364))
.zoom(18f)
.tilt(67.5f)
.bearing(314f)
.build()
map.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition))

By using the tilt and bearing, you can set up proper values to adjust the Google Maps camera angle.

That’s it. Happy coding.