昔から人気の駄菓子「ビッグカツ」のフリー素材画像が公開されたので、無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 を使って、ビッグカツ画像を使ったブロック崩しを作成します。
「ビッグカツブロック崩し」作成の第20回では、独自のシグナル(カスタムシグナル)を使って、ブロック崩しのボールが画面外に出てゲームオーバーになったことを、ボールシーンの外部にあるステージのシーンのノードの関数(受信側メソッド)に伝える実装例を紹介します。
![](https://compota-soft.work/wp1/wp-content/uploads/2024/09/GodotEngine4.3-公式サイトの一部-20240911.png)
※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※スクリプトは自己責任でご使用ください。
前回の記事
前回は、画面外にボールが出た際に発せられる VisibleOnScreenNotifier2D ノードの screen_exited() シグナルを ball.gd スクリプトの関数に接続して、ボールが画面外に出た際にその関数が呼び出されることを確認しました。
カスタムシグナルの定義
以前に作成したボールの動きを制御する ball.gd スクリプトに
- カスタムシグナル ball_screen_exited() の定義
- 画面外に出た際に呼び出される関数内で、そのカスタムシグナルを発する処理
を追加したものを上書きします。
また、ゲームオーバー時やクリア時にボールを一時停止するためのフラグとそれを用いた判定も追加しました。
init_speed_and_angle 関数は、毎レベルごとにボールの初期の角度と速度を設定する関数で stage.gd でプレイ開始時にも呼び出されます。
extends CharacterBody2D
class_name Ball
## ブロック崩しの球の動きを制御するスクリプトです。
## ボールの移動速度です。
@export var BALL_SPEED: float = 400.0
## ボールの初期角度です。
@export var INITIAL_ANGLE: float = PI / 4 # 45度
## 壁・パドルにぶつかった際の効果音を読み込んで保持します。
@onready var audio_stream_hit: AudioStream = preload("res://sound/Hit.wav")
## ブロックにぶつかりブロックを壊した際の効果音を読み込んで保持します。
@onready var audio_stream_break: AudioStream = preload("res://sound/Break.wav")
## 球を一時停止している場合は true, 他は false を設定します。
## getter, setter @sa https://www.reddit.com/r/godot/comments/164z4at/setters_and_getters/
var is_pause: bool = true:
get:
return is_pause
set(value):
is_pause = value
func _ready():
init_speed_and_angle()
func _physics_process(delta):
# 一時停止している場合は、動かしません。
if is_pause:
return
# 設定されている加速度で移動します。
var collision: KinematicCollision2D = move_and_collide(velocity * delta)
# 何かに衝突した場合
if collision:
# 衝突した Object を取得します。
var collider:Object = collision.get_collider()
# Paddle の場合
if collider.name == "Paddle":
#print("Paddle")
var paddle:Paddle = collider
velocity = paddle.get_bounce(velocity, collision.get_position())
#velocity = velocity.bounce(collision.get_normal()) # 進行方向を変更
SCUtil.AudioStreamOneShotPlay(self, audio_stream_hit) # hit.wav 効果音を再生
# Wall の場合
elif collider.name.begins_with("Wall"):
#print("Wall")
velocity = velocity.bounce(collision.get_normal()) # 進行方向を変更
SCUtil.AudioStreamOneShotPlay(self, audio_stream_hit) # hit.wav 効果音を再生
# Block の場合
elif collider.name.begins_with("Block"):
#print("Block")
velocity = velocity.bounce(collision.get_normal()) # 進行方向を変更
collider.queue_free() # 衝突したブロックを消去します。
SCUtil.AudioStreamOneShotPlay(self, audio_stream_break) # break.wav 効果音を再生
else:
printerr("Ball が不明なものと衝突しました。") # 不明なものとの接触はエラーメッセージを表示します。
return
## 角度と速度を初期化します。
func init_speed_and_angle() -> void:
# 初期角度でボールを発射します。
var direction = Vector2(cos(INITIAL_ANGLE), sin(INITIAL_ANGLE))
# 速度に角度を掛け合わせて、最初の移動ベクトルを設定します。
velocity = direction * BALL_SPEED
return
## 一時停止させる場合は true を、解除する場合は false を指定します。
func set_pause(_is_pause: bool) -> void:
is_pause = _is_pause
## 一時停止している場合は true, 他は false を返します。
func get_pause() -> bool:
return is_pause
## $VisibleOnScreenNotifer2D ノードの screen_exited シグナルの受信メソッドです。
## ボールがゲーム画面の外に出た際に発するカスタムシグナルです。
## ボールが配置される stage シーンの Stage ルートノードに設定した受信側メソッドと
## 接続します。
## 他のノードの関数とも。同様にノードドックの Ball ルートノードのシグナル一覧から接続できます。
## 引数も指定できます。
signal ball_screen_exited()
## ボールが画面外に出た際に呼び出されます。
func _on_visible_on_screen_notifier_2d_screen_exited():
# ボールが画面外に出たことを検知したことのテスト用のメッセージ出力です。
#print("Game Over")
# シグナルを発します。ノードドックで接続したノードの関数が呼び出されます。
ball_screen_exited.emit()
return
以前作成したボールを制御する ball.gd スクリプトについては以下の記事を参照してください。
指定した AudioStream の音を1回だけ再生する自作関数 AudioStreamOneShotPlay については以下の記事を参照してください。
カスタムシグナルを受信する関数の作成と接続
カスタムシグナルを定義して、ボールが画面外に出たタイミングで、そのカスタムシグナルを発する処理を ball.gd に追加しました。
次に、そのカスタムシグナルから呼び出される関数(受信側メソッド)を作成します。
Stage タブを選択して、ステージのシーンを開いたら、シーンドックの Ball 子ノードを選択します。
ノードドックで Ball 子ノードの持つシグナルを確認すると Ball クラスのセクションに先ほど ball.gd スクリプトに定義した ball_screen_exited() カスタムシグナルが追加されています。
![Godot4 ビッグカツブロック崩し Ball のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知1](https://compota-soft.work/wp1/wp-content/uploads/2024/12/Godot4-ビッグカツブロック崩し-Ball-のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知1-1024x553.png)
ノードドックのカスタムシグナル ball_screen_exited() をダブルクリックして、「メソッドにシグナルを接続」ダイアログを開きます。
そのダイアログで、すでに stage.gd スクリプトを割り当てている Stage ルートノードを選択して「接続」ボタンを押します。
![Godot4 ビッグカツブロック崩し Ball のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知2](https://compota-soft.work/wp1/wp-content/uploads/2024/12/Godot4-ビッグカツブロック崩し-Ball-のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知2-1024x553.png)
そのダイアログ下側の「受信側メソッド」のテキストボックスに書かれている名前の関数(受信側メソッド)が stage.gd スクリプトに追加され、カスタムシグナルとその関数が接続しました。
![Godot4 ビッグカツブロック崩し Ball のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知3](https://compota-soft.work/wp1/wp-content/uploads/2024/12/Godot4-ビッグカツブロック崩し-Ball-のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知3-1024x553.png)
シグナルから呼び出してもらうために作成した _on_ball_ball_screen_exited 関数の処理で on_game_over 関数を呼び出します。
on_game_over 関数では、仮に print 文のメッセージを出力して、呼び出されたことを確認します。
stage.gd スクリプトのそれら2つの関数の処理を以下のように変更します。
## ゲームオーバーになった際に呼び出されます。
func on_game_over():
# ゲームの進行状況を更新します。
current_phase = Phase.GameOver
print("current_phase = Phase.GameOver")
return
## Ball ノードが画面外に出た際に発する
## カスタムノイズ ball_screen_exited を受信するメソッドです。
func _on_ball_ball_screen_exited():
# ゲームオーバー時の処理を呼び出します。
on_game_over()
return
テスト
F6 キーで開いているステージのシーンを実行します。
ボールが画面外(下図では下側)に出た直後に、ボールの子ノード VisibleOnScreenNotifier2D ノードの screen_exited() シグナルが送信され、接続した関数(受信側メソッド)が呼び出され、関数内の print によるメッセージの出力が確認できました。
![Godot4 ビッグカツブロック崩し Ball のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知4](https://compota-soft.work/wp1/wp-content/uploads/2024/12/Godot4-ビッグカツブロック崩し-Ball-のカスタムシグナルで別のシーンのノードがゲームオーバーのタイミングを検知4-1024x679.png)
まとめ
「ビッグカツブロック崩し」作成の第20回では、独自のシグナル(カスタムシグナル)を使って、ブロック崩しのボールが画面外に出てゲームオーバーになったことを、ボールシーンの外部にあるステージのシーンのノードの関数(受信側メソッド)に伝える実装例を紹介しました。
参照サイト Thank You!
- Godot Engine – Free and open source 2D and 3D game engine
- Xユーザーのビッグカツといか姿フライのすぐる【公式】さん: 「使いどころは思いつきませんが、フリー素材としてどうぞご自由にお使いくださいませ! https://t.co/8F9q3hS02b」 / X
- しょかきうたげ【フリーフォント版あり】 – ぼんのう堂 – BOOTH
- シグナルの使用 — Godot Engine (4.x)の日本語のドキュメント
記事一覧 → Compota-Soft-Press
コメント