Skip to content

Commit e347280

Browse files
authored
Merge pull request #31 from Noofbiz/mobile-building
added mobile tutorial
2 parents d284f74 + 22bd171 commit e347280

File tree

2 files changed

+324
-0
lines changed

2 files changed

+324
-0
lines changed

concepts/mobileBuilding.md

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
---
2+
layout: tutorial
3+
title: Mobile
4+
---
5+
6+
The `engo` game engine, and Go in general, has two ways to build for a
7+
mobile device: binding or building.
8+
9+
First, you'll need to [install Go Mobile] (https://github.com/golang/go/wiki/Mobile).
10+
11+
## Using gomobile build
12+
13+
To use gomobile build, simply go to the folder that you have your main package
14+
and run
15+
16+
```go
17+
gomobile build
18+
```
19+
20+
A few caveats:
21+
22+
* All your asset files must be in the asset folder to be accessed
23+
* You only have access to touch input and ogl. So you can't use things like
24+
Facebook or AdMob's sdks. This includes things like gradle and pro-guard
25+
* You'll get a generic AndroidManifest, unless you include one yourself in the
26+
same folder as your main package
27+
28+
## Using gomobile bind
29+
30+
Using bindings allows access to and from the Android system, and you can just
31+
build into your glue whatever functions you need to be called or to call.
32+
However, it is more complicated to initially setup. This is taken from [here]
33+
(https://github.com/Noofbiz/MouseTests) if you want to look at the code while
34+
reading this.
35+
36+
#### Setting up your game library
37+
First thing to notice is the file game.go here. It's an (almost) exact copy of main.go, except it's a library instead of a main package. You'll need to add
38+
39+
```go
40+
//+build !mobilebind
41+
```
42+
to the top (before package declaration) of your main, and then
43+
44+
```go
45+
//+build mobilebind
46+
```
47+
48+
to the top of the library. The other differences are that when loading a file, you can't keep assets in an asset folder for binding, so instead you'll need to use go-bindata to turn your assets into binary data. Then to load the files use
49+
50+
```go
51+
b, err := assets.Asset("icon.png")
52+
if err != nil {
53+
log.Panic("no such icon")
54+
}
55+
engo.Files.LoadReaderData("icon.png", bytes.NewReader(b))
56+
```
57+
and when you're starting a game, your main becomes a start function that can be called from the androidglue package
58+
59+
```go
60+
func Start(width, height int) {
61+
opts := engo.RunOptions{
62+
Title: "Mouse Demo",
63+
Width: 1024,
64+
Height: 640,
65+
MobileWidth: width,
66+
MobileHeight: height,
67+
}
68+
engo.Run(opts, &DefaultScene{})
69+
}
70+
```
71+
The additional options, as well as the width and height being passed in, are for Android to tell your game the actual dimensions of the screen.
72+
73+
#### Setting up the android glue
74+
Next, you'll need a package that handles communication between your Go library and Android. That's where the package androidglue comes in! androidglue.go just contains exported functions that Android can call to communicate with your game, such as tell it when to start, stop, or when touch events occur. You could potentially add more to this, for handling when to trigger a handler for the Facebook SDK or to preload an intersitial ad.
75+
76+
```go
77+
//+build mobilebind
78+
79+
package androidglue
80+
81+
import (
82+
"github.com/Noofbiz/mousetests"
83+
84+
"engo.io/engo"
85+
)
86+
87+
var running bool
88+
89+
func Start(width, height int) {
90+
running = true
91+
mousetests.Start(width, height)
92+
}
93+
94+
func Update() {
95+
engo.RunIteration()
96+
}
97+
98+
func IsRunning() bool {
99+
return running
100+
}
101+
102+
func Touch(x, y, action int) {
103+
engo.TouchEvent(x, y, action)
104+
}
105+
106+
func Stop() {
107+
running = false
108+
engo.MobileStop()
109+
}
110+
111+
```
112+
113+
And, that's it for the Go side of things. All that's left for Go is to use (inside the androidglue folder)
114+
115+
```
116+
gomobile bind -target=android -tags=mobilebind
117+
```
118+
119+
to compile the .aar library to import into Android Studio.
120+
121+
#### Setting up Android side
122+
123+
To setup the Android side, I used Android Studio. There's also a way to do it via gradle and the command line, but I don't know the exact details on doing that at the moment.
124+
125+
Start by creating a new project in Android Studio. Phone and Tablet with minimum SDK set to 15 and with no starting activity. In the AndroidManifest.xml, add a main activity. Mine ends up looking like this
126+
127+
```xml
128+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
129+
130+
package="io.engo.mousetests">
131+
132+
<application
133+
android:allowBackup="true"
134+
android:icon="@mipmap/ic_launcher"
135+
android:label="@string/app_name"
136+
android:roundIcon="@mipmap/ic_launcher_round"
137+
android:supportsRtl="true"
138+
android:theme="@style/AppTheme">
139+
<activity
140+
android:name=".MainActivity"
141+
android:screenOrientation="landscape">
142+
<intent-filter>
143+
<action android:name="android.intent.action.MAIN" />
144+
145+
<category android:name="android.intent.category.LAUNCHER" />
146+
</intent-filter>
147+
</activity>
148+
</application>
149+
150+
</manifest>
151+
```
152+
153+
and then to styles.xml I added the following to give the full screen to the gl surface view
154+
155+
```xml
156+
<item name="windowNoTitle">true</item>
157+
<item name="android:windowFullscreen">true</item>
158+
<item name="android:windowContentOverlay">@null</item>
159+
```
160+
161+
Next we have to add a main activity, by creating a MainActivity.java file.
162+
163+
```java
164+
package io.engo.mousetests;
165+
166+
import android.opengl.GLSurfaceView;
167+
import android.support.v7.app.AppCompatActivity;
168+
import android.os.Bundle;
169+
import android.util.Log;
170+
171+
public class MainActivity extends AppCompatActivity {
172+
173+
@Override
174+
protected void onCreate(Bundle savedInstanceState) {
175+
super.onCreate(savedInstanceState);
176+
setContentView(R.layout.activity_main);
177+
}
178+
179+
private GLSurfaceView glSurfaceView() {
180+
return (GLSurfaceView)this.findViewById(R.id.glview);
181+
}
182+
183+
@Override
184+
protected void onPause() {
185+
super.onPause();
186+
this.glSurfaceView().onPause();
187+
}
188+
189+
@Override
190+
protected void onResume() {
191+
super.onResume();
192+
this.glSurfaceView().onResume();
193+
}
194+
}
195+
```
196+
197+
as well as a style xml for it. Here's activity_main.xml in the layout folder
198+
199+
```xml
200+
<?xml version="1.0" encoding="utf-8"?>
201+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
202+
xmlns:tools="http://schemas.android.com/tools"
203+
android:layout_width="match_parent"
204+
android:layout_height="match_parent"
205+
tools:context="io.engo.mousetests.MainActivity"
206+
android:keepScreenOn="true" >
207+
<io.engo.mousetests.EngoGLSurfaceView
208+
android:id="@+id/glview"
209+
android:layout_width="wrap_content"
210+
android:layout_height="wrap_content"
211+
android:layout_centerHorizontal="true"
212+
android:layout_centerVertical="true" />
213+
</RelativeLayout>
214+
```
215+
216+
and finally, create the glSurfaceView. EngoGLSurfaceView.java
217+
218+
```java
219+
package io.engo.mousetests;
220+
221+
import android.content.Context;
222+
import android.content.res.Resources;
223+
import android.opengl.GLSurfaceView;
224+
import android.util.Log;
225+
import android.util.AttributeSet;
226+
import android.view.MotionEvent;
227+
228+
import javax.microedition.khronos.egl.EGLConfig;
229+
import javax.microedition.khronos.opengles.GL10;
230+
231+
import androidglue.*;
232+
233+
public class EngoGLSurfaceView extends GLSurfaceView {
234+
235+
private class EngoRenderer implements Renderer {
236+
237+
private boolean mErrored;
238+
239+
@Override
240+
public void onDrawFrame(GL10 gl) {
241+
if (mErrored) {
242+
return;
243+
}
244+
try {
245+
Androidglue.update();
246+
} catch (Exception e) {
247+
Log.e("Go Error", e.toString());
248+
mErrored = true;
249+
}
250+
}
251+
252+
@Override
253+
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
254+
}
255+
256+
@Override
257+
public void onSurfaceChanged(GL10 gl, int width, int height) {
258+
}
259+
}
260+
261+
public EngoGLSurfaceView(Context context) {
262+
super(context);
263+
initialize();
264+
}
265+
266+
public EngoGLSurfaceView(Context context, AttributeSet attrs) {
267+
super(context, attrs);
268+
initialize();
269+
}
270+
271+
private void initialize() {
272+
setEGLContextClientVersion(2);
273+
setEGLConfigChooser(8, 8, 8, 8, 0, 0);
274+
setRenderer(new EngoRenderer());
275+
}
276+
277+
@Override
278+
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
279+
super.onLayout(changed, left, top, right, bottom);
280+
281+
try {
282+
if (!Androidglue.isRunning()) {
283+
Androidglue.start(Resources.getSystem().getDisplayMetrics().widthPixels, Resources.getSystem().getDisplayMetrics().heightPixels);
284+
}
285+
} catch (Exception e) {
286+
Log.e("Go Error", e.toString());
287+
}
288+
}
289+
290+
@Override
291+
public boolean onTouchEvent(MotionEvent e) {
292+
for (int i = 0; i < e.getPointerCount(); i++) {
293+
Androidglue.touch((int)e.getX(i), (int)e.getY(i), e.getActionMasked());
294+
}
295+
return true;
296+
}
297+
298+
@Override
299+
public void onPause() {
300+
try {
301+
if (Androidglue.isRunning()) {
302+
Androidglue.stop();
303+
}
304+
} catch (Exception e) {
305+
Log.e("Go Error", e.toString());
306+
}
307+
}
308+
}
309+
```
310+
311+
Now the last part is to import the aar created by gomobile bind
312+
313+
File -> New -> New Module...
314+
315+
Pick Import .JAR/.AAR Package
316+
317+
Navigate to the .AAR package you created and import it
318+
319+
Then add it as a dependency to your android project
320+
321+
File -> Project Structure -> app -> on the dependencies tab
322+
323+
Then click the +, and under module dependencies you'll find your imported androidglue library. Everything should build nicely and you can then run it in an emulator or a device!

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ <h2>Conceptual Explanations</h2>
2525

2626
<ul class="button-group stacked">
2727
<li><a class="button" href="/concepts/animation.html">Animation</a></li>
28+
<li><a class="button" href="/concepts/mobileBuilding.html">Building for Mobile</a></li>
2829
</ul>
2930

3031
<h2>Links</h2>

0 commit comments

Comments
 (0)