2020/10/28(水) [n年前の日記]
#1 [godot] Godot Engineでゲームのメインシーンを作成
Godot Enigne 3.2.3 x64 の勉強を兼ねて、Apple Catcher っぽいゲームを作成中。
前回までの作業でプレイヤーシーンと林檎・爆弾の発生シーンを作れたので、今回は、ゲームのメインシーンを作成してみる。
前回までの作業でプレイヤーシーンと林檎・爆弾の発生シーンを作れたので、今回は、ゲームのメインシーンを作成してみる。
◎ ルートノードを作成。 :
新規シーンを作って、ルートノードを作成する。
Godot Engine で2Dゲームを作る場合、「メインシーンのルートノードには Node を使え」という話をどこかで見かけた記憶があるのでソレに従う。
「その他のノード」を選択。
「Node」を選んで「作成」。
ルートノードとして Node が追加された。
分かりやすくするために、ノード名を「Main」に変更。
Godot Engine で2Dゲームを作る場合、「メインシーンのルートノードには Node を使え」という話をどこかで見かけた記憶があるのでソレに従う。
「その他のノード」を選択。
「Node」を選んで「作成」。
ルートノードとして Node が追加された。
分かりやすくするために、ノード名を「Main」に変更。
◎ 子ノードを追加。 :
子ノードとして、プレイヤーキャラのシーンと、林檎や爆弾の発生シーンを追加する。
「シーンファイルをノードとしてインスタンスにします」ボタンをクリック。プラスマークの右にあるボタン。
子にするシーンを選ぶ。プレイヤーキャラのシーン、assets/Player.tscn を選択して「開く」。
同様に、林檎や爆弾の発生シーン、assets/ItemGenerator.tscn も選択して「開く」。
Mainノードの下に、Player と ItemGenerator がぶら下がっている構成にした。
「シーンファイルをノードとしてインスタンスにします」ボタンをクリック。プラスマークの右にあるボタン。
子にするシーンを選ぶ。プレイヤーキャラのシーン、assets/Player.tscn を選択して「開く」。
同様に、林檎や爆弾の発生シーン、assets/ItemGenerator.tscn も選択して「開く」。
Mainノードの下に、Player と ItemGenerator がぶら下がっている構成にした。
◎ シーンを保存。 :
◎ 実行してみる。 :
◎ 衝突判定処理を書く。 :
前述の画面は一見するとゲームっぽい画面だけど、プレイヤー、林檎、爆弾は衝突判定の類をまだ何もしていないので、これでは全然ゲームになってない。そのあたりの処理を追加していく。
プレイヤーキャラは、アタリ範囲を持てるArea2Dノードを使っているけれど。Area2Dノードは、自分のアタリ範囲にRigidBody2D が入ってきた時に、「何かが自分に当たったよ」と教えてくれる、body_entered(body) シグナルを発行することができる。
つまり、Playerノードが持ってるシグナル、body_entered にメソッドを接続してやれば、「プレイヤーに林檎か爆弾が当たった時にメソッドを呼んで何か処理をする」という状態を作れる。
Playerノードを選択して、ノードタブを選択。body_entered(body:Node) を選んで、「接続」。
「メソッドにシグナルを接続」ウインドウが開くので、「Player」を選択して「接続」。受信側メソッド名はそのままでいい。
プレイヤーキャラのスクリプト、Player.gd の最後に、メソッド _on_Player_body_entered(body) が追加された。
このメソッドの中に、林檎や爆弾と当たった時の処理を書けばいい。
スクリプトを書く。
追加する内容は以下。
_Player.gd
body には、林檎か爆弾のどちらかのインスタンスが入ってくるので、それが林檎なのか爆弾なのかを判別しないといけないけれど…。
以前、林檎や爆弾のスクリプトを書いた際に、以下を記述してあるので…。
print("hoge") で、Godot Engine エディタ画面の出力ウインドウにメッセージを出力することができる。
また、林檎と衝突した場合、その林檎はもう不要なので、body.queue_free() を呼んで林檎を消去してやる。
衝突判定処理を書けたので、F6キーを押して実行してみる。
プレイヤーが林檎か爆弾と衝突するたびに、出力ウインドウにどちらに当たったかが出力された。ちゃんと衝突判定が動いている。後はこのメソッドの中で、林檎を取った時の処理や、爆弾に当たった時の処理を書いていけばいい。
プレイヤーキャラは、アタリ範囲を持てるArea2Dノードを使っているけれど。Area2Dノードは、自分のアタリ範囲にRigidBody2D が入ってきた時に、「何かが自分に当たったよ」と教えてくれる、body_entered(body) シグナルを発行することができる。
つまり、Playerノードが持ってるシグナル、body_entered にメソッドを接続してやれば、「プレイヤーに林檎か爆弾が当たった時にメソッドを呼んで何か処理をする」という状態を作れる。
Playerノードを選択して、ノードタブを選択。body_entered(body:Node) を選んで、「接続」。
「メソッドにシグナルを接続」ウインドウが開くので、「Player」を選択して「接続」。受信側メソッド名はそのままでいい。
プレイヤーキャラのスクリプト、Player.gd の最後に、メソッド _on_Player_body_entered(body) が追加された。
このメソッドの中に、林檎や爆弾と当たった時の処理を書けばいい。
スクリプトを書く。
追加する内容は以下。
_Player.gd
func _on_Player_body_entered(body): if body.kind == "Apple": print("Apple") body.queue_free() # kill Apple else: print("bomb")
body には、林檎か爆弾のどちらかのインスタンスが入ってくるので、それが林檎なのか爆弾なのかを判別しないといけないけれど…。
以前、林檎や爆弾のスクリプトを書いた際に、以下を記述してあるので…。
export var kind = "Apple"
export var kind = "bomb"body.kind に "Apple" が入ってるのか、それとも "bomb" が入ってるのかを調べれば、林檎か爆弾なのかを判別できる。 *1
print("hoge") で、Godot Engine エディタ画面の出力ウインドウにメッセージを出力することができる。
また、林檎と衝突した場合、その林檎はもう不要なので、body.queue_free() を呼んで林檎を消去してやる。
衝突判定処理を書けたので、F6キーを押して実行してみる。
プレイヤーが林檎か爆弾と衝突するたびに、出力ウインドウにどちらに当たったかが出力された。ちゃんと衝突判定が動いている。後はこのメソッドの中で、林檎を取った時の処理や、爆弾に当たった時の処理を書いていけばいい。
◎ メインシーンとして設定。 :
今回作った Main.tscn を、このプロジェクトのメインシーンとして設定しておく。ファイル一覧ウインドウ内で、Main.tscn を右クリック。「メインシーンとして設定」を選ぶ。
これで、Godot Enigne を起動してプロジェクトを開いたときに、Main.tscn が開かれた状態になる。
さて、林檎や爆弾と当たる状態にはなったけど、当たった時に何かアクションが欲しい。例えば林檎をキャッチした時はスコアが増えてほしい…。次回はスコア表示等を担当するシーンを作りたい。
これで、Godot Enigne を起動してプロジェクトを開いたときに、Main.tscn が開かれた状態になる。
さて、林檎や爆弾と当たる状態にはなったけど、当たった時に何かアクションが欲しい。例えば林檎をキャッチした時はスコアが増えてほしい…。次回はスコア表示等を担当するシーンを作りたい。
*1: もしかすると、林檎と爆弾に異なる「グループ名」を指定して、グループ名で判別してしまってもいいのかもしれない。
[ ツッコむ ]
以上です。