Вопрос или проблема
Я разрабатываю игру с использованием Godot 4.2.2. Пользователь нажимает кнопку, чтобы начать мини-игру. После завершения мини-игры игрок возвращается в основную сцену, и плитка, соответствующая текущему уровню, должна быть обновлена на новую плитку.
Граф игры
В настоящее время игрок — это кнопка, а мини-игра — это простая кнопка “Нажми на меня”. Мой основной скрипт прикреплен к корню и находится в Autoload.
Дерево сцен
Проблема в том, что после завершения мини-игры уровень сбрасывается на 1. Это приводит к тому, что трансформация всегда применяется к первой плитке. Я пытался изменить свой скрипт, но не понимаю, почему уровень инициализируется заново.
extends Node3D
var level: int = 0 # Текущий уровень
var previous_level: int = 0 # для обнаружения изменений уровня
var level_change: bool
var move_player: bool
var movements: Dictionary
var tiles: Dictionary
# Проверка, является ли текущая сцена основной сценой
@onready var is_main: bool = get_tree().current_scene.name == "main"
func _ready():
# Загрузка данных из JSON файла
var file = FileAccess.open("res://test/movements.json", FileAccess.READ)
movements = JSON.parse_string(file.get_as_text())
file.close()
print("Учебник...")
upgrade_level()
add_tiles()
func _process(delta):
# Проверка, был ли изменен уровень
level_change = level != previous_level
if level_change and is_main:
previous_level += 1
# Обновление сцены
replace_tile()
# Запуск мини-игры, когда игрок (кнопка) нажата
func _on_player_pressed():
print("Запуск игры...")
get_tree().change_scene_to_file("res://test/button_game.tscn")
# Улучшение уровня
func upgrade_level():
if level < 9:
level += 1
print("\nУровень ", level)
# Закрытие игры
func close_game():
print("Игра завершена")
print("Закрытие игры...")
upgrade_level()
# Возврат к основной сцене
get_tree().change_scene_to_file("res://test/change_level.tscn")
# перемещение игрока (обрабатывается в другом скрипте)
move_player = true
func add_tiles():
for i in range(1, 10):
var movement = movements[str(i)]
var game = movement["played"] if level > i else movement["not_played"]
var scene = load("res://test/" + game + ".tscn")
var instance = scene.instantiate()
instance.position = Vector3(movement.x, -1.5, movement.z)
add_child(instance)
tiles[i] = instance
func replace_tile():
print("Изменить плитку ", level)
tiles[level].queue_free()
#var movement = movements[str(level)]
#var game = movement["played"]
#var scene = load("res://test/" + game + ".tscn")
#var instance = scene.instantiate()
#instance.position = Vector3(movement.x, -1.5, movement.z)
#add_child(instance)
Есть ли какие-либо советы по поводу того, почему уровень сбрасывается после возврата к основной сцене?
Ответ или решение
Ваша задача заключается в изменении уровня в Godot 4.2.2, при этом необходимо обеспечить, чтобы после завершения мини-игры уровень не сбрасывался. Мы разберем вашу проблему в деталях и предложим решения.
Причина сброса уровня
Сброс уровня после возвращения в основную сцену может происходить по нескольким причинам, многие из которых связаны с тем, как Godot обрабатывает изменения сцен. Когда вы загружаете новую сцену, все глобальные и локальные переменные, определенные в старой сцене, будут сброшены, поскольку новая сцена инициализируется с нуля.
Поскольку ваш основной скрипт находится в Autoload (глобальный скрипт), существует вероятность, что значения переменных level
и других, относящихся к состоянию игры, не сохраняются между сценами правильно.
Рекомендации по сохранению состояния уровня
-
Использование Autoload для хранения состояния:
Убедитесь, что ваши переменные
level
,previous_level
и другие состояния хранятся в соответствующем Autoload-скрипте. Если у вас несколько сцен, указывающих на одну и ту же логику, вы можете создать файлGameManager.gd
и поместить туда свою логику управления состоянием.Пример содержания
GameManager.gd
:extends Node var level: int = 0 # Текущий уровень var previous_level: int = 0 # Для отслеживания изменений уровня func reset_level(): level = 0 previous_level = 0 func upgrade_level(): if level < 9: # Максимальный уровень level += 1 print("\nУровень ", level) func on_mini_game_completed(): upgrade_level() get_tree().change_scene_to_file("res://test/change_level.tscn")
Это позволит вам сохранять состояние уровня даже при переключении сцен.
-
Обработка событий завершения мини-игры:
Вместо того чтобы просто переключаться на новую сцену при завершении мини-игры, убедитесь, что основной скрипт получает уведомление о завершении мини-игры. Учтите, что вы можете использовать сигнал или вызвать метод
on_mini_game_completed()
из вашего мини-игрового скрипта.func _on_player_pressed(): print("Запуск игры...") get_tree().change_scene_to_file("res://test/button_game.tscn") func _on_mini_game_end(): GameManager.on_mini_game_completed() # Обновляем уровень
-
Обновление плитки после завершения уровня:
После возвращения в основную сцену убедитесь, что плитки обновляются правильно, используя метод
replace_tile()
.func replace_tile(): if level > 0 and level <= tiles.size(): print("Модификация плитки ", level) tiles[level].queue_free() add_tiles() # Добавление новых плиток
Заключение
Перепроверьте вашу структуру кода, чтобы убедиться, что состояние уровня сохраняется при переключении между сценами. Поместите соответствующие переменные в скрипт Autoload
, чтобы избежать их сброса. Следуйте предложенным рекомендациям для обработки завершения мини-игры, и это должно помочь решить вашу проблему.
Эти шаги помогут вам не только изменить уровень в вашем проекте на Godot 4.2.2, но и улучшить общую архитектуру кода, сделав ее более устойчивой к ошибкам и легко расширяемой в будущем.