Mobile

tl;dr

Use ebitenmobile command to create a shared library. The generated library includes a complete and easy-to-use view (or view controller) class.

Create a shared library with ebitenmobile bind (Recommended)

Install ebitenmobile command first:

go install github.com/hajimehoshi/ebiten/cmd/ebitenmobile

Create a package for mobiles to use github.com/hajimehoshi/ebiten/mobile:

package yourgamemobile

import (
    "github.com/hajimehoshi/ebiten"
    "github.com/hajimehoshi/ebiten/mobile"

    "github.com/yourname/yourgame"
)

// game implements mobile.Game interface.
type game struct{
}

// Update is called every frame. This is same as an update function passed to ebiten.Run.
func (g *game) Update(screen *ebiten.Image) error {
    return yourgame.Update(screen)
}

// Layout is called when the game is initialized or the view size is changed.
// You can return a fixed screen size, or you can calculate a screen size based on the given view size.
// The scaling is automatically adjusted.
func (g *game) Layout(viewWidth, viewHeight int) (screenWidth, screenHeight int) {
    return 320, 240
}

func init() {
    mobile.SetGame(&game{})
}

// Dummy is a dummy exported function.
//
// gomobile doesn't compile a package that doesn't include any exported function.
// Dummy forces gomobile to compile this package.
func Dummy() {}

The key function is SetGame, and you can ignore the other functions in the mobile package.

Android

Run ebitenmobile bind command for your package:

env GO111MODULE=off ebitenmobile bind -target android -javapkg [your.domain] -o [path/to/yourgame.aar] [github.com/yourname/yourgame/yourgamemobile]

Then your can get a .aar file. This .aar file defines a view class named EbitenView under the specified Java package (-javapkg option + your package name). You can put it on your screen. That's it!

The view class is defined like this:

package your.domain.yourgamemobile;

import android.view.ViewGroup;

public class EbitenView extends ViewGroup {
    // onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
    // You can define your own error handler, e.g., using Crashlytics, by overwriting this method.
    protected void onErrorOnGameUpdate(Exception e) {
        // Default error handling implementation.
    }

    // suspendGame suspends the game.
    // It is recommended to call this when the application is being suspended e.g.,
    // Activity's onPause is called.
    public void suspendGame() {
        // ...
    }

    // resumeGame resumes the game.
    // It is recommended to call this when the application is being resumed e.g.,
    // Activity's onResume is called.
    public void resumeGame() {
        // ...
    }
}

iOS

Run ebitenmobile bind command for your package:

env GO111MODULE=off ebitenmobile bind -target ios -o [path/to/yourgame.framework] [github.com/yourname/yourgame/yourgamemobile]

Then your can get a .framework file. This .framework defines a view controller class named (Package Name)EbitenViewController. You can put it on your screen by connecting with any UIView. That's it!

The view controller class is defined like this:

#import <UIKit/UIKit.h>

@interface YourgamemobileEbitenViewController : UIViewController

// onErrorOnGameUpdate is called on the main thread when an error happens when updating a game.
// You can define your own error handler, e.g., using Crashlytics, by overwriting this method.
- (void)onErrorOnGameUpdate:(NSError*)err;

// suspendGame suspends the game.
// It is recommended to call this when the application is being suspended e.g.,
// UIApplicationDelegate's applicationWillResignActive is called.
- (void)suspendGame;

// resumeGame resumes the game.
// It is recommended to call this when the application is being resumed e.g.,
// UIApplicationDelegate's applicationDidBecomeActive is called.
- (void)resumeGame;

@end

Example

go-inovation is a complete example to use ebitenmobile bind.

Why ebitenmobile bind?

Why not a complete application instead of a shared library?

It is because it is not feasible to write a mobile application only in Go yet.

Create a shared library with gomobile bind (Deprecated)

This way is deprecated so use ebitenmobile bind if possible. This feature is kept for backward compatibility.

Install gomobile command first.

go install golang.org/x/mobile/cmd/...

Create a package for mobiles to use github.com/hajimehoshi/ebiten/mobile:

package mobile

import (
    "github.com/hajimehoshi/ebiten/mobile"
    "github.com/yourname/yourgame"
)

var (
    running bool
)

const (
    ScreenWidth  = 320
    ScreenHeight = 240
)

// IsRunning returns a boolean value indicating whether the game is running.
func IsRunning() bool {
    return running
}

// Start starts the game.
func Start(scale float64) error {
    running = true
    game, err := yourgame.NewGame()
    if err != nil {
        return err
    }
    // mobile.Start starts the game.
    // In this function, scale is passed from Java/Objecitve-C side
    // and pass it to mobile.Start. You can also receive the screen
    // size from Java/Objetive-C side by adding arguments to this
    // function if you want to make Java/Objective-C side decide the
    // screen size.
    // Note that the screen size unit is dp (device-independent pixel)
    // on Android.
    if err := mobile.Start(game.Update, ScreenWidth, ScreenHeight, scale, "Your Game's Title"); err != nil {
        return err
    }
    return nil
}

// Update proceeds the game.
func Update() error {
    return mobile.Update()
}

// UpdateTouchesOnAndroid dispatches touch events on Android.
func UpdateTouchesOnAndroid(action int, id int, x, y int) {
    mobile.UpdateTouchesOnAndroid(action, id, x, y)
}

// UpdateTouchesOnIOS dispatches touch events on iOS.
func UpdateTouchesOnIOS(phase int, ptr int64, x, y int) {
    // Prepare this function if you also want to make your game run on iOS.
    mobile.UpdateTouchesOnIOS(phase, ptr, x, y)
}

Android

(TBD)

iOS

(TBD)

Create an application with gomobile build (For testing only)

Ebiten application also works with gomobile build. This is useful for testing, but not suitable for actual applications in the stores.

Install gomobile command first.

go install golang.org/x/mobile/cmd/...

Then, run gomobile build

env GO111MODULE=off gomobile build [github.com/yourname/yourpackage]

That's it!

You can install an Ebiten's example directly with gomobile install on your Android device:

env GO111MODULE=off gomobile install -tags=example github.com/hajimehoshi/ebiten/examples/paint

For more details, see the official Wiki page about gomobile