迷路の各マスを配置しよう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にして迷路より手前にします。
