宣言と発信
CoddyのGDScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 36/65。
キーワード signal と名前を使ってシグナルを宣言します。クラスの先頭で、変数の隣に記述します。シグナル名は、すでに起きたイベントを snake_case で表します: died、door_opened、leveled_up。クラスでは必要な数だけシグナルを宣言できます:
# player.gd
class_name Player
extends RefCounted
signal leveled_up
signal max_level_reached
const MAX_LEVEL := 3
var level := 1
var xp := 0
func add_xp(amount: int) -> void:
xp += amount
while xp >= 100 and level < MAX_LEVEL:
xp -= 100
level += 1
leveled_up.emit()
if level == MAX_LEVEL:
max_level_reached.emit()イベントが発生した瞬間に、そのときだけシグナルを発信します。新しいプレイヤーに対するadd_xp(50)では何も発信されません。その後、xpが300になるadd_xp(250)では、レベルが上がるたびに1回ずつ、leveled_upが2回発信され、レベル3に到達するレベルアップ時にmax_level_reachedが1回発信されます。
プロパティのセッターはシグナルを発行するのに適した場所です。値を変更するコードが実行されるたびにシグナルが発火するためです:
signal died
var hp: int = 10:
set(value):
var was_alive := hp > 0
hp = maxi(value, 0)
if was_alive and hp == 0:
died.emit()was_aliveは、HPが0のヒーローが再び攻撃を受けたときに、diedが再度発生するのを防ぎます。
シグナルは、テキストとして名前を指定しても使用できます。emit_signal("died")でシグナルを発行し、hero.connect("died", _on_hero_died)で接続し、hero.has_signal("died")でtrueを返します。オブジェクトが宣言していない名前に接続すると、その行の実行時にエラーになります。
チャレンジ
簡単カウントダウンし、各ステップをシグナルで知らせるBombを作成してください。
- 2つのシグナル、
beepedとexplodedを宣言します。 tick()はfuseを1減らします。導火線がまだ0より大きければbeepedを発行し、0に達していればexplodedを発行します。- 導火線が
0になると、爆弾は爆発済みです。それ以降のティックでは何もせず、何も発行しません。
用意されたコードは開始時の導火線の長さと実行するティック数を読み取り、名前で両方のシグナルに接続し、接続された関数からBeepとBOOM!を出力してから、残りの導火線の長さを出力します。導火線の長さが3で、ティック数が5の場合、次のように出力されます。
Beep
Beep
BOOM!
Fuse: 0コードはbomb.gdに記述します。main.gdには用意された入出力コードが含まれており、編集できません。
自分で試してみよう
extends Node
func _ready():
# 用意された入出力コード: そのままにしてください
var bomb := Bomb.new(int(OS.read_string_from_stdin()))
# シグナル名をテキストとして指定してconnect()を呼び出す
bomb.connect("beeped", _on_beeped)
bomb.connect("exploded", _on_exploded)
var ticks := int(OS.read_string_from_stdin())
for i in ticks:
bomb.tick()
print("Fuse: ", bomb.fuse)
func _on_beeped() -> void:
print("Beep")
func _on_exploded() -> void:
print("BOOM!")
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: GDScriptオンラインコンパイラ