Godot Engine での2Dゲーム作成チュートリアルの Part.3 (最終回)です。
前回はこちらのページです。
【Godot】2Dクリックゲームチュートリアル (2/3)目次
クリックして破壊できるようにする
クリックしてGodotくんを破壊できるようにします。
“Enemy”タブをクリックする、またはファイルシステムから「Enemy.tscn」をダブルクリックして、”Enemy”シーンを開きます。
開いたら、インスペクタのとなりにある「ノード」をクリックします。
するとシグナルの一覧が表示されます。
シグナルとは、「別のオブジェクトと衝突した」「マウスでクリックされた」など、オブジェクトに対する影響を判定できる信号のことです。
色々とシグナルは用意されていますが、ここでは CollisionObject2D > input_event()
を選んで、ダブルクリックします。
そのまま「接続」をクリック。
するとシグナルを受け取る関数が追加されます。
ちなみに関数の左側に表示されている緑色のアイコンは「シグナルで接続されている」ことを示すものとなります。
この関数を以下のように修正します。
func _on_Enemy_input_event(viewport, event, shape_idx):
# 何らかの入力イベントが発生
if event is InputEventMouseButton:
# マウスボタンの入力イベント
if event.is_pressed():
# クリックしたので、インスタンスを破棄
queue_free()
input_event()
は様々なイベントを受け取るので、まずはイベントがマウスボタンのイベントであるかどうかを判定します。
そしてそれがマウスクリックであれば queue_free()
でインスタンスを破棄します。
実行して、マウスクリックでGodotくんが消えることを確認します。
クリア判定
ゲームクリア判定を作ります。
“Main”タブを選ぶ、または ファイルシステムから “Main.tscn” をダブルクリックして、Mainシーンを開きます。
次にMainノードを選択して右クリックし、「スクリプトをアタッチ」を選択します。
そのまま「作成」をクリックします。
“Main.gd” スクリプトを以下のように修正します。
extends Node2D
func _process(delta):
var all_destroyed = true
# 子ノードをすべて調べる
for node in get_children():
if "Enemy" in node.name:
# 敵が生存している
all_destroyed = false
if all_destroyed:
# ゲームクリア
OS.alert("ゲームクリア")
# アプリケーションを終了する
get_tree().quit()
子ノードをすべて調べて、ノード名に “Enemy” が含まれるオブジェクトが存在しなければゲームクリア、としています。
実行して、すべてクリックするとゲームクリアとなることを確認します。
パーティクルを実装する
最後にGodotくんが消滅するときのパーティクルを実装します。
タブの右隣にある「+」をクリックして、シーンを追加します。
「+ その他のノード」をクリックします。
検索欄に「Particle」と入力して CPUParticles2D
を選んで、作成ボタンをクリックします。
作成された CPUParticles2D
のノード名を 「Particle」に変更します。
いったん、Ctrl+S (Cmd+S)
でシーンを「Particle.tscn」として保存します。
パーティクルの設定
Particleノードを選択して、ノードタブから「インスペクタ」に戻します。
インスペクタから、Drawing > Texture > [空]
をクリックして、「読み込み」を選択します。
パーティクルに使用する画像選択画面が表示されるので、”icon.png” を選びます。
すると、Godotくんが生成され続けるパーティクルとなります。
発生時の初期速度を設定します。Initial Velocity > Velocity
の値を「150」に変更します。
すると右方向に向けて放出されるようになります。
発生方向を全方向に変更します。Direction > Spread
の値を「180」にすると±180度となるので、全方向に放出されるようになります。
サイズが大きすぎるので、Scale > Scale Amount
を 0.5 にして小さくします。
また時間経過に合わせてサイズを小さくしたいので、Scale Amount Curve > [空]
をクリックして、「新規カーブ」を選びます。
作成されたCurveをクリックして、カーブグラフを表示し、右クリックしてポイントを追加し、右下がりのカーブを作成します。
すると時間経過で小さくなるパーティクルとなります。
クリックでの破壊時にまとめて放出したいので、Time > Explosiveness
を「1」にします。
この指定をすると、まとめて放出されます。
このパーティクルは一度再生したら終了するタイプなので「One Shot」に変更します。Time > One Shot
にチェックを入れると一度きりの再生となります。
再び動作を確認したい場合は、One Shot
の指定は外して、Emitting
にチェックを入れます。One Shot
にチェックを入れたままにすると、Emitting
をクリックするたびに再生されます。
もしOne Shot
のチェックを外した場合は、チェックを入れるようにしておいてください。
Particleノードを右クリックして、スクリプトのアタッチを選びます。
「作成」を選択します。
スクリプトには以下のように記述します。
extends CPUParticles2D
func start(pos):
# 放出開始
emitting = true
# 位置を設定
position = pos
func _process(delta):
if emitting == false:
# 再生終了
queue_free()
start()
で座標を指定して放出を開始します。
また emitting
で終了判定をします。
Enemyシーンを選択して、Enemy.gd スクリプトを以下のように修正します。
extends Area2D
# パーティクルオブジェクト
var Particle = preload("res://Particle.tscn")
# 画面サイズ
var screen:Rect2
# 移動速度
var velocity:Vector2
……
var Particle = preload("res://Particle.tscn")
という記述が追加されています。これは Particleシーンを Enemy.gd で使用するための記述となります。
そして後半の _on_Enemy_input_event()
を修正します。
func _on_Enemy_input_event(viewport, event, shape_idx):
if event is InputEventMouseButton:
# マウスボタンの入力イベント
if event.is_pressed():
# クリックしたので、インスタンスを破棄
queue_free()
# パーティクルを生成
var p = Particle.instance()
# パーティクル再生開始
p.start(position)
# ルートノードに設定する
var root_node = get_parent()
root_node.add_child(p)
Godotくん破壊時にパーティクルを生成する記述となります。
現在のノード構成では “Enemy” の上に Mainノードがあることが決まっているので、get_parent()
で親ノードを取得して、add_child()
でぶら下げています。
では、実行してGodotくんの破壊パーティクルが再生されることを確認します。
パーティクルの挙動が今ひとつな感じなので、気になる方はより詳しい使い方を以下のページにまとめていますので参考になるかもしれません。
【Godot】2Dパーティクルの使い方最後に
ここまでできたら、あとは色々なチュートリアルを試してみるのが良いと思います。
公式のチュートリアルでは、スプライトアニメーションやボタンの作成方法など、色々な機能が使われているので勉強になると思います。
あと、個人的にシューティングを作るときに悩んだことは以下のページにまとめましたので、ひょっとしたら参考になるかも……。
- 【Godot】2Dシューティングゲームを作るときのポイントまとめ (Qiita)
ステップアップとして、フラッピーバードを作るチュートリアル記事はこちらに作成しています。