● Примерно так выглядит сбор "деталей" для создания модельки в "Dragon Bones".
Из более сотни вариантов выбираются самые удачные части тела и вырезаются для дальнейшего использования в конструкторе.
Нейросеть Stable Diffusion хорошо прорисовывает тени, детали одежды и в половине случаев даже лица получаются более-менее адекватными. Но есть проблема - руки и в особенности пальцы.
Любой кто пытался сгенерировать изображение с руками сталкивается с кучей артефактов. Кривые, непропорциональные и иногда лишние культяпки. В среднем лишь 1 из 100 вариантов более-менее удовлетворяет запросу.
● Как это исправить?
Можно просто добавить в запрос "detailed fingers" и без конца мучать нейросеть в ожидании чуда. Но куда проще взять "ситуацию с руками" в свои руки. Я владею Photoshop на базовом уровне, но даже таких знаний хватает, чтобы исправить косяки робота.
Я отобрал модельки с менее уродливой правой рукой (та где видно пальцы). Именно с ней связанно больше всего косяков. С помощью графического редактора я удалил лишнее и дорисовал недостающее. В основном применялся "Штамп". Цветовая палитра копируется пипеткой, обводка при помощи кисти.
▸ Эволюция руки
Таким образом вместо соотношения 1/100 удачных, мы получаем уже 5-10/100, что делает работу с нейросетью более продуктивной. Да, программа не нарисует все за вас, придется научиться хотя бы редактировать графические элементы. Но это уже в половину проще чем рисовать все с нуля.
Продолжаю изучать нейросети как инструмент в разработке игр. Подписывайся на мой гоблинский блог, впереди еще больше интересного!
Данные персонажи создаются через нейронку Stable Diffusion. Использовал инструменты с сайта OpenArt. За основу взят вот этот товарищ:
Пока что экспериментирую, собираю получившиеся варианты. В дальнейшем буду вырезать понравившиеся детали и как в конструкторе собирать новые образы для анимации в Dragon Bones.
Вот уже два месяца я пишу статьи связанные с темой разработки игр, а так же делаю гайды по Godot Engine от лица новичка. В первую очередь делаю это для себя, так как перед написанием приходится глубже разобраться в материале, да и в комментах более опытные пользователи помогают исправить ошибки.
● Но вот уже не первый раз натыкаюсь на мнение мол "ты новичок - не лезь".
▸ Коммент под последней статьей на Пикабу
И вот с одной стороны чувак прав, чего это мне зеленому кодеру с костылями учить других. А с другой... я и не то что бы учу. Почти каждый пост я начинаю с предупреждения - текст написан новичком и является попыткой разобраться в теме. Мне просто нравится копаться в разработке и рассказывать о своем прогрессе.
▸ Дисклеймер
● Теперь нахожусь в раздумьях, какой дальше делать контент.
По одну сторону барикад опытные ребята, которые говорят что я делаю мусорные статьи и они никому неинтересны. Сиди учи матчасть, а уже потом имея за плечами хотя бы одну игру на релизе раздавай советы.
По другую же сторону новички, которые все чаще пишут комменты под моими постами и интересуются движком. Некоторые даже начали учить GD-Script по моим статьям, возможно ввиду малого количества русскоязычного контента по Godot Engine.
● Может кто-то сталкивался с подобной делемой? Поделитесь мнение в комментах!
Этот интересный факт о Python напрямую связан с предыдущим. На эмблеме Python изображены как раз таки змеи. Пресмыкающиеся образуют квадрат.
Составил лого брат Гвидо, дизайнер Юст ван Россум. Шрифт текста тоже изобрел он.
До 2006 года логотип Питона был текстовым. Но кобры всевозможных видов в книгах, журналах и на сайтах про Python подтолкнули к смене лого во избежание путаницы.
Интересный факт про Python заключается в том, что это один из самых популярных языков программирования в мире. Он был создан 90-х годах прошлого века Гвидо ван Россумом и с тех пор стал одним из наиболее распространенных языков программирования.
1. "Python Crash Course" Эрика Мэтиза — это книга для начинающих, которая поможет вам освоить основы языка Python и научиться создавать простые программы.
2. "The Pragmatic Programmer" Эндрю Хант и Дэвид Томас — это книга о том, как стать успешным программистом, используя принципы Agile-разработки.
3. "Python for Data Analysis" Роберт Лафоре — это книга о том, как использовать язык программирования Python для анализа данных и создания приложений для работы с большими объемами информации.
1. Используйте переменные вместо констант. Константы — это значения, которые определены один раз и не могут быть изменены. В то время как переменные могут быть изменены в любой момент времени.
2. Используйте циклы для повторения кода много раз. Цикл позволяет повторять код до тех пор, пока он не будет выполнен полностью.
3. Используйте условные операторы для проверки условий и выполнения действий в зависимости от результата. Например, если вы хотите найти все четные числа в списке, вы можете использовать оператор if.
Для тех кто первый раз читает мой гоблинский блог - расскажу кратко что тут происходит. Я сам являюсь зеленым новичком в разработке игр и в своем блоге описываю этапы изучения столь сложного дела. На данный момент - это работа с движком Godot 4.
Чтобы не мучать вас длинными статьями, я разбиваю этот путь на кучу мелких блоков. Один пост - одна механика движка. Все гоблинские заумные слова расшифровываются на человеческий, так что даже пациент из Кащенко поймет о чем речь. Погнали!
● Создание сцены с персонажем:
В прошлой статье мы создали редактор карт с автоматическим заполнением, кто не читал - почитайте, будет полезно. Теперь нам нужно сделать персонажа, которым мы будем бегать по данной карте. Для этого нам нужен узел типа "CharacterBody2D", на основе которого мы и создаем новую сцену. Сделать это можно выбрав вкладку "Другой узел".
Как выглядит узел "CharacterBody2D"
● Визуальное изображение персонажа:
Узел это конечно хорошо, но мы пока ни черта не видим - нам нужен визуальный образ. Добавляем дочерний узел "Sprite2D". В его настройках находим вкладку текстуры и добавляем иконку Godot. В будущем мы заменим спрайт на анимацию, но пока нам хватит такой затычки.
Узел "Sprite" -> Texture -> Быстро загрузить
● Настройка зоны столкновения:
Чтобы наш персонаж не проваливался в текстуры и реагировал на поверхности мы должны настроить зоны столкновения. В прошлом уроке мы работали со слоем Collision в нашем TileMap. Тут же мы добавляем узел "CollisionShape2D", который представляет из себя выделение зоны столкновения в виде простой геометрической фигуры. Вид этой фигуры мы выбираем во вкладке "Shape".
Узел "CollisionShape2D" -> Shape -> Новый RectangleShape2D
● Начальные данные для физики и управления:
Создаем скрипт для нашей сцены и первым делом зададим константы. Константа - это постоянное значение, которое не будет меняться в ходе работы программы.
Чтобы создать константу мы пишем: const название_константы = значение
Переменные же создаются по другому: var название_переменной = значение
Давайте разберемся за что отвечают указанные нами значения:
speed и acceleration - от этих значений будет зависеть скорость передвижения по оси X (влево-вправо)
jump_velocity - это значение влияющее на высоту прыжка. Ось Y в Godot перевернута с ног на голову и отрицательное значение означает вверх.
friction - значение влияющее на скорость остановки при прекращении передвижения.
Так выглядят наши константы в коде
Так же мы добавляем значение гравитации, однако оно выставляется из внутренних настроек проекта.
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
● Общая функция для управления персонажем:
Задав исходные данные мы можем приступать к настройкам функций нашего персонажа. Для этого мы пишем стандартную функцию Godot:
func _physics_process(delta):
Для тех кто не знает - эта функция вызывается перед каждым физическим кадром, который привязан к физическому fps, он по умолчанию равен 60 раз в секунду.
var input_axis = Input.get_axis("ui_left","ui_right")
Get_axis - это функция которая присваивает переменной одно из двух значений при нажатии одной из двух кнопок. Первое значение равно -1 и задается при нажатии клавиши "влево". Второе же равно 1 и задается при нажатии клавиши "вправо". Если на момент кадра не нажата ни одна из этих кнопок, значение равно 0. Это позволяет нам определить нужное направление для изменения координат персонажа.
Влево = -1 | Вправо = 1 | Стоим на месте = 0
● Движение по оси X (влево-вправо), создаем новую функцию:
handle_acceleration (input_axis, delta)
В нее мы добавляем условие, что должна быть нажата одна из клавиш - влево или вправо.
if input_axis !=0:
Если данное условие выполнено, то мы совершаем перемещение в заданном направлении. Для этого используется функция move_toward.
velocity.x - это переменная отвечающая за перемещение по оси X.
В move_toward мы задаем три параметра через запятую. Изначальная точка, точка в которую мы должны прийти, шаг в сторону нужной точки за один кадр.
Каждый кадр мы двигаемся в выбранную сторону, начальная точка меняется и это создает замкнутый круг движения. А чтобы его запустить, мы добавляем нашу функцию под physics_process и в конце пишем move_and_slide().
move_toward ( начальная точка, точка прибытия, расстояние шага за один кадр )
▸ А где тормоза то !?
● Как сделать остановку?
Мы начали двигаться и если не нажмем кнопку в противоположную сторону - улетим за край карты. Чтобы разорвать наш круг постоянного движения мы должны сделать функцию тормоза.
Копируем нашу прошлую функцию и переименовываем ее:
handle_friction (input_axis, delta):
Так же меняем заданное условие, input_axis должен быть равен нулю. Главное помнить, что знак равенства при сравнении выглядит вот так "==".
if input_axis == 0:
В функции move_toward заменяем значения. Первое остается прежним, на втором ставим ноль, а на третьем стираем acceleration и пишем friction. Все это в сумме обеспечит нам быструю остановку.
Функции обратные друг другу
● Движение по оси Y (прыжок, гравитация), создаем новую функцию:
aplay_gravity(delta):
Если мы не на земле, то бишь в воздухе - нас должно тянуть вниз.
if not is_on_floor():
velocity.y += gravity * delta
Ставим именно "+=", так как это сделает плавное падение с нарастающим ускорением. Не забудьте умножить на delta, иначе все произойдет за долю секонды.
● Следующая функция для прыжка:
handle_jump(delta):
Для нас важны два условия - нахождение на земле в момент прыжка и нажатие нужной клавиши.
if is_on_floor() and Input.is_action_just_pressed("ui_accept"):
Если данное условие соблюдено мы приравниваем параметр оси Y к значению высоты прыжка.
velocity.y = jump_velocity
Добавляем эти функции под physics_process, а после переходим на сцену "world". Туда из общего списка ресурсов перетаскиваем сцену "player".
.tscn - это формат сцены в Godot
Как выглядит наш блок с функциями
● Что у нас получилось в итоге?
✓ Если вы нажимаем клавишу влево или вправо - персонаж двигается в выбранном направлении.
✓ Если ни одна из клавиш направления не нажата - мы останавливаемся.
✓ Если мы находимся в воздухе - нас тянет вниз с каждой секундой все сильнее.
✓ Если находясь на земле, мы жмем прыжок - нас подкинет вверх.
▸ Оно живое!
Вот так при помощи четырех простых функций мы создали основу физики и управление персонажем. Надеюсь разобрал каждый шаг максимально подробно и понятно.
✓ Зеленые новички - крепитесь и подписывайтесь, скоро новая статья. На очереди две темы - "анимация персонажа" или "двойные прыжки и прыжки от стены".
✓ Опытные шаманы - запасайтесь успокоительным, ибо дальше будет еще куча попыток освоить gamedev.
✓ Ну и все кто имеет свое мнение, поддержку или усмешку - пишите комменты!
Взять с собой побольше вкусняшек, запасное колесо и знак аварийной остановки. А что сделать еще — посмотрите в нашем чек-листе. Бонусом — маршруты для отдыха, которые можно проехать даже в плохую погоду.