レベルの管理と自動保存
レベルの管理と自動保存のスクリプトを作成
ユーザーデータの保存と復帰はできました。今度は、「ListDialog」用に迷路のレベル選択メニューを作ったり、成績を管理したりします。
data_manager.gdを、次のように書き換えます。
_ready関数の「ファイルアクセスのテスト」はコメントアウトします。load_from_file関数とsave_to_file関数はそのままです。
extends Node
const PATH_SAVE_DATA = "user://save.dat"
var record_array = []
var level_array = []
var level_index = 0
func _ready() -> void:
# ファイルアクセスのテスト
#load_from_file()
#record_array = [true, false, true]
#save_to_file()
#load_from_file()
#DirAccess.remove_absolute(PATH_SAVE_DATA)
# データの初期化と、保存データの復帰
for i in 10:
var h = 9 + i * 2
var w = int(h * 1.5)
level_array.append({"level": i + 1, "w": w, "h": h})
record_array.append(false)
load_from_file()
func get_level_menus() -> Array[Variant]:
var menus = []
for i in level_array.size():
var item = level_array[i]
var title = "レベル %s" % item["level"]
if record_array[i]:
title += " クリア!"
var desc = "迷路 横幅 {w}、高さ {h}".format(item)
menus.append({"title": title, "desc": desc})
return menus
func set_level(i: int) -> void:
level_index = i
func get_current() -> Dictionary:
return level_array[level_index]
func record() -> void:
record_array[level_index] = true
save_to_file()
func load_from_file() -> void:
if FileAccess.file_exists(PATH_SAVE_DATA):
var file = FileAccess.open(PATH_SAVE_DATA, FileAccess.READ)
var json_string = file.get_as_text()
var tmp_data = JSON.parse_string(json_string)
if tmp_data != null:
record_array = tmp_data
print("record_array: " + str(record_array))
else:
print("Not exist.")
func save_to_file() -> void:
var file = FileAccess.open(PATH_SAVE_DATA, FileAccess.WRITE)
var json_string = JSON.stringify(record_array)
file.store_string(json_string)
スクリプトの解説1 _ready
新しく追加した部分を見ていきましょう。
まずは_ready関数です。
var level_array = []
var level_index = 0
func _ready() -> void:
# データの初期化と、保存データの復帰
for i in 10:
var h = 9 + i * 2
var w = int(h * 1.5)
level_array.append({"level": i + 1, "w": w, "h": h})
record_array.append(false)
load_from_file()
10レベル分のデータを作成しています。データの中身は「レベルの数値」と「迷路の横幅と高さ」、そして「初期の成績」です。
また最後に、load_from_file関数で過去の成績を読み込んでいます。
load_from_file関数では、データがまだない場合は読み込みをおこないません。そのためrecord_arrayは初期化した状態のままです。
データがある場合は、読み込んだデータで置き換えられます。
スクリプトの解説2 get_level_menus
次はget_level_menus関数です。
func get_level_menus() -> Array[Variant]:
var menus = []
for i in level_array.size():
var item = level_array[i]
var title = "レベル %s" % item["level"]
if record_array[i]:
title += " クリア!"
var desc = "迷路 横幅 {w}、高さ {h}".format(item)
menus.append({"title": title, "desc": desc})
return menus
リストダイアログ用のメニューを作成して得ます。
クリアしているレベルは" クリア!"の表記を加えます。
スクリプトの解説2 その他
その他の細々とした関数です。
func set_level(i: int) -> void: level_index = i func get_current() -> Dictionary: return level_array[level_index] func record() -> void: record_array[level_index] = true save_to_file()
set_level関数は、ダイアログで選択したレベルを設定するための関数です。
get_current関数は、現在のレベルの情報を得るための関数です。
record関数は、迷路をクリアしたあと、そのレベルのクリアを記録する関数です。
ゲームへの組み込み
それではこれらをゲームに組み込みましょう。
まずはタイトル画面です。res://scn/title/title.gdの_on_button_pressed関数を次のように書き換えます。
func _on_button_pressed() -> void: var title = "迷路の選択" var menus = DataManager.get_level_menus() var res = await DialogList.open(title, menus) DataManager.set_level(res) # シーン変更 SceneManager.load_scene(SceneManager.MAZE)
レベルの選択ダイアログを出して、選択結果を設定します。
次は、迷路画面です。res://scn/maze/maze.gdの_ready関数を次のように書き換えます。
func _ready() -> void: #MazeUtil.test_gen_maze() # シーン開始 SceneManager.effect_enter_scene() BgmManager.start_bgm() # 迷路データの作成と表示 var item = DataManager.get_current() var maze_info = MazeUtil.gen_maze(item["w"], item["h"]) MazeLayout.layout(self, maze_info)
DataManager.get_current関数で、タイトル画面で選択したレベルの情報を得ます。その横幅と高さで迷路を作成します。
また、_on_goal_enter関数を次のように書き換えます。
# プレイヤーがゴールした func _on_goal_enter(_area) -> void: DataManager.record() # プレイヤーを停止して、クリアシーンを追加 player.is_act = false add_child(clear_scene.instantiate()) # クリア音楽を流したあと、シーンを変更 BgmManager.bgm_off() var audio = $AudioStreamPlayer audio.play() await get_tree().create_timer(audio.stream.get_length() + 1).timeout BgmManager.bgm_on() SceneManager.load_scene(SceneManager.TITLE)
冒頭にDataManager.record()を追加しています。追加はこれだけです。
ここでは、プレイしたレベルのクリア情報を保存します。
ゲームの開発はこれで終了です。
