Как изменить уровень в Godot 4?

Вопрос или проблема

Я разрабатываю игру с использованием 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 и других, относящихся к состоянию игры, не сохраняются между сценами правильно.

Рекомендации по сохранению состояния уровня

  1. Использование 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")

    Это позволит вам сохранять состояние уровня даже при переключении сцен.

  2. Обработка событий завершения мини-игры:

    Вместо того чтобы просто переключаться на новую сцену при завершении мини-игры, убедитесь, что основной скрипт получает уведомление о завершении мини-игры. Учтите, что вы можете использовать сигнал или вызвать метод 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()  # Обновляем уровень
  3. Обновление плитки после завершения уровня:

    После возвращения в основную сцену убедитесь, что плитки обновляются правильно, используя метод 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, но и улучшить общую архитектуру кода, сделав ее более устойчивой к ошибкам и легко расширяемой в будущем.

Оцените материал
Добавить комментарий

Капча загружается...