Godotで放置ゲームを作る③:SignalでクリックとGameManagerをつなぐ

初心者向け実践開発

※本記事にはアフィリエイト広告(Udemy)を含みます。

前回のおさらい

前回②では、ヘッダー・資源表示・ECHOエリア・アップグレード一覧・クリックボタンをVBoxContainerで縦に並べ、UIの見た目を組み立てました。ただし、この時点ではボタンを押しても何も起こりません。

今回は、このボタンに実際の動作を接続し、押すと電力が増えるようにします。

Signalとは何か

Signal(シグナル)とは、「何かが起きたこと」を他のスクリプトに知らせる仕組みです。

たとえば「ボタンが押された」という出来事が起きたとき、ボタン自身は「押されたよ」と発信するだけで、それを受け取って何をするかは決めません。受け取る側(今回で言えばMain.gd)が「押されたら電力を増やす」という処理を後から接続します。この仕組みのおかげで、ボタン側のコードを書き換えずに、反応する内容だけを自由に変更できます。

GodotのButtonノードには、あらかじめpressedという名前のSignalが用意されています。今回はこれを使います。

GameManagerに電力を増やす処理を追加する

なぜロジックをUI側ではなくGameManager側に書くのか

電力の値は、STATION OPS全体で共有される情報です。UI側(Main.gd)に直接「電力を増やす処理」を書いてしまうと、将来的に別の画面や別の仕組みから電力を増やしたくなったときに、同じ処理をあちこちに書く必要が出てきます。①で用意したオートロード「GameManager」に処理をまとめておくことで、どこからでも同じ関数を呼び出せるようにします。

add_power()関数を追加する

GameManager.gdに、以下の関数を追加します。

func add_power(amount: float) -> void:
    power += amount
    resources_changed.emit()

amountという引数で「増やす量」を受け取り、power変数に加算しています。

Signal「resources_changed」を宣言する

上のコードで使っているresources_changedは、まだ宣言していないSignalです。スクリプトの先頭付近に、以下の1行を追加します。

signal resources_changed

これで、電力(またはこの後追加する酸素・部品)の値が変わるたびに、「資源が変わったよ」という合図を出せるようになりました。add_power()の最後にあるresources_changed.emit()が、その合図を実際に発信している部分です。

Main.gdからクリックとSignalをつなぐ

_ready()関数とは

_ready()は、そのノードがシーンに登録され、使える状態になった直後に自動的に1回だけ呼ばれる関数です。ボタンやラベルへの参照を取得したり、Signalの接続をしたりといった、最初の準備処理をここに書きます。

クリックボタンのpressedSignalに処理を接続する

Main.gd(VBoxContainerを配置したControlノードにアタッチしたスクリプト)に、以下のように追記します。

@onready var click_button: Button = $Margin/VBoxContainer/ClickButton
@onready var power_label: Label = $Margin/VBoxContainer/ResourceDisplay/PowerLabel

func _ready() -> void:
    click_button.pressed.connect(_on_click_button_pressed)
    GameManager.resources_changed.connect(_on_resources_changed)
    _update_display()

func _on_click_button_pressed() -> void:
    GameManager.add_power(1.0)

func _on_resources_changed() -> void:
    _update_display()

func _update_display() -> void:
    power_label.text = "電力: %d" % int(GameManager.power)

click_button.pressed.connect(_on_click_button_pressed)の行が、ボタンのpressedSignalと_on_click_button_pressedという関数を接続している部分です。ボタンが押されるたびに、この関数が呼ばれます。

resources_changedSignalを購読して表示を更新する

GameManager.resources_changed.connect(_on_resources_changed)の行では、GameManager側から発信される「資源が変わったよ」という合図を受け取り、_update_display()で表示を更新しています。

ここでのポイントは、_on_click_button_pressed()の中では画面の表示を直接書き換えていないことです。処理の流れは次のようになります。

  1. ボタンが押される
  2. GameManager.add_power(1.0)が呼ばれ、powerが増える
  3. GameManager側でresources_changedSignalが発信される
  4. Main.gd側がそのSignalを受け取り、_update_display()でラベルを更新する

一見遠回りに見えますが、こうしておくことで、電力が増える原因(クリック以外にも、後の記事で追加する自動生産などが増えていきます)が何であっても、表示側の更新処理は1箇所にまとめられます。

動作確認

ここまでできたら、ゲームを実行して「発電する」ボタンを押してみてください。押すたびに「電力: 1」「電力: 2」と表示が増えていけば成功です。

次回予告

次回④では、Timer(時間経過の処理)を使って、ボタンを押さなくても自動的に電力が増える「発電パネル」を実装します。あわせて、発電パネルを購入するためのUIも追加します。

Godot学習におすすめのオンライン講座

SignalはGodot特有の考え方なので、最初は戸惑う人も多い部分です。体系的な講座で他の使用例にも触れておくと理解が早まります。

Godotのコースを見る

参考リンク


コメント

タイトルとURLをコピーしました