Go言語 ポートフォリオ

【第2回】Go言語(engo)でゲーム作成してみた【実装〜完成まで】

【第2回】Go言語でゲーム作成してみた

こんにちは!今回はGo言語を使ったゲーム作成の第2回です。
 
 
まだ第1回の記事を読んでいない人は、先に読むことをおすすめします!


 
 
早速作成していきましょう!

背景の作成

まずは背景を作成していきます。engoの公式ページによると、Systemは以下の3つの機能を実装しています。

3つの機能

・Update
・Remove
・New

それぞれのテンプレートはこちらです。

Update

Updateは毎フレームで呼び出されます。キャラクターの移動やジャンプをする場合は、Update()の中に処理を記述します。

Remove

Remove()はWorldからEntityを削除する時に呼び出されます。

New

NewはSystemがSceneに追加されたときに呼び出されます。今回作成する背景は特に動気がないので、New()だけソースを記述していきます。
 
 
次に、EntityとSystemを作成します。Entityは以下の3要素をメンバーに持ちます。

Entityのメンバー

・BasicEntity
・SpaceComponent
・RenderComponent

また、Systemは以下の2要素をメンバーに持ちます。

Systemのメンバー

・Entity
・World

それぞれを構造体で定義するとこうなります。

 
 
次に、必要な定数とグローバル変数を定義します。

地面、落とし穴の作成

地面・落とし穴

まずは、地面と落とし穴を作成します。地面は、リソースファイル(スプライトシート)を16px × 16pxで分割した1タイルを、深さ4、長さ200で等間隔で並べていきます。
 
 
落とし穴は、ランダムに地面を作成しないことで再現します。ランダム値は、math/randパッケージをimportすると使えるようになります。

 
 
Start地点とGoal地点に落とし穴があると、ゲームとして成立しないので、条件で除外します。
 
 
落とし穴の位置は、プレイヤーの落下や、山・土管の作成に必要な情報になるので、全位置を記録します。また、落とし穴は最低2タイルとします。

雲の作成

雲

地面の作成と同時に雲の作成を行います。

 
 
ただ雲を配置するだけだと何か物足りなかったので、今回は雲を2つ重ねて、大きな雲にしてみました。
 
 
また、リソースの性質上、雲画像はスプライトシートを32px × 32pxで分割します。NewSpritesheetWithBorderFromFile()の引数が変わっていることに注意してください。

山の作成

山

次に山を作成していきます。山は落とし穴の位置と被らないように、別途で作成します。また、この後に作成する土管と場所が被らないように、山の位置も記録します。

 
 
山はリソースファイルの都合上、5タイル分の幅が必要なので、落とし穴が一定以上幅で存在しない場所に作成します。落とし穴かどうかの判断は、以下の関数で行います。

土管の作成

土管

山と同様に土管を作成します。落とし穴が山の位置に被らないように、ランダムに作成します。

 
 
プレイヤーがぶつかったりジャンプすると上に乗れるように、土管の位置も記録します。

ゴールの作成

ゴール

ステージの最後にゴールを作成します。ゴールに使用するリソースは通常の画像ファイルなので、LoadedSprite()を使用して読み込みます。今回は、城をゴール代わりに使用します。

 
 
最後に、作成したEntityの配列をRenderSystemに追加します。これで、背景の完成です。

プレイヤーの作成

プレイヤー

次にプレイヤーを作成していきます。背景と同様に、まずは定数とグローバル変数、そしてEntityとPlayerSystemを定義します。

プレイヤーの初期設定

New()の中でプレイヤーの初期設定を行います。

 
 
プレイヤーが移動して、スクリーン幅(480px)を超えてしまうと、プレイヤーは画面から消えてしまいます。そこで、プレイヤーの移動に合わせてカメラの移動を行います。
 
 
カメラの動作は、engo/commonに用意されているCameraSystemを使用します。ここでは、カメラ範囲を設定します。

右移動

右移動

main.goで設定した名前のボタン入力を検知したら、プレイヤーを右移動させます。
 
 
今回のステージ上には土管があるので、土管用の処理が必要です。地面上を右移動していて土管がある場合は、右移動は無効にします。また、土管上から地面に右移動する場合は、プレイヤーの位置を地面上まで下げます。

 
 
カメラの移動はMailboxとCameraMessageを使用します。CameraSystemは、1つのWorldに必ず存在し、CameraMessageの送信を常に監視しています。

 
プレイヤーに動作をつけるため、右移動中はスプライトシートの読込セルをローテーションさせます。また、ジャンプ中は読込セルを固定にします。

ジャンプ

ジャンプ

同様にボタン入力を検知したら、ジャンプを行います。ジャンプは2段ジャンプできるようにしました。

 
 
ジャンプを開始する場所と着地する場所によって、プレイヤー位置をどれだけ上げるか、下げるかが変化します。

落下

落下

プレイヤーの左右の足が落とし穴の位置と一致したら、プレイヤーを落下させます。

 
 
落下後はEntityをRenderSystemから削除し、リターンします。

ゴール

ゴールしたとき

プレイヤーがゴールしたら、EntityをRenderSystemから削除します。

静止時の動作

プレイヤー 

最後に静止時の動作を作成して完成です。プレイヤーが地面と土管の上にいるときは、スプライトシートの読込セルを固定にします。

完成

これで完成です。お疲れ様でした!
 
 
本当に基本の機能しか実装していませんが、意外と落とし穴に落ちてしまい、割と楽しめるゲームができました。
 
 
今後は、別ステージ、敵キャラ、リトライ、文字表示など、色々と拡張機能が欲しいので、随時作成していきたいと思います。(第3回更新しました!)


 
 
ではまた!

 

-Go言語, ポートフォリオ
-,

© 2022 まいふぁんず