Иконки для октобита
В октябре я рисовала по одной иконке 32х32 каждый день. И вот что в итоге вышло.
Темы брались отсюда: https://bbrunomoraes.deviantart.com/art/Octobit-2017-Prompt-...
В октябре я рисовала по одной иконке 32х32 каждый день. И вот что в итоге вышло.
Темы брались отсюда: https://bbrunomoraes.deviantart.com/art/Octobit-2017-Prompt-...
Сделал небольшой туториал по тому, как можно изобразить дерево, к примеру для jRPG или платформера. Дерево может выглядеть по разному - зависит от стиля вашей игры и ваших навыков!
Приступим!
Для начала вы должны нарисовать примерные очертания вашего будущего дерева(обычно это шарик на палочке, если говорить грубо)
Добавьте начальные цвета, укажите какие будут тени( в моем случае самый темной оттенок листвы совмещается с оттенком будущего ствола дерева )
Не забывайте, где ваш источник света( в данном случае этот спрайт для jRPG и источник света, солнышко, светит сверху дерева, и свет равномерно переход от яркого к более темному.
Вообще чем темнее оттенок, тем сильнее он должен быть насыщен, но я не всегда следую этому плану, решать вам какие цвета выбирать.
Далее начинаем прорисовывать начальный объем листвы,добавляя объемности огромному зеленому шару
Следующим шагом идет начальная прорисовка листвы. Рисуется листва обычно кластерами.
Если рисовать пиксели по одному - выйдет честно говоря не очень, какая-то пиксельная каша, если говорить проще. В этом кластеры и помогают нам.
Далее продолжаем прорисовывать скопления листвы и тени. Стараемся рисовать объемно, чтобы было легче, представьте форму листвы дерева в виде шара
Начинаем рисовать ствол дерева(На самом деле ствол можете рисовать когда угодно, это уже зависит от вас)
Автор сидит тут (Группа Вконтакте) : https://vk.com/artist404
Привет! Меня зовут Никита Шестаков, я один из разработчиков игры AfterStories(а их немного, всего два. Один отвечает за графику(эт я), а второй, мой старший брат- программирует все это дело :))
Эта игра расскажет вам про доброго мальчугана, жизнь которого превратится в Новейшую MMORPG благодаря новой компьютерной игре и последним новинкам технического прогресса!
Вы - Скотт. Простой 13-ти летний подросток, увлекающийся видеоиграми. Ваша цель - найти причину возникновения ряда странных аномалий в своем городе и предотвратить наступающую катастрофу!
По сути Afterstories - jRPG. Перед вами огромный мир, доступный для исследования, множество врагов и ценных вещей! Игра будет вести вас по сюжету в течении всего времени, показывая все многообразие контента. Конечно, вы можете открыть больше, если решите поискать секретные комнаты и миссии, что расширит время на прохождение всей игры.
Игра предоставит вам три путя развития - Мирный путь, Нейтральный путь и Геноцид.
Выбор стиля игры зависит полностью от вас. Так же, каждый стиль игры кардинально отличается друг от друга. (АФТАР ТЫ ЧО АНДЕРТЕЛ ИГРАТЬ ЛЮБИШ ЧОРТ????)
Боевая система AfterStories отличается от многих игр, но сама при этом берет многое из других боевых систем.
Сама по себе боевая система содержит в себе как и jRPG, так и Арены.
Вкратце - это два сменяющих друг-друга по ходу битвы экрана.
На первом экране происходят тактические шаги - например выбор действия(Атака, Действие или Магия)
ВНИМАНИЕ, СИСТЕМА БОЯ ПРЕДСТАВЛЯЕТ СОБОЙ ЛИШЬ ТЕХНИЧЕСКУЮ СОСТАВЛЯЮЩУЮ И ПОКАЗЫВАЕТ ЕЕ БУДУЩИЙ ВИД! ВСЯ ГРАФИКА БУДЕТ НАРИСОВАНА ПОЗЖЕ( вы сможете увидеть ее в будущей демо-версии)
В вашем распоряжении несколько кнопок с различными действиями
•Атака отвечает за насилие в игре, с помощью этой кнопки вы можете рубить своих врагов, превращая их в мертвый пепел!
•Кнопка действия отвечает за мирные поступки, к примеру разговор с врагов или какое либо действие по усмирению или приручению врага( например, если это какая-то дикая лягушка мутант)
•Кнопка Заклинаний отвечает за магические способности игрока. Она может быть нацелена как на мирное применение, так и на насилие.
К примеру есть заклинания подчинения разума для мирного прохождения или заклинания разрушения, по типу огненных стрел, ледяного дождя и т.д
•Кнопка предметов дает вам полный доступ к вашему инвентарю! Захотели переодеться во время боя - да на здоровье, только вам придется пропустить ход :)
•Последняя кнопка отвечает сразу за несколько действий!
•Подпункт Бегство позволяет вам сбежать с поля боя, если вам не по зубам враг или вам лень сражаться с ним
•Подпункт Просить пощады дает вам возможность попросить пощадить вас и получить снисхождение от вашего врага, если он вдруг решит отказаться сражаться с вами дальше
•Подпункт Пощада дает вам право прекратить бой, если ваш враг больше не хочет с вами сражаться или боится вас.
На втором экране происходит самый экшн! Вам дается определенное время, например чтобы ударить врага или просто избежать его атак, если вы не хотите сражаться с ним!
Второй экран представляет из себя зону, где встречаетесь вы и ваши враги! 1 на 1( ну или 2 на 1, если ваш враг решит пригласить друзей)
При выборе Атаки вы сможете попытаться ударить вашего врага, пока он будет пытаться убить вас.
•При выборе Действия перед боем вы увидите анимацию того, что вы выбрали(например небольшое диалоговое окно, если вы решили поболтать с вашим соперником). После окончания анимации начнется непосредственно битва, где вы не сможете ударить врага, все что вы сможете это попытаться не умереть, избегая атак врага
•При выборе магии перед боем вы так же увидите анимацию, но только заклинание которое вы выбрали.
Во время избегания атак врага вы так же не сможете наносить физический урон.
Если говорить вкратце, вы либо наносите урон вначале хода, если это атакующее заклинание, либо накладываете какой-то бафф на себя, если это мирное заклинание.
Многие скажут "АФТАР ЭТА ЖИ АНДИРТИЛ ТЫ ЧО ВАРУЕШЬ ЧОРТ"
Да, некоторые детали игры вдохновлены андертейлом и серией Mother.
Но стоит отметить, игра разрабатывается не как какое-либо дополнение к Undertale или Mother, а является самостоятельным продуктом.
Так например, были усложнены механики боя, и в отличии от андертейл, в AfterStories вы управляете уже самостоятельным героем, а не душой героя.
Сама концепция мира AfterStories была придумана мной еще полтора года назад(она даже пыталась осуществиться в виде наработок и т.д), но разработка была начата совсем недавно.
На данный момент создается основной костяк игры или же "минимальный жизнеспособный продукт"
Ниже вы можете увидеть, как развивался весь мир нашей будущей игры
К примеру вот так вот менялся сам Скотт за полтора года ( Сорян за разнопиксельность, пытался впихнуть всех в одно корыто)
Вот так менялся портрет главного героя
Изменения сестры Скотта за полтора года
Изменения ее портрета
Огромное спасибо, если вы дочитали эту статью!
Для меня важно поделиться какими-либо наработками для дальнейшей разработки игры, ведь вы те, кто оцениваете саму игру!
Если вы заинтересовались этим проектом, то можете заглянуть ко мне в группу: https://vk.com/artist404
Я буду рад вашей подписке и буду продолжать дальше улучшать свой проект!
Привет, Pikabu! С моего первого поста прошло всего несколько дней, но, на удивление для меня, кому-то стало все-таки интересно что творится под капотом страшной фразы "генерация подземелий" и как изнутри выглядит её код говнокод. Поэтому передаю привет моим трём подписчикам:
и начинаю свой рассказ про то как потратить полтора месяца блуждая по массивам. Материала получилось много, поэтому с коротким промежутком выпущу две части, чтобы ничего не упустить и не запихать все в одну кашу.
Первое, что приходит на ум при придумывании очередного велосипеда на тему создания подземелий - это наспаунить кучу квадратов и соединить их палками. А что, круто же? Комнаты есть, туннели - есть, бегай да собирай бонусы. Вот так и думал мой препод, для которого левел дизайн это "расставь алмазик в трех местах = три разных уровня". Помимо того, что это не так уж и просто сделать, такой подход еще и выглядит отчасти убого, ведь алгоритм объединения отдельных комнат туннелями в таком случае будет примитивным - соедини две ближних и получишь "змейку" из квадратов. Пара дней сидения за гуглом и спешным транслейтом ангельского языка на русский привели меня к статье на хабре, в которой примерно был описан алгоритм неплохой генерации, но на Юнити. Однако, цитировать его слово в слово я не буду, ведь:
так что, опишу то, что изменил под себя и как это выглядит на нашем деревенском GMS2.
Начало простое и логичное. Алгоритм последовательной генерации квадратов налагает на себя одну большую проблему - эти квадраты необходимо разместить так, чтобы они друг друга не касались. Да, можно поступить по топорному - пусть алгоритм ищет пустое место и тыкает туда комнату, размер которой будет рандомным. Вроде и не пересекается, вроде и недалеко друг от друга. Однако, если нам понадобится:
а) определенное количество основных комнат
б) определенный размер комнат
то мы выстрелим себе в ногу, потому что нам либо придется писать кучу условий на проверку свободного места (и в случае нехватки либо распределять заново либо удалять лишнее), либо сидеть и надеяться, что без этих условий рандом сжалится и ни разу не улетит в бесконечный цикл, наткнувшись на место, в которое нужно воткнуть комнату но не нельзя уместиться в минимальный размер.
Решение здесь такое же простое и ленивое - зачем думать над условиями, если программа сама может решить твою проблему? Существует такое понятие как "флокирующее поведение". Это поведение объекта (именуемого агентом) в условии присутствия других таких же объектов. У него существуют несколько ограничений, связывая которые можно получить различный тип поведения, от преследования до убегания. В моем случае, генерируем случайное количество комнат на плоскости со случайным размером в радиусе определенной окружности, определяем вектор каждой комнаты до ближайшего соседа, и просто разворачиваем его в обратную сторону. Иными словами:
Таким образом, расположенные рядом на очень близком расстоянии объекты, разлетаются друг от друга в противоположных направлениях. В итоге, мы получаем гарантированное "несовпадение" по координатам в независимости от размера комнат. В коде это выглядит примерно так:
"если я касаюсь какого-то выродка - посмотреть в его сторону и бежать в противоположную со скоростью 10"
Разбежавшись, комнаты занимают свои позиции и переводят дух. Теперь их ждет вторая стадия - необходимо определиться, кто здесь главный и с кем из соседей этот главный хочешь скорешиться. Забыл упомянуть, как это все хранится: каждая комната это обычный объект GMS2, имеющий координаты, спрайт, а также возможность добавления кода. Для того, чтобы дальше работать с ними как с совокупностью, а не раздельным сбродом, я добавляю id каждого объекта в специальный одномерный массив. Массив хранится в еще одном объекте, который отвечает здесь вообще за всю тусовку связанную с генерацией - obj_dungeonGenerator. Вон сидит, сидит палит
Комнат получается много, поэтому нужно отсечь лишние и взять нужные. Под нужными я понимаю те, которые имеют определенный размер, например, больше среднего. "Лишние" комнаты, однако, совсем не лишние. Почему? Взгляните сюда:
Зеленые квадраты - это нужные комнаты, а красные линии - потенциальные соединения между ними. И знаете что меня напрягает? Вот этот шакал:
Т.е, в некоторых случаях мы получим ситуацию, при которой может сгенерироваться гигантский туннель, незаполненный абсолютно ничем, но счастливо соединяющий нужные нам комнаты. Напоминает "я сделяль", и нас это категорически не устраивает. Игрок, бегущий по такому пространству, быстрее плюнет на игру чем дойдет до соседней комнаты. Чтобы этого избежать можно не идти далеко за грибами - просто берем и включаем в список нужных комнат те, которые умудрились попасть на эту линию. Выходит что-то вроде:
Однако, это еще не конец истории. Окунемся немножко в теорию вероятностей чтобы было понятно о чем речь. В ненавистной мной ТВ (из-за тотального её непонимания когда я сидел на её парах) существует понятие равномерно распределения. Оно используется в любимой нами функции radom(), random_range() и прочих прочих. Согласно термину: "В теории вероятностей случайная величина имеет дискретное равномерное распределение, если она принимает конечное число значений с равными вероятностями." Это значит, что рандомно задавая размер комнаты, мы, каждый раз, можем равновероятно получить как большую, так и среднюю или малую комнату в нашем диапазоне. Как это нам мешает? Такое распределение создает ситуацию, в которой все комнаты получаются примерно одинакового размера. Поэтому, на моменте отбора нужных комнат получится, что мы отберем 10 самых больших, но на фоне останутся, фактически, такие же комнаты, только чуууть меньше или больше. Из этого следует, что в качестве туннелей мы получим не линию из маленьких комнат, а совокупность больших инвалидов, которые уместились по соседству. В своей игре я хочу иметь понятие "основной" и "дополнительной" комнаты - в первой будут сундуки и плюшки с сильными мобами, во вторых - прочая мишура для тира, которую можно пробежать и забыть, не сильно при этом скучая. Поэтому я беру на вооружение так называемое Геометрическое распределение. Оно отличается вероятностью появления каждого последующего события, т.е., чем дальше от начала отсчета "событие", тем меньше вероятность его появления. Таким образом, мы получим маленькое количество больших, и большое количество маленьких комнат, что играет нам на руку - первые в основные, вторые - на мясо. В итоге этого выглядит примерно так (на скрине еще старое, равномерно распределение, но прикрепляю его чтобы видно было дело, а не рисунки с пэинта):
На нем видно окружность, из которой выползли уже готовые комнаты, а также их разделение на основные и дополнительные. Однако, многие посмотрят на скриншот и спросят:
А это еще одна отдельная история. Получив равномерно распределенные по пространству и геометрически распределенные по размерам комнаты мы, по сути, ничего и не сделали - это просто набор объектов, хоть и располагающихся так, как нам нужно. Следующая задача - это сформировать из них массив, каждая ячейка которого будет отвечать за свое место в пространстве и то, что в нем находится - стена, пол, дверь или же пропасть. Благодаря этому массиву в будущем мы сформируем карту тайлов, которые и отрисуют нам графику (с ними, кстати, я недавно разобрался), а не цифры. Чтобы его сделать я отсортировываю все комнаты по х-координате и y-координате и выбираю самые крайние по четырем направлениям.
Получив их, я вычитаю самую верхнюю координату по Y из самой нижней, и самую правую из самой левой по X, получая, тем самым, размер всего занятого комнатами пространства. Дело осталось за малым - делим эти дистанции на размер нашей сетки (я выбрал 16 пикселей, т.к. всю графику буду рисовать именно в этом стиле) и, вауля, у нас получилась матрица определенного размера и с определенной шириной ячейки, однако, она все еще пустая.
Пробегаемся вложенным циклом по этому двумерному массиву с таким условием: "если по координатам этой ячейки ничего нет - кладем туда #, если есть главная комната - кладем 2, если дополнительная - кладем 1", а затем, пробегаем второй раз с другим условием: "если рядом с единицой или двойком в матрице есть # - заменяем его на +", получая тем самым заполненную матрицу с расположением комнат, стен, а также пустых пространств.
Итак, что мы имеем в конце всего этого сложного действа? Во-первых, массив комнат, к каждому элементу которого мы можем отдельно обратиться в случае необходимости. Во-вторых - готовую матрицу, в которой хранится расположение комнат и стен, и, которая, поможет нам при отрисовке тайлов стен и пола. Таким образом, мы подготовили платформу для последующего объединения комнат в граф и создания связей при помощи туннелей, о которых я расскажу в следующем посте.
P.S. имхо, получилось скучнее и нуднее, чем я ожидал, поэтому заранее извиняюсь за слог. В следующий раз попытаюсь вещать более лаконично и грамотно, а то так даже мемасики не спасут положение. Отметьте в комментариях что непонятно или чего недостаточно, пишу такое, отчасти, в первый раз, так что постараюсь уточнить все, что смогу