Godot4 ビッグカツブロック崩し9 ブロックの作成とボール衝突時の消去

※この連載の全ての記事は、タグ「ビッグカツ」の検索一覧から探すことができます。
※この連載で作ったゲームは「BigBreakOut(ゲームの作り方の記事付き) | フリーゲーム投稿サイト GodotPlayer」でプレイできます。

昔から人気の駄菓子「ビッグカツ」フリー素材画像が公開されたので、無料・軽快な 2D / 3D 用のゲームエンジン Godot Engine 4 を使って、ビッグカツ画像を使ったブロック崩しを作成します。

「ビッグカツブロック崩し」作成の第9回では、ブロックのシーンを作成して、その画像表示当たり判定領域の設定、ステージシーンに子ノードとして複数配置する手順、ボール衝突した際にそのブロックを消去するスクリプト例とそのテストを紹介します。

※ GodotEngine 4.3 を使用しています。.NET 版ではありません。
※スクリプトは自己責任でご使用ください。

前回の記事

前回は、パドル(バー)がボール衝突されても揺れないように、壁・ボール・パドルの各コリジョンレイヤー・マスクを設定しました。

後述する、ノードで画像を表示当たり判定の領域を設定する手順は、以下の記事にも書いてあります。

ブロックのシーンの新規作成

ボールがぶつかったら消されるブロックシーンとして作成して、あとでステージのシーンに子ノードとして追加します。

メニュー「シーン」→「新規シーン」でブロックのシーンを新規作成します。

Godot4 ビッグカツブロック崩し ブロックのシーンの作成1

ブロックは、動かない剛体を表現できる StaticBody2D クラスをルートノードとして作成するので「その他のノード」をシーンドックで選択して、そのクラスを選択して「作成」ボタンを押します。
※ダイアログ上部の検索ボックスを利用すると探しやすいです。

Godot4 ビッグカツブロック崩し ブロックのシーンの作成2

作成したルートノードはわかりやすいように Block という名前に変更します。
※名前の変更は、シーンドックでノードを右クリックして表示されるメニュー「名前を変更」などで行います。

Godot4 ビッグカツブロック崩し ブロックのシーンの作成3

画像を表示するノードの追加

ファイルシステムドックに画像ファイルをドラッグ&ドロップしてプロジェクトに追加しておいたビッグカツのフリー素材画像を、2D ワークスペースドラッグ&ドロップすると、開いている Block シーンの下位ノードにその画像を表示する Sprite2D クラスのノードが追加されます。

後で子ノードとして扱いやすいように、インスペクタードックで追加されたノードの Node2D クラスの Transform セクションの Position 項目の (x, y) でノードの位置を (0, 0) に調整します。

Godot4 ビッグカツブロック崩し ブロックのシーンの作成4

当たり判定領域の設定

追加した画像に合わせて、四角形の当たり判定領域を設定します。

シーンドックの Block ルートノード右クリックして表示されるメニュー「子ノードを追加」を選択してから CollisionShape2D クラスを選択・作成します。

下位に追加された CollsionShape2D ノードを選択してから、インスペクタードックで、 Shape プロパティのリストの「新規 RectangleShape2D」を選択して、四角形の情報を持つリソース割り当てます。

Godot4 ビッグカツブロック崩し ブロックのシーンの作成5

シーンの保存

Block の画像と当たり判定領域を設定したら、Ctrl + S などでシーンを保存します。
※例では block.tscn ファイルに保存します。

Godot4 ビッグカツブロック崩し ブロックのシーンの作成6

ブロックシーンをステージシーンに子ノードとして複数配置

ブロックのシーンを保存したら、stage のタブを選択してステージのシーンを開きます。
ウィンドウ中央上部で、 2D ワークスペースを選択すると、前回までに追加したステージ内の壁・パドル(バー)・ボールが配置されている画面が表示されます。

2D ワークスペースに、先ほど保存したブロックのシーンのファイル(例では block.tscn)をファイルシステムドックから 2D ワークスペースの壁に囲まれた中央付近にドラッグ&ドロップしてみましょう。

