на Главную Вход Регистрация Забыли пароль ?

skype: megainformatic, телеграм: megainformatic, онлайн-чат (megainformatic live chat), форма обратной связи

Онлайн Школа Компьютерных Наук Андрея Синицина

Онлайн Школа Компьютерных Наук Андрея Синицина - автор

Добро пожаловать в нашу школу ! Давайте вместе откроем путь к новым перспективам !!!

Глава 5 - Разработка игры на godot 3.4 - рефакторинг кода, полноэкранный режим, звуки и музыка




В данной серии статей мы знакомимся с созданием игр на godot версии 3.4

Если вы совсем не знаете godot, советую начать изучение с этих уроков -


Осваиваем движок godot 3.4 Глава 1 - Первые шаги

Глава 2 - Основы анимации и создание дистрибутива игры на godot

Глава 3 - Визуальная новелла на godot 3.4 часть 1 - основа будущей игры

Глава 4 - Визуальная новелла на godot 3.4 часть 2 - поддержка нескольких языков, signals



Сейчас мы займемся рефакторингом кода - то есть его улучшением.


Не совсем правильно то, что сейчас код, отвечающий за показ диалогов текстовых фраз, размещен
в скрипте 
main_scene.gd


Было бы логичнее создать отдельный узел с типом Node2D
и поместить в нём все, что касается отображения текстовой панели и работы с фразами текстовых
диалогов.

Этим мы сейчас и займёмся.


main_scene.gd

