2020/10/27(火) [n年前の日記]
#1 [godot] Godot Engineで林檎と爆弾をたくさん生成
Godot Enigne 3.2.3 x64 の勉強を兼ねて、Apple Catcher っぽいゲームを作成中。
今回は、 _前回作成した林檎と爆弾 をゲームウインドウ上に大量発生させるシーンを作ってみる。
今回は、 _前回作成した林檎と爆弾 をゲームウインドウ上に大量発生させるシーンを作ってみる。
◎ シーンとノード構成を作成。 :
以下のようなノード構成でシーンを作成。
各ノードの名前を分かりやすく変更しておく。
Timer は、指定時間毎に「時間だよ」とシグナル(Signal、信号)を出してくれるノード。Signal と何かのメソッドを接続しておくことで、指定時間毎に何かの処理をする、ということができるようになる。
Node2D │ ├─ Node2D │ ├─ Timer │ └─ Timer
各ノードの名前を分かりやすく変更しておく。
ItemGenerator (Node2D) │ ├─ Items (Node2D) │ ├─ ItemTimer (Timer) │ └─ RateTimer (Timer)
- Items : 発生させた林檎や爆弾を追加していくノード。
- ItemTimer : 林檎や爆弾の発生間隔を担当するノード。
- RateTimer : 爆弾が混じる確率を変化させるノード。
Timer は、指定時間毎に「時間だよ」とシグナル(Signal、信号)を出してくれるノード。Signal と何かのメソッドを接続しておくことで、指定時間毎に何かの処理をする、ということができるようになる。
◎ Timerのプロパティを変更。 :
ItemTimer の時間設定を変更。Wait Time を 0.2秒に。Autostart も有効に。
RateTimer の時間設定を変更。Wait Time を 1秒に。Autostart も有効に。
RateTimer の時間設定を変更。Wait Time を 1秒に。Autostart も有効に。
◎ スクリプトをアタッチ。 :
ItemGenerator にスクリプトをアタッチする。
スクリプト、ItemGenerator.gd を記述。
内容は以下。
_ItemGenerator.gd
今回は、林檎のシーン Apple.tscn と 爆弾のシーン Bomb.tscn をドラッグアンドドロップで設定しておく。
変数 Apple と、変数 Bomb に、Apple.tscn、Bomb.tscn が登録(?)された。これでスクリプト内から Apple と Bomb を使える状態になった。
スクリプト、ItemGenerator.gd を記述。
内容は以下。
_ItemGenerator.gd
extends Node2D export (PackedScene) var Apple export (PackedScene) var Bomb export var w = 96 var rnd = RandomNumberGenerator.new() var screen_size var born_rate = 100 var born_enable = false func _ready(): rnd.randomize() screen_size = get_viewport_rect().size born_rate = 100 born_enable = false start() # Delete in production environment func start(): born_enable = true born_rate = 100 func stop(): born_enable = false func generate_item(): if born_enable: var x0 = w / 2 var x1 = screen_size.x - (w / 2) var x = rnd.randi_range(x0, x1) var item if rnd.randi_range(0, 100) > max(20, born_rate): item = Bomb.instance() else: item = Apple.instance() item.position.x = x item.position.y = -w $Items.add_child(item) func update_rate(): if born_enable: born_rate -= 3 if born_rate <= 1: born_rate = 100
- export (PackedScene) var Apple : 林檎キャラのシーンを記憶する変数。
- export (PackedScene) var Bomb : 爆弾キャラのシーンを記憶する変数。
- _ready(): 初期化処理。
- start() : 発生処理開始。実行フラグを立てる。
- stop() : 発生処理停止。実行フラグを下す。
- generate_item() : 林檎か爆弾を発生させる処理。ランダムなx座標位置で、Items に登録していく。
- update_rate(): 爆弾が混ざってくる確率を変化させる。
- vat item = Apple.instance() で、Apple のインスタンスが得られる。
- add_child(item) で、item を自分の子ノードとして追加できる。
- $Items.add_child(item) なら、自分の子ノードの Items に、item を子ノードとして追加する。
- export var xxxx と書いておけば、GUIで変数の値を設定できるようになる。
- export (PackedScene) var xxxx なら、シーンを記憶できる変数になる。
今回は、林檎のシーン Apple.tscn と 爆弾のシーン Bomb.tscn をドラッグアンドドロップで設定しておく。
変数 Apple と、変数 Bomb に、Apple.tscn、Bomb.tscn が登録(?)された。これでスクリプト内から Apple と Bomb を使える状態になった。
◎ シグナルとメソッドを接続。 :
Godot Engine の各ノードは、何かの条件を満たした時に「xxxになったよ」的お知らせとして「シグナル(Signal、信号)」を発行する。例えば、Timerノードは設定された時間が経過すると timeout() シグナルを発行する。timeout() シグナルと何かのメソッドを接続しておけば、設定時間毎に何かの処理が実行される状態を作れる。
今回は、以下のシグナルとメソッドを接続する。
ItemTimer を設定。ItemTimer を選んでから、ノードタブに切り替えて、timeout() を選んで「接続」。
「メソッドにシグナルを接続」ウインドウが表示される。
ItemGenerator を選んで、受信側メソッドに「generate_item」を入力して「接続」。「()」は打ち込まなくていい。
メソッドとシグナルが接続されると、スクリプトのエディタ画面で、メソッド名の左側に「シグナルが接続されてるよ」と示す緑のアイコンが表示される。
RateTimer を設定。RateTimer を選んでから、ノードタブに切り替えて、timeout() を選んで「接続」。
ItemGenerator を選んで、受信側メソッドに「update_rate」を入力して「接続」。
スクリプトのエディタ画面で、update_rate() の左側にも「シグナルが接続されてるよ」アイコンが表示された。
ItemGeneratorノードを選択してからF6キーを押して実行してみる。次々に林檎や爆弾が発生してくれた。
しばらく動かし続けると爆弾の出現頻度が高くなって、ある時間を超えるとまた林檎だけ出てくる状態になる。それらしく動いてくれた。
今回は、以下のシグナルとメソッドを接続する。
- ItemTimer の timeout() → ItemGenerator.gd 内の generate_item()。林檎か爆弾の発生処理メソッド。
- RateTimer の timeout() → ItemGenerator.gd 内の update_rate()。爆弾が発生する確率を変化させるメソッド。
ItemTimer を設定。ItemTimer を選んでから、ノードタブに切り替えて、timeout() を選んで「接続」。
「メソッドにシグナルを接続」ウインドウが表示される。
ItemGenerator を選んで、受信側メソッドに「generate_item」を入力して「接続」。「()」は打ち込まなくていい。
メソッドとシグナルが接続されると、スクリプトのエディタ画面で、メソッド名の左側に「シグナルが接続されてるよ」と示す緑のアイコンが表示される。
RateTimer を設定。RateTimer を選んでから、ノードタブに切り替えて、timeout() を選んで「接続」。
ItemGenerator を選んで、受信側メソッドに「update_rate」を入力して「接続」。
スクリプトのエディタ画面で、update_rate() の左側にも「シグナルが接続されてるよ」アイコンが表示された。
ItemGeneratorノードを選択してからF6キーを押して実行してみる。次々に林檎や爆弾が発生してくれた。
しばらく動かし続けると爆弾の出現頻度が高くなって、ある時間を超えるとまた林檎だけ出てくる状態になる。それらしく動いてくれた。
◎ アタリ判定のMask設定を変更。 :
今の状態では林檎と爆弾の発生間隔が長いので見た感じそれほどおかしくはないけれど…。例えば、ItemTimer の Wait Time を小さくすると林檎と爆弾の発生数が増えて、ところどころの林檎や爆弾が回転してる感じになる。これは林檎や爆弾同士がぶつかり合ってその際に回転してしまうから。
林檎や爆弾はプレイヤーキャラとぶつかればいいのであって、林檎や爆弾同士でぶつかる必要は無い。そこで、林檎キャラや爆弾キャラの Collision 設定を変更して、林檎や爆弾同士では衝突判定をしない・アタリを取らないようにする。
Apple.tscn を開いて、Collision → Mask を全てオフにする。デフォルトでは一番左だけチェックが入っているはず。
Bomb.tscn も開いて、Collision → Mask を全てオフにする。
これで、林檎や爆弾同士では衝突判定をしない状態になった。
プレイヤーキャラと林檎・爆弾の大量発生まで作れたので、次回はゲームのメインシーンを作ってそれぞれ合体させてみたい。
林檎や爆弾はプレイヤーキャラとぶつかればいいのであって、林檎や爆弾同士でぶつかる必要は無い。そこで、林檎キャラや爆弾キャラの Collision 設定を変更して、林檎や爆弾同士では衝突判定をしない・アタリを取らないようにする。
Apple.tscn を開いて、Collision → Mask を全てオフにする。デフォルトでは一番左だけチェックが入っているはず。
Bomb.tscn も開いて、Collision → Mask を全てオフにする。
これで、林檎や爆弾同士では衝突判定をしない状態になった。
プレイヤーキャラと林檎・爆弾の大量発生まで作れたので、次回はゲームのメインシーンを作ってそれぞれ合体させてみたい。
[ ツッコむ ]
以上です。