迷路の各マスを配置しよう1
スクリプトの作成
前回は、迷路の「Maze」シーンには「Player」しか登場していませんでした。迷路の部品になる床、スタート、ゴール、壁を用意したので、プログラムで生成した迷路の二次元配列に従い、迷路のタイルを配置していきます。
「ファイルシステム」ドックでres://scn/maze
フォルダーを開き、右クリックして「新規作成」>「スクリプト」を選びます。
「スクリプト作成」ダイアログが開きますので、「テンプレート」のチェックボックスを外し、「パス」をres://scn/maze/maze_layout.gd
にして「作成」ボタンを押します。
作成されたmaze_layout.gd
をダブルクリックして「Script」ビューで開きます。maze_layout.gd
に、次のように迷路を配置するプログラムを書きます。
extends Node2D class_name MazeLayout const TILE_SIZE = 32 # 迷路表示 static func layout(root: Node, maze_info: Dictionary) -> void: var start_pos = maze_info["start"] var goal_pos = maze_info["goal"] var maze_arr = maze_info["maze_arr"] var floor_scene = load("res://scn/floor/floor.tscn") var wall_scene = load("res://scn/floor/wall.tscn") var start_scene = load("res://scn/floor/start.tscn") var goal_scene = load("res://scn/floor/goal.tscn") # 迷路タイルの配置 for y in maze_arr.size(): var line = maze_arr[y] for x in line.size(): var block if line[x] == MazeUtil.ROAD: block = floor_scene.instantiate() else: block = wall_scene.instantiate() block.position = Vector2(x, y) * TILE_SIZE root.add_child(block) # スタート位置の配置 var start = start_scene.instantiate() start.position = start_pos * TILE_SIZE root.add_child(start) # ゴール位置の配置と、シグナルの接続 var goal = goal_scene.instantiate() goal.position = goal_pos * TILE_SIZE root.add_child(goal) goal.body_entered.connect(root._on_goal_enter) # プレイヤーの配置 var player = root.get_node("Player") player.position = start_pos * TILE_SIZE player.z_index = 1
スクリプトの解説1 迷路各マスの作成
このファイルのクラス名はMazeLayout
にします。タイルのピクセルサイズは32
です。
class_name MazeLayout const TILE_SIZE = 32
関数はlayout
だけです。この関数は、ルートのノードと、maze_util.gd
のgen_maze
関数の戻り値を引数にして、迷路の配置をおこないます。
# 迷路表示 static func layout(root: Node, maze_info: Dictionary) -> void:
まず冒頭では、gen_maze
関数の戻り値から、スタート位置、ゴール位置、迷路の2次元配列を取り出します。
var start_pos = maze_info["start"] var goal_pos = maze_info["goal"] var maze_arr = maze_info["maze_arr"]
続いて、床、スタート、ゴール、壁のシーンを読み込みます。読み込みはload
関数でおこないます。
var floor_scene = load("res://scn/floor/floor.tscn") var wall_scene = load("res://scn/floor/wall.tscn") var start_scene = load("res://scn/floor/start.tscn") var goal_scene = load("res://scn/floor/goal.tscn")
次は迷路タイルの配置です。
# 迷路タイルの配置 for y in maze_arr.size(): var line = maze_arr[y] for x in line.size(): var block if line[x] == MazeUtil.ROAD: block = floor_scene.instantiate() else: block = wall_scene.instantiate() block.position = Vector2(x, y) * TILE_SIZE root.add_child(block)
2次元配列maze_arr
を利用して、値がMazeUtil.ROAD
の時は床を配置します。この時はfloor_scene.instantiate()
として「Floor」シーンをインスタンス化します。
値がMazeUtil.ROAD
ではない時は壁を配置します。この時はwall_scene.instantiate()
として「Wall」シーンをインスタンス化します。
それぞれroot
のadd_child
で、シーンツリーに作成したインスタンスを追加します。
スクリプトの解説2 特殊なマスの作成とプレイヤーの調整
迷路の各マスを配置したあと、スタートとゴールのマスを作ります。スタートはstart_scene
から作ります。ゴールはgoal_scene
から作ります。
# スタート位置の配置 var start = start_scene.instantiate() start.position = start_pos * TILE_SIZE root.add_child(start) # ゴール位置の配置と、シグナルの接続 var goal = goal_scene.instantiate() goal.position = goal_pos * TILE_SIZE root.add_child(goal)
「Goal」シーンでは、body_entered.connect
でシグナルを接続します。
goal.body_entered.connect(root._on_goal_enter)
「Goal」シーンのシェイプに「Player」シーンが入ってきたら(body_entered
が発生したら)、root
ノードの_on_goal_enter
関数を実行します。この_on_goal_enter
関数はあとで作ります。
最後は「Player」の設定です。
# プレイヤーの配置 var player = root.get_node("Player") player.position = start_pos * TILE_SIZE player.z_index = 1
まず、get_node
関数を使って、root
配下のPlayer
を探して取得します。static
関数の中では$NodeName
の書き方は利用できません。
Player
の位置をスタートマスと同じ位置にして、z_index
を1
にして迷路より手前にします。