godot-mota/src/level/LevelsManager.gd

182 lines
5.1 KiB
GDScript

extends Node2D
class_name LevelsManager
const tmp_level_scene_path = "user://tmp/"
const init_level_scene_path = "res://src/levels/"
const group_name = "serializable"
# 当前楼层
export var level : int = 1 setget set_level
# 全局数据
var global : Dictionary = {}
signal level_changed(level)
func _ready():
var dir = Directory.new()
FileUtils.remove_dir(tmp_level_scene_path)
dir.make_dir(tmp_level_scene_path)
# 获取当前楼层实例
func get_current_level_instance() -> LevelInstance:
return get_child(0) as LevelInstance
# 设置楼层
func set_level(next_level:int):
#保存数据
save_screenshot()
save_instance_to_local()
save_data_to_local()
load_data(next_level)
save_go_to_level(next_level)
# 保存去过的楼层
func save_go_to_level(level:int):
if not self.global.has("player_levels"):
self.global.player_levels = {1:-1}
self.global.player_levels[level] = -1
# 获取去过的楼层
func get_go_to_levels() -> Array:
if not self.global.has("player_levels"):
return [1]
return self.global.player_levels.keys()
# 获取屏幕截图路径
func get_screenshot_image_path(now_level:int) -> String:
return "%s%s.png" % [tmp_level_scene_path,now_level]
func load_data(next_level:int):
#加载数据
var next_scene = load_scene_from_local(next_level) as LevelInstance
add_child(next_scene)
get_current_level_instance().free()
$"/root/Main".on_level_changed(next_level)
load_data_from_local(next_level)
#设置数据
level = next_level
# 保存当前楼层的屏幕截图
func save_screenshot():
var image = get_viewport().get_texture().get_data()
image.flip_y()
var save_error = image.save_png(get_screenshot_image_path(self.level))
if save_error != OK:
print("保存截图失败:"+save_error)
# 设置楼层和位置
func set_level_and_position(next_level:int,position:Vector2):
set_level(next_level)
var player = get_current_level_instance().get_player()
player.position = position
# 保存当前场景到本地文件
func save_instance_to_local():
var scene = PackedScene.new()
var result = scene.pack(get_current_level_instance())
if result == OK:
var error = ResourceSaver.save("%s%s.tscn" % [tmp_level_scene_path,level], scene)
if error != OK:
push_error("保存场景失败")
# 从本地加载场景文件
func load_scene_from_local(next_level:int) -> LevelInstance:
var path = "%s%s.tscn" % [tmp_level_scene_path,next_level]
var scene = null
if FileUtils.file_exist(path):
scene = load(path).instance()
else:
var init_path = "%sLevel%s.tscn" % [init_level_scene_path,next_level]
scene = load(init_path).instance()
scene.name = "Level%s" % next_level
return scene as LevelInstance
# 保存游戏数据
func save_data_to_local():
var data = {}
for node in get_tree().get_nodes_in_group(group_name):
node.save_data(data,global)
var file = File.new()
var file_error = file.open("%s%s.data" % [tmp_level_scene_path,level],File.WRITE)
if file_error != OK:
print("保存游戏数据失败:",file_error)
return
file.store_var(data,true)
file.close()
# 还原游戏数据
func load_data_from_local(next_level:int):
var file = File.new()
var file_error = file.open("%s%s.data" % [tmp_level_scene_path,next_level],File.READ)
var data = null
if file_error == OK:
data = file.get_var(true)
else:
data = {}
for node in get_tree().get_nodes_in_group(group_name):
node.load_data(data,global)
# 持久化数据
func save_persistent(index:int)->void:
#保存当前场景
save_instance_to_local()
save_data_to_local()
#保存当前楼层
var file = File.new()
var dir = Directory.new()
var dest_dir = "user://%s/" % index
dir.make_dir(dest_dir)
file.open(dest_dir + "level.data",File.WRITE)
file.store_string(to_json({
"level":self.level,
"global":self.global
}))
file.close()
#迁移数据到持久化目录
if dir.open(tmp_level_scene_path) == OK:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if dir.current_is_dir():
print("Found directory: " + file_name)
else:
var copy_result = dir.copy(tmp_level_scene_path + file_name,dest_dir + file_name)
if copy_result != OK:
print("保存存档失败",copy_result)
file_name = dir.get_next()
else:
print("An error occurred when trying to access the path.")
# 加载持久化数据
func load_persistent(index:int)->void:
var file = File.new()
var dir = Directory.new()
var dest_dir = "user://%s/" % index
dir.remove(tmp_level_scene_path)
dir.make_dir(tmp_level_scene_path)
#迁移持久化目录到临时目录
if dir.open(dest_dir) == OK:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if dir.current_is_dir():
print("Found directory: " + file_name)
else:
if file_name != "level.data":
var copy_result = dir.copy(dest_dir + file_name,tmp_level_scene_path + file_name)
if copy_result != OK:
print("读取存档失败",copy_result)
file_name = dir.get_next()
else:
print("An error occurred when trying to access the path.")
#读取楼层
file.open(dest_dir + "level.data",File.READ)
var data = JSON.parse(file.get_as_text()).result
var level = data.level
self.global = data.global
file.close()
load_data(level)