こんにちは、ハートランド・データ株式会社の草野です。
社内の”技術者研修”という活動で、ゲーム開発プロジェクトに参加しました。
プロジェクトメンバーの「ピ○パークみたいな2Dゲーム作りたい」「バグレスくん(※弊社オリジナルキャラクター)ピコピコさせたい」という意見から、
”バグレスくん”をプレイヤーとした2Dスクロールゲームを開発することに。
バグレスくんはバグ退治が趣味で、バグを食べるという設定があります。
そこで、ゲームのステージ上にバグをアイテムとして登場させ、プレイヤーであるバグレスくんがバグを獲得していく仕様にしました。
本記事では、プレイヤーの作成~アイテムの作成に焦点を絞って、今回取り組んだ内容をまとめました。
- 開発環境:Godot 4.5、Windows11
- 開発言語:GDScript
- 成果物:Godot Windowsアプリ
- 制作チーム:Bloom Bit Lab. (B.B.Lab.)
- 想定読者:Godotでこれから2Dゲームを作ってみたい人
2Dゲーム開発を始める前の事前学習
今回集まったメンバーは全員ゲーム開発未経験で、開発環境として選定したGodotもまったく触れたことがありませんでした。
なので、どんなゲームにするかのアイディア出しと並行して、まずは公式が出している2Dゲーム用のチュートリアルをやってみるところから始めました。
公式チュートリアルに取り組むことで、エディタの基本操作やシーン構成、ノードの考え方がなんとなく理解できました。
公式チュートリアルは、プレイヤーが上下左右に動くトップダウン型の2Dゲームを題材にしています。一方で、今回作りたかったのは、プレイヤーがジャンプしたり、足場に乗ったりしながらステージを進んでいく2Dプラットフォーマー寄りのゲームです。
そのため、公式チュートリアルで基本を押さえたあと、横スクロールアクションに近い挙動を学べる以下のチュートリアルも少し参考にしました。
プレイヤーを作る
ゲームの印象を大きく左右する要素のひとつが、プレイヤーやアイテムなどのグラフィックです。
いい絵があるとモチベも上がります。
今回はレトロな2Dゲームの雰囲気を目指していたため、全体の見た目をドット絵で統一する方針にしました。
ドット絵を作成するツールはいろいろありますが、今回、プレイヤーであるバグレスくんのグラフィックは、GraphicsGale というドット絵・アニメーション作成ツールを使って作成しました。
今回、画像サイズ自体は 100 pixel 前後にしたいけれど、ドット自体は粗い感じの絵にしたかったので、そのあたりの GraphicsGale を使用した描き方は以下のページを参考にしました。
画像サイズは 128×128 pixel、ドットは 32×32 で作成しました。
止まっている時と走っている時のアニメーションです。かわいいですね。
動いているところを見せたかったのでGIFを貼りましたが、Godotでアニメーションとして扱う場合は、GIFをそのまま読み込むことはできません。各フレームの画像やスプライトシートを用意して設定する必要があります。
チュートリアルで使用されていたプレイヤーのグラフィックほどのフレーム数を用意するのは大変だったので、今回は1つのアニメーションにつき多くても2枚程度のフレームにしました。
なお、今回はメンバーで分担して、プレイヤーだけでなくアイテム、モブ、背景などの素材もツールやAIを使用して作成しました。
Piskel というWebブラウザ上で使えるドット絵作成ツールを使用したメンバーもいました。
ちなみに余談ですが、今回作成したバグレスくんのGIFは、弊社Teamsのカスタム絵文字など、ゲーム以外でも活用されています😊
プレイヤーのシーンを作成する
プレイヤーのグラフィックが用意できたら、次にGodot上でプレイヤー用のシーンを作成します。基本的な流れは、参考にした2Dプラットフォーマーのチュートリアルに沿って進めました。
Godotでは、ゲーム内の要素を「シーン」として分けて作成できます。プレイヤーもひとつのシーンとして作っておくことで、あとから別なシーンに配置したり、設定を調整したりしやすくなります。
今回作成したプレイヤーシーンは以下のようなノードで構成されています。
- CharacterBody2D (チュートリアルに倣って Player というクラス名を付けました)
- AnimatedSprite2D (各モーションのアニメーションを再生するためのノード)
- CollisionShape2D (当たり判定用ノード)
- Camera2D (プレイヤーを中心としてゲーム画面を表示するためのカメラノード)
- AudioStreamPlayer2D (ジャンプ時に効果音を再生するためのノード)
ゲーム作成時は気づかずに各フレームの画像を1枚ずつ用意して追加していたのですが、GraphicsGale で ファイル > エクスポート > タイプ で”連結画像”を選択してエクスポートすれば、全フレームの画像を連結した1枚の画像(スプライトシート)で出力することができます。
こんなの
これなら、チュートリアルの「スプライトシートからフレームを追加」と同じ手順でまとめてフレームを追加できます。
フレーム数が多い場合は、こちらの方法のほうがより効率的だと思います。
プレイヤーを動かす(スクリプトの追加)
プレイヤーのシーンができたら、キーボード入力に応じて移動やジャンプができるようにスクリプトを追加します。スクリプトのアタッチ方法や基本的なコードは、参考にしたチュートリアルとほぼ同じ流れで実装しました。
ジャンプ力や移動速度などの数値は、実際にステージ上でプレイヤーを動かしながら調整していきました。
いい感じ
アイテムをゲットする
アイテムのシーンを追加する
プレイヤーを動かせるようになったら、次はステージ上で獲得できるアイテムを追加しました。今回のゲームでは、バグレスくんがバグを食べるという設定に合わせて、バグをアイテムとして配置しています。
アイテムもプレイヤーと同じように、ひとつのシーンとして作成しました。シーンとして分けておくと、同じアイテムを複数の場所に配置したり、別の種類のアイテムを作ったりするときに扱いやすくなります。
アイテムシーンは以下のようなノードで構成されています。
- Area2D
- AnimatedSprite2D (アニメーションを再生するためのノード)
- CollisionShape2D (当たり判定用ノード)
基本的な作り方は、プレイヤーのシーンを作成したときと大きく変わりません。画像を用意し、当たり判定用のノードを設定して、プレイヤーが触れたことを検知できるようにしていきます。
スクリプトの共通化
アイテムを複数作っていく中で、最初は、これまでのチュートリアルで学んだ手順通り、各シーンで新規スクリプトをアタッチして、一つのシーンにつき一つのスクリプトを作成していました。しかし、実装を進めてみると、どのアイテムでも必要な処理はほとんど同じでした。
具体的に、今回のアイテムに必要な処理は以下です。
- 自分の当たり判定エリアに入ってきたノードを検知する
- それがプレイヤーかどうかを判定する
- プレイヤーが触れたら獲得されたことを通知し、自分自身を消す
アイテムごとに見た目は違っても、獲得時の基本処理は共通化できます。
そこで、アイテム用の共通スクリプトをひとつ用意し、複数のアイテムシーンから同じスクリプトを参照する形にしました。
以下のコードでは、Area2Dに入ってきたノードがPlayerだった場合に、取得イベントを通知してアイテム自身を削除します。
extends Area2D
func _ready() -> void:
if not body_entered.is_connected(_on_body_entered):
body_entered.connect(_on_body_entered)
# プレイヤーがこのエリアに入った時に呼ばれる
func _on_body_entered(body: Node2D):
# body はこのシーンのエリアに入ってきた「もの」
# プレイヤーかどうかを確認
if body is Player and visible:
collect_bug()
func collect_bug():
# ステージ(親)に向かって通知を飛ばす
# ※SignalManager は、アイテム取得時などのシグナルをまとめるために独自で用意した Autoload です。
SignalManager.collected.emit()
# 自身を画面から消す
queue_free()
Godotでは、既存のスクリプトをノードにアタッチできるため、毎回新しいスクリプトを作らなくても済みます。
ゲームっぽい!
小さなゲームであっても、同じ処理を何度も書かないようにしておくと、あとから修正するときに楽になります。今回のように「処理は同じで見た目だけ違う」ものは、共通化を考える良いポイントだと思いました。
まとめ
今回は、2Dゲームのプレイヤー作成からアイテム作成についてまとめてみました。
最初はGodotの基本操作から学ぶ必要がありましたが、チュートリアルを参考にしながら進めることで、シーンの作成、画像の設定、スクリプトの追加、当たり判定の実装といった基本的な流れを少しずつ理解できました。
また、実際に作ってみることで、素材の作り方やスクリプトの持たせ方にも改善できる点が見えてきました。今回はアイテムのスクリプトを共通化した程度でしたが、ゲームの規模が大きくなるほど、同じ処理や似た構成を整理しておくことが重要になりそうです。
今回の実装で得られたポイントは以下です。
- プレイヤーやアイテムはシーンとして分けると管理しやすい
- アニメーション素材はスプライトシートで用意すると扱いやすい
- 見た目だけが違うアイテムは、共通スクリプトで処理をまとめられる
特に、スクリプトや画像ファイルの管理は、あとから機能追加や調整をするときの作業量に大きく影響します。小さな段階から共通化や整理を意識しておくことで、開発を進めやすくできると感じました。
参考文献
参考にした記事・ドキュメント





