"NightFall" _ Получение психоза "Паранойя"
Срабатывает при критическом падении духа и заходе в "жуткую область".
Группа игры: https://vk.com/nightfall_project
Ищу ребят в команду
в общем я делаю свою игру и хочу найти ребят в свою команду так как одному будет сложно работать, СРАЗУ скажу зарплаты не будет! деньги будем получать (если вообще будем) с донатов в вк и скачиваний игры
В КОМАНДУ НУЖНЫ:
программист 1 или 2
2д художник окружения
2д художник персонажей
и один 3д моделлер
вк студии:https://vk.com/club222708923
вк игры: https://vk.com/club222708136
Forest Spirit - моя первая игра в Steam
Хочу представить вам свою первую игру в Steam, скоро она выйдет в Ранний Доступ. До этого я делал и другие игры, но Forest Spirit больше, чем все мои прошлые проекты.
Вы, обычный городской житель, селитесь на пустом клочке земли.
Вам предстоит отстроить свою ферму. Для этого нужно добывать ресурсы. Все постройки на ферме, оружие, доспехи и многое другое нужно крафитить из добытых ресурсов. Постепенно вы будете создавать все более сложные вещи.
Некоторые из ресурсов находятся неподалеку, а чтобы добыть другие, вам придется столкнуться с опасными монстрами.
А монстров в этой местности много разных. Возможно, это как-то связано с огромным заводом и загрязненной окружающей средой (кто знает?). Некоторые монстры не представляют большой угрозы, а другие довольно опасны и к битве с ними придется подготовиться.
Местные жители помогут вам обосноваться на новом месте. Эти люди знают, как тут все устроено. За некоторую помощь они поделятся с вами своими секретами.
Когда будет время вы можете отправиться на реку или море с удочкой. В воде водится разнообразная рыба и многое другое.
На вашей ферме вы сможете выращивать различные овощи и фрукты, а если заведете животных, то сможете получать полезные продукты еще и с них. Из выращенных и собранных вами продуктов можно будет приготовить различные блюда.
Думаю, многие понимают какими играми я вдохновлялся, делая Forest Spirit:) Разработку я начал в 2021 году, а желание сделать подобную игру у меня было еще до того, как я попал в игровую индустрию.
Как это часто бывает с разработчиками, я сильно недооценил время нужное для разработки такой игры. И даже сейчас в игру нужно добавить много дилогов, событий, квестов и предметов. Все инструменты для добавления этого контента готовы и я планирую постепенно наполнять игру.
Если вас заинтересовала игра, то вы можете найти ее в Steam:
Страшная тётенька или Yezinka
Немножко страшненького! Му-ха-ха-ха!
Портрет одного из монстров - Yezinka, который обитает в постапокалиптической вселенной NEO Scavenger.
Создавался для настольной ролевой игры ~☆
"...чрезвычайно крупный гуманоид с удлинёнными руками и туловищем. Езинка одержима преследованием гуманоидов ради их глаз. Чтобы удовлетворить эту потребность, она попытается устроить засаду на игрока ночью, пока он спит."
~ NEO Scavenger wiki
Когда-то, один мой предприимчивый товарищ связался с создателем этой игры для того, чтобы получить доступ и разрешение на использование всяких внутриигровых материалов и иметь возможность использовать их в разработке адаптации этой игры под настольную ролевую игру. Это было очень интересно, мне посчастливилось принимать участие в тестировании, а именно - быть одним из игроков самой первой сессии и активно участвовать в разработке этого проекта!
Безмерно вдохновляющий проект, который давал мне возможность воплотить самые причудливые и необычные идеи, а также ̶т̶в̶о̶р̶и̶т̶ь̶ ̶в̶с̶я̶к̶у̶ю̶ ̶н̶е̶с̶у̶с̶в̶е̶т̶и̶ц̶у̶ создавать интересные ситуации для всей игровой команды!
Тогда родилась моя Мисти, мрачная черноволосая девушка с французскими корнями. Со своей долгой и непростой историей, ставшая жертвой причудливых видений и мистики(ха-ха), которая вязким туманом окутывала её сознание... Но это уже другая история, которую я расскажу позже (¬‿¬ )
Внимание! Бесплатный фулл(8k!!!) моей предыдущей работы можно найти тут — https://boosty.to/sonyanneya
Если вам нравятся мои работы, пожалуйста, заглядывайте в мою маленькую группу в ВК — https://vk.com/sonyanneya
https://sonyanneya.carrd.co/ — здесь вы можете найти другие ссылки.
Сам написал, сам поиграл: Как я написал 2D-игру для Android полностью с нуля, весом менее 1мб?
Многие программисты так или иначе имеют тягу и интерес к разработке игр. Немалое количество спецов было замечено за написанием маленьких и миленьких игрушек, которые были разработаны за короткое время «just for fun». Большинству разработчиков за счастье взять готовый игровой движок по типу Unity/UE и попытаться создать что-то своё с их помощью, особенно упорные изучают и пытаются что-то сделать в экзотических движках типа Godot/Urho, а совсем прожжённые ребята любят писать игрушки… с нуля. Таковым любителем писать все сам оказался и я. И в один день мне просто захотелось написать что-нибудь прикольное, мобильное и обязательно — двадэшное! В этой статье вы узнаете про: написание производительного 2D-рендерера с нуля на базе OpenGL ES, обработку «сырого» ввода в мобильных играх, организацию архитектуры и игровой логики и адаптация игры под любые устройства. Интересно? Тогда жду вас в статье!
❯ Как это работает?
Конечно же разработка собственных игр с нуля — это довольно веселое и увлекательное занятие само по себе. Ведь удовольствие получает не только пользователь, который играет в уже готовую игру, но и её разработчик в процессе реализации своего проекта. В геймдеве есть множество различных и интересных задач, в том числе — и для программиста.
Один из прошлых проектов — 3D шутэмап под… коммуникаторы с Windows Mobile без видеоускорителей! Игра отлично работала и на HTC Gene, и на QTek S110!
В больших студиях принято всю нагрузку распределять на целые команды разработчиков. Артовики занимаются графикой, звуковики — музыкой и звуковыми эффектами, геймдизайнеры — продумывают мир и геймплей будущей игры, а программисты — воплощают всё это в жизнь. Однако, за последние 20 лет появилось довольно большое количествобесплатныхинструментов, благодаря которым маленькие команды или даже разработчики-одиночки могут разрабатывать собственные игры сами!
Подобные инструменты включают в себя как довольно функциональныеконструкторы игр, которые обычно не требуют серьёзных навыков программирования и позволяют собирать игру из логических блоков, так и полноценных игровых движков на манер Unity или Unreal Engine, которые позволяют разработчикам писать игры и продумывать их архитектуру самим. Можно сказать что именно «благодаря» доступности подобных инструментов мы можем видеть текущую ситуацию на рынке мобильных игр, где балом правят очень простые и маленькие донатные игрушки, называемыегиперкежуалом.
Но у подобных инструментов есть несколько минусов, которые банально не позволяют их использовать в реализации некоторых проектов:
Большой вес приложения: При сборке, Unity и UE создают достаточно объёмные пакеты из-за большого количества зависимостей. Таким образом, даже пустой проект может спокойно весить 50-100 мегабайт.
Неоптимальная производительность: И у Unity, и у UE очень комплексные и сложные рендереры «под капотом». Если сейчас купить дешевый смартфон за 3-4 тысячи рублей и попытаться на него накатить какой-нибудь 3 в ряд, то нас ждут либо вылеты, либо дикие тормоза.
Лично я для себя приметил ещё один минус — невозможность деплоить игры на устройства с старыми версиями Android, но это, опять же, моя личная хотелка.
Поэтому когда мне в голову пришла мысль сделать игрушку, я решил написать её с нуля — не используя никаких готовых движков, а реализовав всё сам — и игровую логику, и сам «движок» (правильнее сказать фреймворк). Не сказать, что в этом есть что-то очень сложное — в геймдеве есть отдельная каста «отшельников», которые называют себя «движкописателями» и пишут либо движки, либо игры — правда, не всегда хотя-бы одна игра доходит до релиза.
❯ Определяемся с задачами
Перед тем, как садится и пилить игрушку, нужно сразу же определится с целями и поставить перед собой задачи — какой стек технологий мы будет использовать, как будем организовать игровую логику, на каких устройствах игра должна работать и.т.п. Я прикинул и решил реализовать что-то совсем несложное, но при этом достаточно динамичное и забавное… 2D-шутер с видом сверху!
Игра будет написана полностью на Java — родном языке для Android-приложений. Пустые пакеты без зависимостей весят всего около 20 килобайт — что только нам на руку! Ни AppCompat, ни какие либо ещё библиотеки мы использовать не будем — нам нужен минимальный размер из возможных!
Итак, что должно быть в нашей игре:
Основная суть: Вид сверху, человечком по центру экрана можно управлять и стрелять во вражин. Цель заключается в том, чтобы набрать как можно больше очков перед тем, как игрока загрызут. За каждого поверженного врага начисляются баксы, за которые можно купить новые пушки!
Оружие: Несколько видов вооружения, в том числе пистолеты, дробовики, автоматы и даже пулеметы! Всё оружие можно купить в внутриигровом магазине за валюту, которую игрок заработал во время игры
Враги: Два типа врагов — обычный зомби и «шустрик». Враги спавнятся в заранее предусмотренных точках и начинают идти (или бежать) в сторону игрока с целью побить его.
Уровни: Можно сказать, простые декорации — на момент написания статьи без какого либо интерактива.
Поскольку игра пишется с нуля, необходимо сразу продумать необходимые для реализации модули:
Графика: Аппаратно-ускоренный рендерер полупрозрачных 2D-спрайтов с возможность аффинных трансформаций (поворот/масштаб/искривление и.т.п). На мобильных устройствах нужно поддерживать число DIP'ов (вызовов отрисовки) как можно ниже — для этого используется техника батчинга. Сам рендерер работает на базе OpenGLES 1.1 — т.е чистый FFP.
Ввод: Обработка тачскрина и геймпадов. Оба способа ввода очень легко реализовать на Android — для тачскрина нам достаточно повесить onTouchListener на окно нашей игры, а для обработки кнопок — ловить события onKeyListener и сопоставлять коды кнопок с кнопками нашего виртуального геймпада.
Звук: Воспроизведение как «маленьких» звуков, которые можно загрузить целиком в память (выстрелы, звуки шагов и… т.п), так и музыки/эмбиента, которые нужно стримить из физического носителя. Тут практически всю работу делает за нас сам Android, для звуков есть класс — SoundPool (который, тем не менее, не умеет сообщать о статусе проигрывания звука), для музыки — MediaPlayer. Есть возможность проигрывать PCM-сэмплы напрямую, чем я и воспользовался изначально, но с ним есть проблемы.
«Физика»: Я не зря взял этот пункт в кавычки :) По сути, вся физика у нас — это один метод для определения AABB (пересечения прямоугольник с прямоугольником). Всё, ни о какой настоящей физике и речи не идет :)
Поэтому, с учетом требований описанных выше, наша игра будет работать практически на любых смартфонах/планшетах/тв-приставках кроме китайских смартфонов на базе чипсета MT6516 без GPU из 2010-2011 годов. На всех остальных устройствах, включая самый первый Android-смартфон, игра должна работать без проблем. А вот и парк устройств, на которых мы будем тестировать нашу игру:
С целями определились, самое время переходить к практической реализации игры! По сути, её разработка заняла у меня около дву-трех дней — это с учетом написания фреймворка. Но и сама игра совсем несложная :)
❯ Рендерер
Начинаем, мы конечно же, с инициализации контекста GLES и продумывания архитектуры нашего будущего фреймворка. Я всегда ставил рендерер на первое место, поскольку реализация остальных модулей не особо сложная и их можно дописать прямо в процессе разработки игры.
По сути, в современном мире, 2D — это частный случай 3D, когда рисуются всё те же примитивы в виде треугольников, но вместо перспективной матрицы, используется ортографическая матрица определенных размеров. Во времена актуальности DirectDraw (середина-конец 90х) и Java-телефонов, графику обычно не делали адаптивной, из-за чего при смене разрешения, игровое поле могло растягиваться на всю площадь дисплея. Сейчас же, когда разброс разрешений стал колоссальным, чаще всего можно встретить два подхода к организацию проекции:
Установка ортографической матрицы в фиксированные размеры: Если координатная система уже была завязана на пиксели, или по какой-то причине хочется использовать именно её, то можно просто завязать игру на определенном разрешении (например, 480x320, или 480x800). Растеризатор формально не оперирует с пикселями — у него есть нормализованные координаты -1..1 (где -1 — начало экрана, 0 — середина, 1 — конец, это называется clip-space), а матрица проекции как раз и переводит координаты геометрии в camera-space координатах в clip-space — т.е в нашем случае, автоматически подгоняет размеры спрайтов из желаемого нами размера в физический. Обратите внимание, физические движки обычно рассчитаны на работу в метрических координатных системах. Попытки задавать ускорения в пикселях вызывают рывки и баги.
Перевод координатной системы с пиксельной на метрическую/абстрактную:
Сейчас этот способ используется чаще всего, поскольку именно его используют самые популярные движки и фреймворки. Если говорить совсем просто — то мы задаем координаты объектов и их размеры не относительно пикселей, а относительно размеров этих объектов в метрах, или ещё какой-либо абстрактной системы координат. Этот подход близок к обычной 3D-графике и имеет свои плюшки: например, можно выпустить HD-пак для вашей игры и заменить все спрайты на варианты с более высоким разрешением, не переделывая половину игры.
Для совсем простых игр я выбираю обычно первый подход. Самое время реализовать главный метод всего рендерера — рисование спрайтов. В моём случае, спрайты не были упакованы в атласы (одна текстура, содержащая в себе целую анимацию или ещё что-то в этом духе), поэтому и возможность выборки тайла из текстуры я реализовывать не стал. В остальном, всё стандартно:
Всё более чем понятно — преобразуем координаты спрайта из world-space в camera-space, отсекаем спрайт, если он находится за пределами экрана, задаем стейты для GAPI (на данный момент, их всего два), заполняем вершинный буфер геометрией и рисуем на экран. Никакого смысла использовать VBO здесь нет, а на nio-буфферы можно получить прямой указатель без лишних копирований, так что никаких проблем с производительностью не будет. Обратите внимание — вершинный буфер выделяется заранее — аллокации каждый дравколл нам не нужны и вредны.
Обратите внимание на вызовы ByteBuffer.order — это важно, по умолчанию, Java создаёт все буферы в BIG_ENDIAN, в то время как большинство Android-устройств — LITTLE_ENDIAN, из-за этого можно запросто накосячить и долго думать «а почему у меня буферы заполнены правильно, но геометрии на экране нет!?».
В процессе разработки игры, при отрисовке относительно небольшой карты с большим количеством тайлов, количество вызовов отрисовки возросло аж до 600, из-за чего FPS в игре очень сильно просел. Связано это с тем, что на старых мобильных GPU каждый вызов отрисовки означал пересылку состояния сцены видеочипу, из-за чего мы получали лаги. Фиксится это довольно просто: реализацией батчинга — специальной техники, которая «сшивает» большое количество спрайтов с одной текстурой в один и позволяет отрисовать хоть 1000, хоть 100000 спрайтов в один проход! Есть два вида батчинга, статический — когда объекты «сшиваются» при загрузке карты/в процессе компиляции игры (привет Unity) и динамический — когда объекты сшиваются прямо на лету (тоже привет Unity). На более современных мобильных GPU с поддержкой GLES 3.0 есть также инстансинг — схожая технология, но реализуемая прямо на GPU. Суть её в том, что мы передаём в шейдер параметры объектов, которые мы хотим отрисовать (матрицу, настройки материала и.т.п) и просим видеочип отрисовать одну и ту же геометрию, допустим, 15 раз. Каждая итерация отрисовки геометрии будет увеличивать счетчик gl_InstanceID на один, благодаря чему мы сможем расставить все модельки на свои места! Но тут уж справедливости ради стоит сказать, что в D3D10+ можно вообще стейты передавать на видеокарту «пачками», что здорово снижает оверхед одного вызова отрисовки.
Для загрузки спрайтов используется встроенный в Android декодер изображений. Он умеет работать в нескольких режимах (ARGB/RGB565 и.т.п), декодировать кучу форматов — в том числе и jpeg, что положительно скажется на финальном размере игры.
На этом реализация рендерера закончена. Да, все вот так просто :)
Переходим к двум остальным модулям — звук и ввод.
❯ Звук и ввод
Как я уже говорил, звук я решитл реализовать на базе уже существующей звуковой подсистемы Android. Ничего сложного в её реализацир нет, можно сказать, нам остаётся лишь написать обёртку, необходимую для работы. Изначально я написал собственный загрузчик wav-файлов и хотел использовать AudioTrack — класс для воспрозизведения PCM-звука напрямую, но мне не понравилось, что в нём нет разделения на источники звука и буферы, из-за чего каждый источник вынужден заниматься копированием PCM-потока в новый и новый буфер…
Полная реализация звукового потока выглядит так. И да, с SoundPool нет возможности получить позицию проигрывания звука или узнать, когда проигрывание закончилось. Увы.
Да будет звук! Ну и про ввод не забываем (листинг получился слишком длинный, а на Пикабу нет тега для кода - так что как-то так):
Сама реализация джойстика крайне простая — запоминаем координаты, куда пользователь поставил палец и затем считаем дистанцию положения пальца относительно центральной точки, параллельно нормализововая их относительно максимальной дистанции:
Кроме того, я добавил вспомогательный метод для вызова диалога ввода текста — это для таблицы рекордов и прочих фишек, которые требуют ввода текста пользователем. Ну не будем же мы сами клавиатуру костылить!
Основа для игры есть, теперь переходим к её реализации!
❯ Пишем игру
Писать игру я начал с создания первого уровня и реализации загрузчика уровней. В качестве редактора, я выбрал популярный и широко-известный TileEd — удобный редактор с возможностью экспорта карт в несколько разных форматов. Я лично выбрал Json, поскольку в Android уже есть удобный пакет для работы с этим форматом данных.
Карта делится на 3 базовые понятия: тайлы — фон, с изображением травы/асфальта/земли и.т.п, пропы — статичные объекты по типу деревьев и кустов и сущности — объекты, участвующие в игровом процессе, т.е игрок, зомби и летящие пули. Система сущностей реализована в виде абстрактного базового класса, который реализовывает логику апдейтов, просчитывает Forward-вектор и выполняет другие необходимые задачи:
После этого, я приступил к реализации игрока, оружия и механики стрельбы. В целом, практически всю логику игрока можно описать в виде одного метода update: обрабатываем ввод и ходьбу с джойстика, поворачиваем игрока в сторону пальца на экране и пока зажата какая-либо область на экране мы ходим и стреляем:
Ну и не забываем про реализацию зомби. Она тоже очень простая: есть базовый класс Zombie, от которого наследуются все монстры и который реализует несколько необходимых методов — повернуться в сторону игрока, идти вперед и конечно же атака!
❯ Что у нас есть на данный момент?
Честно сказать, статья итак уже получилась слишком длинной. Я очень хотел написать игру, о разработке которой можно было бы рассказать в рамках одной не особо большой статьи, но с моим стилем написания текстов так сделать не выйдет. Придется разбивать на части!
Однако, некоторый прогресс уже есть и мы можем даже поиграть в игру на текущем ее этапе!
Как мы видим, игра (а пока что — proof of concept) работает довольно неплохо на всех устройствах, которые были выбраны для тестирования. Однако это ещё не всё — предстоит добавить конечную цель игры (набор очков), магазин стволов и разные типы мобов. Благо, это всё реализовать уже совсем несложно :)
❯ Заключение
Написать небольшую игрушку с нуля в одиночку вполне реально. Разработка достаточно больших проектов конечно же требует довольно больших человекочасов, однако реализовать что-то своё, маленькое может и самому!
Пишите своё мнение в комментариях. Если вам вдруг интересна тематика самопальной разработки игр, то постараюсь выпускать подобные статьи почаще!
Статья подготовлена при поддержке компании TimeWeb Cloud. Подписывайтесь на меня и @Timeweb.Cloud, чтобы не пропускать новые статьи каждую неделю!
Но тут я даже чутка навру - на этой неделе вас ждёт сразу две статьи :) Следующая - в четверг, прошлую неделю я отдыхал и работал.
Нейросети - это буквально "руки из ж*пы". Как решить проблему лишних пальцев и конечностей?
● Примерно так выглядит сбор "деталей" для создания модельки в "Dragon Bones".
Из более сотни вариантов выбираются самые удачные части тела и вырезаются для дальнейшего использования в конструкторе.
Нейросеть Stable Diffusion хорошо прорисовывает тени, детали одежды и в половине случаев даже лица получаются более-менее адекватными. Но есть проблема - руки и в особенности пальцы.
Любой кто пытался сгенерировать изображение с руками сталкивается с кучей артефактов. Кривые, непропорциональные и иногда лишние культяпки. В среднем лишь 1 из 100 вариантов более-менее удовлетворяет запросу.
● Как это исправить?
Можно просто добавить в запрос "detailed fingers" и без конца мучать нейросеть в ожидании чуда. Но куда проще взять "ситуацию с руками" в свои руки. Я владею Photoshop на базовом уровне, но даже таких знаний хватает, чтобы исправить косяки робота.
Я отобрал модельки с менее уродливой правой рукой (та где видно пальцы). Именно с ней связанно больше всего косяков. С помощью графического редактора я удалил лишнее и дорисовал недостающее. В основном применялся "Штамп". Цветовая палитра копируется пипеткой, обводка при помощи кисти.
▸ Эволюция руки
Таким образом вместо соотношения 1/100 удачных, мы получаем уже 5-10/100, что делает работу с нейросетью более продуктивной. Да, программа не нарисует все за вас, придется научиться хотя бы редактировать графические элементы. Но это уже в половину проще чем рисовать все с нуля.
Продолжаю изучать нейросети как инструмент в разработке игр. Подписывайся на мой гоблинский блог, впереди еще больше интересного!
Сможете найти на картинке цифру среди букв?
Справились? Тогда попробуйте пройти нашу новую игру на внимательность. Приз — награда в профиль на Пикабу: https://pikabu.ru/link/-oD8sjtmAi
Готовлю для вас интересный материал по созданию 2D персонажа через нейронки, а пока делюсь наработками. Ссылка на саму неросеть внизу поста
Удачные варианты - партия №1
Удачные варианты - партия №2
Милые варианты - партия №1
Парад уродов
Данные персонажи создаются через нейронку Stable Diffusion. Использовал инструменты с сайта OpenArt. За основу взят вот этот товарищ:
Пока что экспериментирую, собираю получившиеся варианты. В дальнейшем буду вырезать понравившиеся детали и как в конструкторе собирать новые образы для анимации в Dragon Bones.
Подпишись, чтобы увидеть итог эксперимента!