2D / 3D ゲームを作成できる無料・オープンソースの軽快なゲームエンジン「Godot Engine 4」で、マウスでスプライト画像(黄色い光)を移動させ、接触した他のスプライト画像(お化け)を消すミニゲームを作成します。
パート2では、以前に作成した黄色い光のスプライト画像に触れると消えるお化けを実装して、ゲーム画面に配置してテストプレイを行います。
※ GodotEngine のバージョンは 4.1.2 です。 .NET 版ではありません。
※記事で紹介するスクリプト / プログラム / コードは自己責任で使用してください。
※記事の中で「いらすとや」様の画像を使用しています。
前回の記事
前回、パート1では、スプライト画像に当たり判定を設定するために Area2D, CollisionShape2D クラスを基底クラスとしたノードを追加して、当たり判定領域の円を配置してサイズと位置を調整しました。
明かりに触れると消える obake(おばけ)シーンの作成
以下のクラスからノードを作成します。
- Obake ルートノード (Node クラス)
- Area2D ノード (Area2D クラス)
- CollisionShape2D ノード (CollisionShape2D クラス)
- Area2D ノード (Area2D クラス)
作り方の詳細は、「https://compota-soft.work/wp1/wp-admin/post.php?post=24134&action=edit」で同様の構成を作成しているので参考にしてください。
CollisionShape2D の当たり判定領域は、円ではなくカプセル型(CapsuleShape2D)を選択しました。
シーンドックの Obake ルートノードを選択してから右上の + ボタンを押します。
「ノードにスクリプトをアタッチする」ダイアログで、パスを確認して「作成」ボタンを押して、Obake.gd スクリプトを Obake ルートノードに割り当てます。
ここまで設定したら、メニュー「シーン」→「シーンを保存」などで obake.tscn ファイルにシーンを保存しましょう。
シグナルと受信側メソッド(関数)の接続
Obake シーン(ノード)は明かりの画像スプライトに触れると消えます。
それを実現するために他の物が接触したイベントを検知して自身を消す処理を実装します。
先ほど子ノードに追加した Area2D では、CollisionShape2D で設定した当たり判定の領域に、他の Area2D の当たり判定領域が重なると area_entered シグナルを発します。
area_entered シグナルを発した時に呼び出してもらう関数(受信側メソッド)を作成するために、ノードドックを選択して、シグナルタブのリスト内の Area2D の area_entered シグナルをダブルクリックします。
先ほど Obake.gd スクリプトを割り当てた Obake ルートノードに、受信側メソッドの関数を追加して area_entered シグナルと呼び出すように接続します。
「メソッドにシグナルを接続」ダイアログで、関数を追加するスクリプトを持つノード Obake を選択してから「接続」ボタンを押すと、受信側メソッドのテキストボックスに書かれている _on_area_2d_area_entered 関数が Obake.gd スクリプトに追加されます。
ノードタブを見ると area_entered シグナルの下位に、作成した関数 _on_area_2d_area_entered が接続しています。
これで、他の Area2D の当たり判定領域と接触した直後にこの関数が呼び出されます。
エディタ上部の Script ビューを選択して、Obake.gd スクリプトを確認すると以下のように関数(受信側メソッド)が追加されています。
func _on_area_2d_area_entered(area):
pass # Replace with function body.
呼び出したノードを消去する queue_free() を自身で呼び出して、自身のノードを消去する処理を実装します。
func _on_area_2d_area_entered(area):
# 他の Area2D( TouchMarker ) と接触したら消えます。
queue_free() # 自身のノードを消去します。
お化けのサイズの調整
Obake シーンを画面上部の 2D ビューで表示すると思ったよりも大きいので、シーンノードでObake ルートノード(Sprite2D クラス)を選択すると表示される拡大縮小のハンドルを Shift + Alt キーを押しながらドラッグしてサイズ調整します。
Shift + Alt キーで、位置と比率を固定してサイズを変更できます。
game_manager シーンにお化けのシーンをノードとして複数配置
エディター上部を 2D ビューにして、 game_manager タブを選択してシーンドックに game_manager シーンを表示します。
ファイルシステムドックの obake.tscn (obake シーン)ファイルを、シーンドックの GameManager ルートノードに向けてドラッグ&ドロップすることで、obake シーンを子ノードとして複数追加します。
追加した obake 子ノードを 2D ビュー内でドラッグして位置を調整しましょう。
テスト
F6 キーを押して開いている game_manager シーンを再生しましょう。
クリック / ドラッグ時に表示される黄色い明かりの円におばけが触れると消えるミニゲームができました。
まとめ
パート2では、2D / 3D ゲームを作成できる無料・オープンソースの軽快なゲームエンジン「Godot Engine 4」で、以前に作成した黄色い光のスプライト画像に触れると消えるお化けのシーンを実装して、ゲーム画面に配置してテストプレイを行いました。
これで、明かりに触れるとお化けが消えるミニゲームができました。
これをベースに、お化けが次々に出てきたり、フワフワと移動するなどの独自のアレンジを加えていっても良いでしょう。
スクリプト
以下は GameManager と Obake ノードに割り当てたスクリプトの全文です。
スクリプトの内容についてはコメント文を参照してください。
※冒頭に書いてあるように自己責任でご利用ください。
extends Node
# 波紋を描画するシーンを子ノードとして生成する際に用います。
var sceneRipple
# 子ノードの TouchMarker の参照
var touchMarker
# Called when the node enters the scene tree for the first time.
func _ready():
# 子ノードの TouchMarker を変数に設定します。
touchMarker = $TouchMarker
# TouchMarker はクリックされるまでは非表示にしておきます。
touchMarker.visible = false
return
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
# ドラッグ中またはスワイプ中ならば true です。 _input イベントで扱います。
var dragging = false
# 入力イベントが発生するたびに呼び出されるイベント関数です。
func _input(event):
# 入力の例 — Godot Engine (4.x)の日本語のドキュメント - https://docs.godotengine.org/ja/4.x/tutorials/inputs/input_examples.html#mouse-motion
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
# Start dragging if the click is on the sprite.
if not dragging and event.pressed:
dragging = true
# 左ボタンを押した瞬間の処理
# タッチマーカーを表示状態に変更します。クリックした座標に位置を変更します。
touchMarker.position = event.position
touchMarker.visible = true
# Stop dragging if the button is released.
if dragging and not event.pressed:
dragging = false
# ボタンを離した瞬間の処理
# タッチマーカーを非表示に変更します。
touchMarker.visible = false
# While dragging, move the sprite with the mouse.
if event is InputEventMouseMotion and dragging:
# ドラッグ中の処理
# タッチマーカーの位置をドラッグしている位置に更新します。
touchMarker.position = event.position
return
extends Sprite2D
# Called when the node enters the scene tree for the first time.
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
pass
func _on_area_2d_area_entered(area):
# 他の Area2D( TouchMarker ) と接触したら消えます。
queue_free() # 自身のノードを消去します。
参照サイト Thank You!
- Godot Engine – Free and open source 2D and 3D game engine
- Custom drawing in 2D — Godot Engine (stable) documentation in English
- Sprite2D — Godot Engine (4.x)の日本語のドキュメント
- 入力の例 — Godot Engine (4.x)の日本語のドキュメント
- Node — Godot Engine (4.x)の日本語のドキュメント
- Area2Dの使用 — Godot Engine (4.x)の日本語のドキュメント
- CollisionShape2D — Godot Engine (4.x)の日本語のドキュメント
- かわいいフリー素材集 いらすとや
- ハロウィンのキャラクター(おばけ) | かわいいフリー素材集 いらすとや
記事一覧 → Compota-Soft-Press
コメント