以上で、ブロックのシーンが、ステージに、子ノードとして追加配置されました。

Godot4 ビッグカツブロック崩し ブロックのシーンのステージへの配置(仮)

同様に、複数のブロックを配置できます。
配置すると Block, Block2, Block3 という名前でブロックの子ノードステージのシーン複数追加できました。

Godot4 ビッグカツブロック崩し ブロックのシーンのステージへの配置(仮)2

ボールのスクリプトのブロックを消去する処理の説明

次に、画面中央上部の Script ワークスペースを選択してから、ワークスペース内の左側の ball.gd を選択します。
ブロック崩しの玉を制御するスクリプトの割り当ては、以下の記事で行いました。

https://compota-soft.work/wp1/wp-admin/post.php?post=41400&action=edit

その記事で作成した ball.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")

func _ready():
	# 初期角度でボールを発射
	var direction = Vector2(cos(INITIAL_ANGLE), sin(INITIAL_ANGLE))
	velocity = direction * BALL_SPEED

func _physics_process(delta):
	# 設定されている加速度で移動します。
	var collision: KinematicCollision2D = move_and_collide(velocity * delta)

	# 何かに衝突した場合
	if collision:
		# 衝突した Object を取得します。
		var collider:Object = collision.get_collider()
		# Paddle の場合
		if collider.name == "Paddle":
			#print("Paddle")
			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

39 行目では、衝突したノードの名前が Block から始まるかを判定しています。
Block から始まる名前だった場合は、ブロックを消去する処理として collider.queue_free() を呼び出します。
queue_free メンバ関数は、それを呼び出したノード(例ではぶつかったブロックのノード)を消去します。
※詳細はスクリプトのコメントを参照してください。

Queues this node to be deleted at the end of the current frame. When deleted, all of its children are deleted as well, and all references to the node and its children become invalid.

Unlike with Object.free, the node is not deleted instantly, and it can still be accessed before deletion. It is also safe to call queue_free multiple times. Use Object.is_queued_for_deletion to check if the node will be deleted at the end of the frame.

Note: The node will only be freed after all other deferred calls are finished. Using this method is not always the same as calling Object.free through Object.call_deferred.

現在のフレームの最後に削除されるようにこのノードをキューに入れます。削除すると、その子もすべて削除され、ノードとその子へのすべての参照が無効になります。

Object.free とは異なり、ノードはすぐには削除されず、削除前でもアクセスできます。 queue_free を複数回呼び出しても安全です。 Object.is_queued_for_deletion を使用して、フレームの最後にノードが削除されるかどうかを確認します。

注: ノードは、他のすべての遅延呼び出しが終了した後にのみ解放されます。このメソッドの使用は、Object.call_deferred を介して Object.free を呼び出すことと必ずしも同じではありません。
Node — Godot Engine (4.x)の日本語のドキュメント #method-queue-free と Google 翻訳

効果音を再生する SCUtil.AudioStreamOneShotPlay 自作静的関数については以下の記事を参照してください。

テスト

F6 キーなどで選択しているステージのシーン実行すると、玉がぶつかったブロックが消えることが確認できました。

Godot4 ビッグカツブロック崩し ボールがブロックにぶつかったらブロックを消す処理のテストSS1

まとめ

「ビッグカツブロック崩し」作成の第9回では、ブロックのシーンを作成して、その画像表示当たり判定領域の設定、ステージシーンに子ノードとして複数配置する手順、ボール衝突した際にそのブロックを消去するスクリプト例とそのテストを紹介しました。

参照サイト Thank You!

記事一覧 → Compota-Soft-Press

コメント

Ads Blocker Image Powered by Code Help Pro

お願い - Ads Blocker Detected

このサイトは広告を掲載して運営しています。

ポップアップを閉じて閲覧できますが、よろしければ

このサイト内の広告を非表示にする拡張機能をオフにしていただけませんか?

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

We have detected that you are using extensions to block ads. Please support us by disabling these ads blocker.

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