-
-
Notifications
You must be signed in to change notification settings - Fork 664
Android
Hajime Hoshi edited this page Sep 23, 2022
·
26 revisions
This document describes about a deprecated feature. Use ebitenmobile
command instead. See https://ebitengine.org/en/documents/mobile.html
See the document Mobile for details common in Android and iOS.
In this article, we explain gomobile bind
usage, not gomobile build
usage.
See https://github.com/hajimehoshi/ebiten/wiki/Mobile#create-a-package-for-mobiles.
Use gomobile bind
, generate an aar file and import this to your Android Studio project as an external aar file. Here is the example command to build the package.
:; gomobile bind -target android -javapkg com.example.yourgame -o /path/to/android/studio/project/mobile.aar github.com/yourname/yourgame/mobile
The below implementation implements a GLSurfaceView class and its Renderer class. When the view's onLayout
is called, the size of view is calculated and the game starts if the game doesn't start yet.
For an actual example, see go-inovation's EbitenGLSurfaceView.java.
package com.example.yourgame;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.util.Log;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import com.hajimehoshi.goinovation.mobile.*;
public class EbitenGLSurfaceView extends GLSurfaceView {
private class EbitenRenderer implements Renderer {
private boolean mErrored;
@Override
public void onDrawFrame(GL10 gl) {
if (mErrored) {
return;
}
try {
// onDrawFrame is called every frame.
// Let's call your game's Update.
Mobile.Update();
} catch (Exception e) {
Log.e("Go Error", e.toString());
mErrored = true;
}
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
}
}
private double mDeviceScale = 0.0;
public EbitenGLSurfaceView(Context context) {
super(context);
initialize();
}
public EbitenGLSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
private void initialize() {
setEGLContextClientVersion(2);
setEGLConfigChooser(8, 8, 8, 8, 0, 0);
setRenderer(new EbitenRenderer());
}
// pxToDp converts an value in pixels to dp.
// Note that Ebiten's mobile.Start accepts size value in dp.
private double pxToDp(double x) {
if (mDeviceScale == 0.0) {
mDeviceScale = getResources().getDisplayMetrics().density;
}
return x / mDeviceScale;
}
// getScaleInPx returns a scale value which fits the parent view.
public double getScaleInPx() {
View parent = (View)getParent();
return Math.max(1,
Math.min(parent.getWidth() / (double)Mobile.ScreenWidth,
parent.getHeight() / (double)Mobile.ScreenHeight));
}
@Override
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
// Calculate the scale fitting the screen and use it.
double scaleInPx = getScaleInPx();
getLayoutParams().width = (int)(Mobile.ScreenWidth * scaleInPx);
getLayoutParams().height = (int)(Mobile.ScreenHeight * scaleInPx);
try {
if (!Mobile.IsRunning()) {
Mobile.Start(pxToDp(scaleInPx));
}
} catch (Exception e) {
Log.e("Go Error", e.toString());
}
// If you want to center this view, you can set `android:layout_centerHorizontal="true"` and
// `android:layout_centerVertical="true"` in the layout XML.
}
@Override
public boolean onTouchEvent(MotionEvent e) {
for (int i = 0; i < e.getPointerCount(); i++) {
int id = e.getPointerId(i);
int x = (int)e.getX(i);
int y = (int)e.getY(i);
// Call `mobile.UpdateTouchesOnAndroid` via your exported function.
// The position is in dp.
Mobile.UpdateTouchesOnAndroid(e.getActionMasked(), id, (int)pxToDp(x), (int)pxToDp(y));
}
return true;
}
}
Note that Seq.setContext
must be called when the activity is created.
// ...
import go.Seq;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Seq.setContext(getApplicationContext());
}
// ...
}