Ebitenで作ったHello WorldをiOS端末で表示させる その1

## はじめに
Ebitenは素晴らしいことにmobile対応もしているため、作ったゲームをiOS/andoridで動かすことができます。
とはいえ、コマンド一発で全てが完了するわけではなく、ebiten側の準備、iOS用ファイルの書き出し、Xcodeの準備をする必要があります。
まずはいつものHello worldをiOSの実機で表示させるためのサンプルコードと手順を解説する第１弾としてebiten側の準備とiOS用ファイルの書き出しを説明していきます。

## 参考にしたもの
やっぱり公式の[go-inovation](https://github.com/hajimehoshi/go-inovation)に倣って作業するのが一番です

## ディレクトリ構造
.
├── hello
│   └── hello.go&emsp;&emsp;// hello worldを表示させるコードが書かれている
│
├── mobile
│   └── mobile.go&emsp;&emsp;// mobile用にhello.goを呼び出す
│   └── tools.go&emsp;&emsp;// ビルドツールのimport用？
│
└── go.mod
└── go.sum
└── main.go&emsp;&emsp;//PC用にhello.goを呼び出す

## 今回の作業の前に
公式の[ツアーのHello world](https://ebiten.org/tour/hello_world.html)を見ると、main.goの中にHello worldを表示させるコードが書いてあります。
ただし、今回はmobile用に書き出すためにinit関数の中で`mobile.SetGame`を実行する必要があります。
そこで、PCで作業する入り口をmain.goに、mobile用に書き出す入り口をmobile.goに、共有で使うコードをhello.goにします。
PCで作業をするときは`go run main.go`、mobileに書き出すときはmobile.goを使うという形で共通のhello.goが表示されるようにします。

## それぞれのコード

~~~ go:hello/hello.go
package hello

import (
	"fmt"
	"github.com/hajimehoshi/ebiten/v2"
	"github.com/hajimehoshi/ebiten/v2/ebitenutil"
)

type Game struct{}

func (g *Game) Update() error {
	return nil
}

func (g *Game) Draw(screen *ebiten.Image) {
	// Hello, WorldとTPSを画面に表示させる
	ebitenutil.DebugPrint(screen, "Hello, World!\n")
	ebitenutil.DebugPrint(screen, fmt.Sprintf("\nTPS: %0.2f", ebiten.CurrentTPS()))
}

func (g *Game) Layout(outsideWidth, outsideHeight int) (screenWidth, screenHeight int) {
	return 320, 240
}

// main.goやmobile.goで、ここで作ったGame構造体を使えるようにする重要な部分
func NewGame() (*Game, error){
		game := &Game{}
		return game, nil
}
~~~

<br>

~~~go:mobile/mobile.go
package mobile

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

	// hello-worldを表示させるファイルをインポート
	"github.com/krile136/hello-world/hello"
)

func init() {
	// helloパッケージで宣言されたGameをgameへ格納
	game, err := hello.NewGame()
	if err != nil {
		panic(err)
	}

	// helloパッケージで宣言されているGameをmobile用にセットする
	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() {}
~~~

<br>

~~~go:mobile/tools.go
// +build tools

import (
	_ "github.com/hajimehoshi/ebiten/v2/cmd/ebitenmobile"
)
~~~

<br>

~~~go:main.go
package main

import (
	"log"
	
	"github.com/hajimehoshi/ebiten/v2"

	// hello-worldを表示させるファイルをインポート
	"github.com/username/projectname/hello"
)


func main() {
	// helloパッケージで宣言されたGameをgameへ格納
	game, err := hello.NewGame()
	if err != nil {
		panic(err)
	}

	ebiten.SetWindowSize(640, 480)
	ebiten.SetWindowTitle("Hello, World!")

	// helloパッケージで宣言されているGameを実行する
	if err := ebiten.RunGame(game); err != nil {
		log.Fatal(err)
	}
}
~~~

## PCでの動作確認
main.goがあるディレクトリで、`go run main.go`を実行

## iOS用ファイルの書き出し
main.goがあるディレクトリで

~~~
$ ebitenmobile bind -target ios -o ./mobile/ios/Mobile.framework ./mobile
~~~

これは、`./mobile`フォルダにあるmobile.goを参照して、`./mobile/ios/` に `Mobile.framework`を書き出すコマンドになります。
私の環境だと`ebitenmobile`コマンドががうまく認識されなかったため

~~~
$ go run github.com/hajimehoshi/ebiten/v2/cmd/ebitenmobile bind -target ios -o ./mobile/ios/Mobile.framework ./mobile
~~~
を実行しました。

## 書き出し後
`./mobile/ios/`に`Mobile.framework`があればOKです。
これを読み込んで実機で動かすステップは、[Ebitenで作ったHello WorldをiOS端末で表示させる その2](https://qiita.com/krile136/items/b931a56cbcaa8690bc9c) で解説します。