Qiita初投稿です。入門編は書くよりむしろ読む側ですが、どうぞお手柔らかによろしくお願いします。今回は、今まで全くゲーム開発を経験してこなかった自分が、業務の中でIoTの情報の可視化の手段としてゲームエンジンのEbitenの利用を検証するため、実際にゲーム開発に取り組む過程でつまずいた画像(キャラクター)の移動操作についてまとめていきます。ゲームライブラリです。(詳しくはこちら)ゲーム開発に必要なAPIが非常にシンプルにまとまっているの、自分のようなゲーム開発初心者でも簡単にゲームを作ることができます。Ebiten自体のチュートリアルやサンプルは本家が非常に充実しているので、こちらではゲーム開発特有のテクニカルな部分をまとめられればと思っています。ゲームエンジンについて実際の実装を見ていく前に、ゲームを走らせているゲームエンジンとは何かについて少しまとめておきます。ゲームエンジンは、ゲームを動かすのに必要なスクリーンの描画やサウンドなどの処理を効率化するソフトウェアです。errorで定義した画面の変化を、ebiten.Run()によって無限ループで走らせることにより、1秒につき数十回~数百回の頻度でスクリーンの描画が更新されます。ゲーム開発者としては、ゲームエンジンのおかげで画面や音の変化をいかに実装していくかということに集中することができる訳です。error内で行うことにより、ゲームが動いていることも伝わると幸いです。キャラクターを動かしたいゲーム開発でビジュアル的にもなかなか面白い部分です。座標を更新する更新後の座標の位置に画像を描画するの繰り返しで、2.の描画についてはebitenのおかげで簡単にできるので、基本的にはいかにそれぞれのキャラクターの座標更新を行うかという課題になるのですが、キャラクターの構造体があるとして、「構造体のリスト」としてデータを保持するか、「構造体のポインタのリスト」として持つかで座標更新処理は少しだけ変わってきます。時間経過で動くオブジェクトで説明します。簡単なユーザーインプットで動かす方法から見ていきます。プレイヤーの入力で動かすEbitenには、様々なユーザーインプットを読むAPIがあります。今回は単純のため、矢印キーで単体の海老天の画像を動かしてみます。Spritesのソースコードを参考に、単体の海老天を矢印キーで移動させるシンプルなプログラムです。最後にはこの海老天が矢印キーで動きます。3)インスタンス生成インスタンスspriteをポインタで保持しています。init関数内で画像の読み込みやインスタンスの生成をしています。以下のような手順です。画像ファイルをebiten.Image型に変換し、その(ポインタの)変数に受け取る(ebitenには様々な画像読み込みの関数があり、ほかのやり方でも可能)画像のサイズを変数に受け取る(ebiten.size())スクリーンのサイズに合わせ中央にキャラクターの座標を設定インスタンス化して変数に保持。errorに実装していきます。今回は矢印キーの入力を受け取りたいので、ebiten.IsKeyPressed()を使います。sprite.y)に対し行っています。最後に、それぞれ4つの矢印キーについての更新が終わった後の座標にキャラクターの画像を描画し、終了します。この全体の処理が、無限ループで回ることによりゲームが動きます。時間経過で動くオブジェクト公式のExampleであるSpritesはこの良い例かと思います。時間経過で海老天が画面内でバウンドしながら移動します。(ぜひ公式に飛んで動いているところを見てみてください。)このような時間経過でランダム(周辺でぶらつくNPCなど)、もしくは規則的に動き続けるケースは、ポインタで保持したオブジェクトに対し、ポインタレシーバの座標更新メソッドを定義してあげます。ここで、処理の実装が「構造体のリスト」か「構造体のポインタのリスト」かで少しだけ異なるので、そこから見てみます。構造体のリスト説明を簡単にするために、以下のようなケースを考えます。以下のようなObjという構造体があるとし、その中の値vを更新するためにそのポインタをレシーバに持つUpdate()関数を以下のように定義します。これにより、インスタンスについてUpdate()を呼ぶたびに中の変数vが1ずつ増えるという、1次元の座標更新と考えてみましょう。1}構造体Objのリスト(スライス)objsを使い、キャラクターを管理してみます。v=0で初期化したObjインスタンスを4つ生成し、objsに追加します。この4つのインスタンスについて、100回座標更新を行ってみましょう。この際注意しなければならないのがポインタレシーバの関数は、ポインタに対してもインスタンスに対しても呼び出せるGo言語の特性上、forループでアクセスしたオブジェクトのコピーが渡されるため、for文内のoはコピー。Updateを行った後の再代入を行う必要があるといった点です。}構造体のポインタのリスト同様のObj、Update()に対し、Objのポインタのリスト(スライス)で管理すると以下のようになります。見てわかる通り、ポインタのリストのほうがわかりやすいので、この記事ではこの方法を採用しています。Update()メソッドを定義します。1}その後、ebitenのupdate内で各characterに対しCharacter.Update()を呼ぶことで、座標を更新します。(例のようなメソッドだと、毎回のupdateで画面上のキャラクターは右に1ピクセル、下に1ピクセル移動します。任意の処理}これで時間経過でも(ユーザーインプットに依存しないような)動くキャラクターの処理をすることができます。最後に記事の内容について、よりよい実装方法などあればぜひコメントお待ちしております。upLoginユーザーは見つかりませんでした。