You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
3.2 KiB
GDScript

extends Node3D
class_name LevelManager
var target: int
var level: Level
var cur_level_instance: LevelInstance
var level_instance_dict: Dictionary = {}
func _ready():
Global.level_mgr = self
SignalManager.character_create.connect(on_character_create)
SignalManager.character_pos_changed.connect(on_character_pos_changed)
SignalManager.character_destroy.connect(on_character_destroy)
func init():
var level_scene: PackedScene = load("res://scene/level/level.tscn")
level = level_scene.instantiate() as Level
add_child(level)
var level_instance_list: Array[LevelInstance] = level.get_level_instance_list()
for level_instance in level_instance_list:
var level_id_list: Array[Vector3i] = get_level_id_list(level_instance.get_global_position(), level_instance.size)
# print("xx", level_instance.name, ":", level_id_list)
for level_id in level_id_list:
if level_id in level_instance_dict:
print("关卡id重复", level_id)
level_instance_dict[level_id] = level_instance
func _process(delta) -> void:
pass
func get_born_pos() -> Vector3:
return level.get_born_pos()
func on_character_create(id: int, type: int, pos: Vector3):
if type == Enum.ECharacterType.Player:
target = id
on_character_pos_changed(id, pos)
func on_character_pos_changed(id: int, pos: Vector3):
if id == target:
set_player_position(pos)
func on_character_destroy(id: int): target = 0
func set_player_position(pos: Vector3) -> void:
var new_id: Vector3i = get_level_id(pos)
var new_level_instance: LevelInstance = level_instance_dict.get(new_id)
if not new_level_instance:
return #todo 不存在的关卡 主角直接死亡
if cur_level_instance:
if new_level_instance == cur_level_instance:
return
pass#todo 销毁原关卡实体 并存档
cur_level_instance = new_level_instance
SignalManager.level_size_change.emit(cur_level_instance.level_size())
SignalManager.level_pos_change.emit(cur_level_instance.level_pos())
func get_level_id_list(pos: Vector3, size: Vector3i) -> Array[Vector3i]:
var size_basic: Vector3 = Setting.size_basic
var ret: Array[Vector3i] = []
for x in range(size.x):
for y in range(size.y):
for z in range(size.z):
var pos_sub: Vector3 = pos +Vector3(x*size_basic.x, y*size_basic.y, z*size_basic.z)
ret.append(get_level_id(pos_sub))
return ret
func get_level_id(pos: Vector3) -> Vector3i:
var ret: Vector3i = Vector3i(get_div_scale(pos.x, Setting.size_basic.x), get_div_scale(pos.y, Setting.size_basic.y), get_div_scale(pos.z, Setting.size_basic.z))
# print("get_level_id", pos, ret)
return ret
func get_div_scale(a: float, b: float) -> int:
#解决浮点数精度问题
var div: float = a / b
var is_positive: bool = div > 0
var decimal: float = abs(div - int(div))
if is_positive and decimal > 0.999:
div += 0.001
if not is_positive and decimal < 0.001:
div += 0.001
# print("get_div_scale", " ", a, " ", b, " ", decimal, " ", div)
return floor(div)