ヘッドアップディスプレイ¶
このゲームに必要な最後の要素は、スコアや"ゲームオーバー"のメッセージ、リスタートボタンなどを表示するユーザーインターフェイス(UI)です。
新しいシーンを作成し、 HUDという名前のCanvasLayerノードを追加します。「HUD」は、ゲームビューの上にオーバーレイとして表示される情報表示である「ヘッドアップディスプレイ」("Heads-up display")の略です。
CanvasLayerノードを使用すると、ゲームの他の部分よりも上のレイヤにUI要素を描画することができるため、表示される情報がプレイヤーやモブなどのゲーム要素によって隠されることがなくなります。
HUDには、次の情報を表示する必要があります:
ScoreTimerによって変更されるスコア。「Game Over」や「Get Ready! (よーい!)」 などのメッセージ
ゲームを開始する「スタート」ボタン。
UI要素の基本ノードはコントロールです。UIを作成するには、ラベルとボタンの2種類のコントロールノードを使用します。
HUD ノードの子として次を作成します:
ScoreLabel をクリックし、インスペクタのTextフィールドに数字を入力します。 Control ノードのデフォルトのフォントは小さく、うまくスケールしません。そこで、ゲームアセットに含まれる 「Xolonium-Regular.ttf」というフォントファイルがあります。 このフォントを使用するには、次のようにしてください:
Theme overrides > Fontsの下で、空欄をクリックして 「新規 DynamicFont」("New DynamicFont") を選択してください
追加した "DynamicFont" をクリックし、Font > FontDataで 「読み込み」("Load") を選択して "Xolonium-Regular.ttf" を選択して下さい。
Settingsの下の"Size"プロパティを64にセットするとうまくいきます。
ScoreLabelでこれを行ったら、Fontプロパティの横の下矢印をクリックして「コピー」("Copy") を選び、他の二つのControlノードの同じ場所に 「貼り付け」("Paste") することができます。
注釈
**アンカーとマージン**: Controlノードには、位置とサイズがありますが、アンカーとマージンもあります。アンカーは原点 (ノードのエッジの参照点)を定義します。マージンはコントロールノードを移動またはサイズ変更すると自動的に更新されます。マージンはコントロールノードのエッジからアンカーまでの距離を表します。
以下に示すようにノードを配置します。「レイアウト」ボタンをクリックして、コントロールノードのレイアウトを設定します:
ノードをドラッグして手動で配置したり、より正確な配置を行うには、次の設定を使用します:
ScoreLabel¶
Layout : "Top Wide"
Text :
0Align : "Center"
メッセージ¶
Layout : "HCenter Wide"
Text :
Dodge the Creeps!Align : "Center"
Autowrap : "On"
HUDをメインに接続する¶
HUD シーンの作成が完了したら、 Main に戻ります。 Player のシーンと同じように HUD シーンを Main にインスタンス化し、ツリーの一番下に配置します。ツリー全体は次のようになるはずです。何も見落としていないか確認してください:
次に、 HUD 機能を Main のスクリプトに接続します。これには、 Main シーンにいくつかの追加が必要です:
ノードタブで、「シグナルを接続」ウィンドウの 「受信側メソッド」に "new_game" と入力して、HUDの start_game のシグナルをメインノードの new_game() 関数に接続します。スクリプトの func new_game() の横に緑色の接続アイコンが表示されていることを確認してください。
new_game() で、スコア表示を更新し、「Get Ready」メッセージを表示します:
$HUD.update_score(score)
$HUD.show_message("Get Ready")
var hud = GetNode<HUD>("HUD");
hud.UpdateScore(Score);
hud.ShowMessage("Get Ready!");
_hud->update_score(score);
_hud->show_get_ready();
game_over() では、対応する HUD 関数を呼び出す必要があります:
$HUD.show_game_over()
GetNode<HUD>("HUD").ShowGameOver();
_hud->show_game_over();
最後に、これを _on_ScoreTimer_timeout() に追加して、変更されたスコアと同期して表示を維持します:
$HUD.update_score(score)
GetNode<HUD>("HUD").UpdateScore(Score);
_hud->update_score(score);
これでプレイの準備が整いました! [プロジェクトを実行] ボタンをクリックします。メインシーンを選択するように求められますので、 Main.tscn を選択します。
古い「クリープ」を削除する¶
「ゲームオーバー」までプレイしてから新しいゲームを開始すると、前のゲームの「クリープ」が画面に表示されたままになっています。 それらすべて、新しいゲームの開始時には消したほうがいいでしょう。それには、すべてのモブたちに自身の削除を指示する方法が必要です。これは「グループ」機能を使えば可能です。
Mob シーンでルートノードを選択し、インスペクタの隣にある「ノード」タブをクリックしてください (ノードのシグナルを見つけるのと同じ場所です)。「シグナル」の横にある「グループ」をクリックして、新しいグループ名を入力して「追加」をクリックします。
これですべてのモブが 「mobs」グループに入るようになります。あとは、 Main内の game_over()関数に次の行を追加します。
get_tree().call_group("mobs", "queue_free")
// Note that for calling Godot-provided methods with strings,
// we have to use the original Godot snake_case name.
GetTree().CallGroup("mobs", "queue_free");
get_tree()->call_group("mobs", "queue_free");
call_group() 関数はグループ内の全てのノードに対して名前付きの関数を呼び出します - この場合は全てのモブに自分自身を削除するように指示しています。
この時点で、ゲームはほぼ完成しています。次と最後のパートでは、背景、ループする音楽、キーボードショートカットを追加して、もう少し磨きをかけます。