Мобильный геймпад на Godot. Кнопки. Часть 1
Введение
Итак, это мой небольшой... Да на самом деле довольно большой! Рассказ как я делал из своего телефона контроллер. Небольшая предыстория. Решил я сыграть в Broforce с друзьями и тут понял, что если я притащу свой ноутбук с игрой, то поиграть с комфортом мы не сможем - нет столько контроллеров. В mvideo геймпады для xbox или ps стоили около 5 тысяч рублей. Можно было и китайские купить, которые обещали нормально работать при подключение к компьютеру, но... Но отсутствие доверия к качеству и жалось не то что к 5 тысяч, а к 700 рублям удавили возможность покупки на корню. И тут мы задумались, а можно ли сделать собственный мобильный контроллер. Конечно же мы нашли готовые проекты в google play, но они шли с вшитой рекламой и могли начать портить игровой процесс в самый неудобный момент. Так родился интересный проект для реализации. Был ли у меня опыт с Godot? Нет. Разработчик или хотя бы хоть сколько-то программист? Нет. Удивительно, что можно сделать при беспардонном упорстве и наличии гугла. Проект я в итоге сделал. Потом забил на него. А недавно вспомнил! И решил переделать :) Эта и все последующие статьи как раз пересказ процесса ПЕРЕСОЗДАНИЯ мобильного контроллера. Кусочек результата старого проекта ниже:

Зачем вообще переделывать, а не дорабатывать готовое? Я решил серьезно углубиться в Godot и реально сделать свой проект, игру. Ту в которую я бы хотел сыграть. Все же гнаться за мечтой, даже детской, это несколько романтично, возвышено и тупо. Меня устраивает. Старый контроллер имел серьезные проблемы в самой своей базе. Так же его переработка хороший способ убить сразу несколько зайцев. Структура проекта "Контроллер" осталась старой.
Сервер на Python - принимает подключение телефона, получает нажатия и передает их драйверу ViGEmBus. Сервер поддерживает подключение до 4ех человек;
Контроллер на Godot (далее по тексту клиент) - подключается к серверу, передает ему нажатия. Для хобби-прототипа сильно париться не хотелось. У клиента всего 2 сцены - настройки и сам контроллер;
ViGEmBus - драйвер для эмуляции виртуальных игровых контроллеров в операционных системах Windows. К сожалению, поддержка этого чуда прекратилась, и что будет теперь, мне не ясно. Скорее всего рано или поздно настанет момент, когда драйвер перестанет быть совместим с играми или новой версией ОС. Но пока что наслаждаемся.
Чертовы кнопки
Бесплатные картинки для кнопок взял с https://itch.io/game-assets/free/tag-gamepad. Набор приличный, на любой вкус. Со стиками было проще всего - не стал создавать велосипед и загрузил Virtual Joystick от MarcoFazio через AssetLib. А вот кнопки делал через узел TouchScreenButton - в документации Godot этот узел как раз предназначен для обработки на сенсорных устройствах. Загрузил текстуры для кнопок ииии... И границы текстур оказались слегка больше, чем ожидалось.
К стикам это не относится, так как они созданы через другую сущность Control. Пока не забивайте этим голову.
В общем Godot правильно определяет границы - я ведь не обрезал прозрачные лишние части. Вроде и черт с ним, но ведь нажатия будут обрабатываться неправильно - в местах пересечений будет срабатывать несколько кнопок. Вариантов была два (по крайней мере о которых я прочитал):
Обрезать кнопки в редакторе убирая пустоты;
Забить на TouchScreenButton и создавать области вручную через Area2D и CollisionShape2D.
Будучи здравомыслящим(?) человеком, я выбрал второй вариант. Чтоб больше страданий было, хех. Если пошагово, то создавалось все это дело следующим образом:
Для 4ех левых кнопок был создан отдельный узел Node2D (CrossButtons1);
Для каждой кнопки создан узел Area2D (UpArea);
Для Area2D были созданы Sprite2D (UPsprite) - отображение кнопки, и CollisionShape2D (для него я уже поленился название выдумывать) - зона обработки нажатия.
Для узла CrossButtons1, в который входят кнопки, добавляем скрипт со следующим текстом:
зашел сюда по быстрому сделать кнопку? Хотел скопировать текст, а тут картинка? Уж прости, картинка красивее текста выглядела.
Строка 4 нужна для привязки функции обработки нажатия к нашей области Area2D (UpArea). Строки 8 и 10 ловят нажатие и отпускание кнопки.
Это все супер, но как будто лень писать подобный код для каждой новой кнопки. Благо, действительно есть способ попроще.
Пробегаемся по всем подузлам нашего Node2D (CrossButtons1), находим те, что принадлежат типу Area2D и подключаемся функцию _on_button_input для обработки всех кнопок в Node2D. Для нашей задачи главное понимать, какая кнопка была нажата - получаем через button.name.
Замечательно, но что если мы хотим, чтобы картинка кнопки менялась при нажатии? Вышеописанные методы уже не сработают, придется работать с каждым Area2D узлом отдельно. В целом ничего страшного. Делаем все те же шаги, что раньше, но создаем скрипт для узла Area2D. В него грузим картинки состояний.
Код +- тот же, но добавляем:
Строка 7 - начальное состояние/начальная картинка;
Строки 12 и 15 для переключения состояния/картинки при обработке нажатия.
Заключение
Все что осталось - томная работа по повторению процесса для создания всех нужных кнопок. В следующей части добавлю новую сцену, ввод текста и сохранение данных в json формате. И немного работы сети. У-о-о-т. Спасибо за чтение. Дельные замечания и советы приветствуются, ибо в плане создания подобного я ещё профан.
Лига программистов
2K постов11.8K подписчиков
Правила сообщества
- Будьте взаимовежливы, аргументируйте критику
- Приветствуются любые посты по тематике программирования
- Если ваш пост содержит ссылки на внешние ресурсы - он должен быть самодостаточным. Вариации на тему "далее читайте в моей телеге" будут удаляться из сообщества