Menu
CoddyTech

デザインパターン入門

CoddyのGDScriptジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 45/65。

デザインパターンとは、プログラムを作るたびに繰り返し現れる問題に対して、クラスをどのように構成するかを示す、よく知られた名前付きの方法です。ライブラリでも、そのままコピーするコードでもありません。どのオブジェクトが存在し、それぞれが何を担当し、どのように連携するのかを説明するものです。自分のゲームに合わせて、自分でコードを書きます。

パターンは、開発者同士で共通の用語を使えるようにもします。「敵はファクトリーから生成される」や「体力バーはプレイヤーを監視する」と言えば、ファイルを開く前にコードの構成をチームメイトに伝えられます。

パターンで解決できる問題を紹介します。レベルを開始するには3つのオブジェクトとやり取りする必要があり、レベルを開始するすべてのスクリプトで次の行が繰り返されます。

var music := MusicPlayer.new()
var level_map := LevelMap.new()
var hud := Hud.new()
music.play("forest.ogg")
level_map.load_map(1)
hud.show_hearts(3)

Facadeパターンでは、それらのオブジェクトの前に1つのクラスを置き、シンプルなメソッドを1つ用意します。

# game_facade.gd
class_name GameFacade
extends RefCounted

var music := MusicPlayer.new()
var level_map := LevelMap.new()
var hud := Hud.new()

func start_level(number: int) -> void:
	music.play("forest.ogg")
	level_map.load_map(number)
	hud.show_hearts(3)
# main.gd
var game := GameFacade.new()
game.start_level(1)
Music: playing forest.ogg
Map: level 1 loaded
HUD: hearts 3

プログラムの残りの部分ではstart_level()を呼び出し、レベルの開始方法を変更するときは、1つのファイルを編集します。

パターンは、解決する問題ごとに分類されます。

  • 生成パターンはオブジェクトの生成方法を制御します:Singleton、Factory。
  • 構造パターンはオブジェクトを組み合わせてより大きな構造を作ります:Facade、Adapter、Decorator、Composite。
  • 振る舞いパターンはオブジェクト同士の連携方法を整理します:Observer、Strategy、Command、Template Method、State。

この章と次の章では、これらのパターンを扱います。それぞれ、独立したファイル内のクラス、継承、ポリモーフィズム、コンポジション、シグナルなど、すでに学んだことをもとに構成されています。

challenge icon

チャレンジ

簡単

ゲームは、すでに実装されている3つのオブジェクトを通じてレベルを開始および終了します。MusicPlayer(music_player.gd)、LevelMap(level_map.gd)、Hud(hud.gd)です。これらの前面にファサード GameFacade を作成してください。

  • メンバー変数として、MusicPlayer、LevelMap、Hud をそれぞれ1つずつ作成します。
  • start_level(number, hearts) は、トラック level_N.ogg(Nはレベル番号)を再生します。ただし、番号が 5 の倍数の場合は boss.ogg を再生します。その後、そのレベルのマップを読み込み、ハートを表示します。
  • quit_level() はHUDを非表示にしてから、音楽を停止します。

提供されたコードは、後続するコマンドの数を読み込んだ後、1行につき1つのコマンドを読み込みます。コマンドは start NUMBER HEARTS または quit です。start 5 2 と quit の出力は次のとおりです。

Music: playing boss.ogg
Map: level 5 loaded
HUD: hearts 2
HUD: hidden
Music: stopped

コードは game_facade.gd に記述してください。main.gd には提供された入出力コードがあり、編集できません。

自分で試してみよう

extends Node

func _ready():
	# 提供された入出力コード: そのままにしてください
	var game := GameFacade.new()
	var count := int(OS.read_string_from_stdin())
	for i in count:
		var parts := OS.read_string_from_stdin().split(" ")
		if parts[0] == "start":
			game.start_level(int(parts[1]), int(parts[2]))
		elif parts[0] == "quit":
			game.quit_level()
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: GDScriptオンラインコンパイラ