если кликать картинку она будет последовательно меняться в размерах от 640 до 1920 пиксель.
Такое разбиение всего проекта на логические и логичные единицы выполняющие свои собственные задачи, а не хранение всего и вся в одной куче и в одном скрипте, позволяет лучше структурировать ваши проекты и облегчить работу над ними, так как с течением времени многое забывается, и когда вы снова однажды вернетесь к своим старым проектам, вам будет в таком случае намного легче понять код. И самое главное такой код легче поддерживать и расширять. Для узла main_game_node создадим дочерний объект Node2D и назовем dialogue_text_panel тип Node2D позволит управлять видимостью объекта в сцене. Обычные объекты с типом Node не имеют такой возможности. Для объекта создадим внутрь объекта dialogue_text_panel перетащим все, что относится к данному объекту: text_panel_container и все его дочерние объекты также для dialogue_text_panel создадим gd скрипт - dialogue_text_panel.gd В него из main_scene.gd перенесем весь код, который отвечает за работу с текстовыми фразами диалогов. нужно будет заново задать файлы для фраз диалогов у объекта dialogue_text_panel также нужно будет внести изменения в main_scene.gd связанные с переносом кода в другой скрипт. в методе func _ready(): мы больше не можем вызывать start_dialogue(); поскольку такого метода в скрипте main_scene.gd больше не существует Она будет вызываться теперь внутри func _ready(): скрипта dialogue_text_panel.gd также строка кода $scene_1/text_panel_container/text.text = dialogue_text; теперь не имеет смысла т. к. переедет в одноименный метод func _ready(): внутри скрипта dialogue_text_panel.gd func _ready(): start_dialogue(); #$scene_1/text_panel_container/text.text = dialogue_text; $text_panel_container/text.text = dialogue_text; Также везде в коде dialogue_text_panel.gd нужно изменить $scene_1/text_panel_container/text.text = dialogue_text; на $text_panel_container/text.text = dialogue_text; для кнопок листания и для сигнала dialogue_started нужно будет сгенерировать новые обработчики событий т. е. все по-аналогии как мы делали в Глава 3 - Визуальная новелла на godot 3.4 часть 1 - основа будущей игры см. видео #302 визуальная новелла на godot 3.4 часть 1.3 начиная с момента 10:10 показывается как добавлять для кнопки Start обработчик клика по ней. нам нужно будет сделать новые обработчики для кнопок prev next а также новый обработчик для сигнала dialogue_started хотя в конце статьи Вы узнаете, что в связи с изменениями он теперь не нужен и реализовать его вызов в скрипте main_scene.gd нужно будет иначе. метод func set_dialogue_text(): примет вид - func set_dialogue_text(): var select_lang_scene = get_node("/root/main_game_node/select_lang_scene"); #match $select_lang_scene.selected_lang: match select_lang_scene.selected_lang: потому что теперь из объекта dialogue_text_panel мы не можем обратиться к объекту $select_lang_scene поэтому мы получаем к нему доступ через var select_lang_scene = get_node("/root/main_game_node/select_lang_scene"); и дальше используем вместо $select_lang_scene.selected_lang код select_lang_scene.selected_lang т. е. переменная select_lang_scene теперь хранит объект /root/main_game_node/select_lang_scene который нам нужен и мы просто проверяем у объекта его свойство (переменную) selected_lang Теперь при старте игры в экране выбора языка видна текстовая панель диалогов. Чтобы исправить это делаем так - main_scene.gd func _ready(): $select_lang_scene.visible = true; $main_scene.visible = false; $scene_1.visible = false; $dialogue_text_panel.visible = false; #т. е. в начальный момент скрываем объект dialogue_text_panel а отображать его будем только в scene_1, когда он нужен (ну и в дальнейшем - в других сценах игры - scene_2 и т. д.) В ходе работы я выяснил еще один важный нюанс. Дело в том, что сигналы доступны только внутри скриптов для которых они объявлены. Если пытаться вызвать сигнал из чужого скрипта, то срабатывания не произойдет. В связи с этим в скрипте main_scene.gd код метода _on_start_button_button_up() будет выглядеть так - #была нажата и отпущена кнопка Start в экране главного меню func _on_start_button_button_up(): $main_scene.visible = false; #скрываем сцену главного экрана $scene_1.visible = true; #делаем видимой сцену 1 $dialogue_text_panel.visible = true; #и панель текстовых диалогов #emit_signal("dialogue_started"); #излучить сигнал не получится - он теперь объявлен в скрипте dialogue_text_panel.gd #хотя ошибки возникать при этом никакой не будет. Но первая фраза будет всегда на русском, даже если выбрать английский #но вот такой вариант - исправляет проблему - $dialogue_text_panel._change_lang(); ну а в скрипте dialogue_text_panel.gd теперь такой код: export(String, FILE, "*.json") var dialogue_file_ru export(String, FILE, "*.json") var dialogue_file_en var dialogue_file var dialogue_name = "" var current = 0 var dialogue_text = "" var dialogue_keys_ru = [] var dialogue_keys_en = [] signal dialogue_started; func start_dialogue(): current = 0; index_dialogue(); set_dialogue_text(); func next_dialogue(): var dialogue_keys = dialogue_keys_ru; var select_lang_scene = get_node("/root/main_game_node/select_lang_scene"); match select_lang_scene.selected_lang: 1: dialogue_keys = dialogue_keys_ru; 2: dialogue_keys = dialogue_keys_en; if current > (dialogue_keys.size() - 2): return; current += 1; set_dialogue_text(); $text_panel_container/text.text = dialogue_text; func index_dialogue(): dialogue_file = dialogue_file_ru; var dialogue = load_dialogue(dialogue_file); dialogue_keys_ru.clear(); for key in dialogue: dialogue_keys_ru.append(dialogue[key]); dialogue_file = dialogue_file_en; dialogue = load_dialogue(dialogue_file) dialogue_keys_en.clear() for key in dialogue: dialogue_keys_en.append(dialogue[key]) func load_dialogue(file_path): var file = File.new() if file.file_exists(file_path): file.open(file_path, file.READ) var dialogue = parse_json(file.get_as_text()) return dialogue func prev_dialogue(): if current < 1: return; current -= 1; set_dialogue_text(); $text_panel_container/text.text = dialogue_text; # Called when the node enters the scene tree for the first time. func _ready(): start_dialogue(); #$scene_1/text_panel_container/text.text = dialogue_text; $text_panel_container/text.text = dialogue_text; emit_signal("dialogue_started"); # Called every frame. 'delta' is the elapsed time since the previous frame. #func _process(delta): # pass func set_dialogue_text(): var select_lang_scene = get_node("/root/main_game_node/select_lang_scene"); print("select_lang_scene.selected_lang ", select_lang_scene.selected_lang); #match $select_lang_scene.selected_lang: match select_lang_scene.selected_lang: #"ru": 1: dialogue_text = dialogue_keys_ru[current].text dialogue_name = dialogue_keys_ru[current].name #"en": 2: dialogue_text = dialogue_keys_en[current].text dialogue_name = dialogue_keys_en[current].name func _on_prev_button_up(): prev_dialogue(); #pass # Replace with function body. func _on_next_button_up(): next_dialogue(); #pass # Replace with function body. func _on_dialogue_text_panel_dialogue_started(): #visible = true; print("_on_dialogue_text_panel_dialogue_started"); set_dialogue_text(); $text_panel_container/text.text = dialogue_text; #pass # Replace with function body. func _change_lang(): print("_change_lang"); set_dialogue_text(); $text_panel_container/text.text = dialogue_text; #pass Проект со всеми необходимыми файлами для открытия из редактора godot 3.4.2.stable вы найдете в папке \examples\chapter_5\refactoring\ Демонстрация процесса рефакторинга и исправление возникающих ошибок показано на 2-х нижеследующих видео часть 1 показано как создать новый узел dialogue_text_panel перенести в него все относящиеся к текстовым диалогам объекты перенести код и исправить в нем возникшие ошибки часть 2 показано исправление ошибки с начальной инициализацией текстовой панели - вызов метода start_dialogue а также настройка смены языка по нажатию клавиши [L] Полноэкранный режим, звуки и музыка Демонстрирую воспроизведение звуков (или музыки) из файлов в формате .ogg, а также показ рядом с FPS текущего разрешения экрана и переключение между оконным/полноэкранным режимом по клавише [U]. Для пояснения того, как сделать игру правильно отображаемой и в полноэкранном режиме демострирую небольшое видео. Посмотрев его вы сможете сделать игру, отображаемую во весь экран с заполнением всего доступного пространства. Проект со всеми необходимыми файлами для открытия из редактора godot 3.4.2.stable вы найдете в папке \examples\chapter_5\music\ Далее - Глава 6 - экран настроек игры (статья скоро будет опубликована на сайте)
оцените статью:
0
Понравилось!
0
Не понравилось!
 

Оставленные комментарии


megainformatic 2006 - 2024 карта сайта




Посетили страницу: 119