Комментарии 71
В мире Java всё ещё более-менее. А вот те, кто пробует сделать кроссплатформенную игру скажем… ну, пусть будет на Rust при помощи Piston, очень быстро приходит к выводу о написании своего собственного Piston'а.
«Русского нет!.. Нет русского!.. Добавьте русский язык!.. Разрабы псы!»
Статья очень понравилась, большое спасибо:)
Но геймплей офигенный.
Понятия эти достаточно расплывчаты, но для упрощения принимается такой принцип — добрые должны бить злых и наоборот. Бьешь злого — становишься добрее, бьешь доброго — становишься злым. Конечно, имеет смысл и относительная «доброта». Добропорядочность (характер) измеряется в очках от «минус» 1000 до «плюс» 1000.
Команда «счет», результат которой на скриншоте, отображает таблицу характеристик персонажа.
Я играю персонажем по имени Тайзур, это человек-нейтрал. Положение натуры не должно быть слишком положительным, и не должно быть слишком отрицательным. То, что натура «любезная» — это просто один из индикаторов, что я слегка отошел от позиции нейтралитета, и следует опасаться перехода на статус «добрый :)
Что это за великолепие ?
www.aladon.ru
Прекрасная статья.
Я не разрабатываю игр, плохо знаю java и вообще не знаю kotlin.
Но это никак не помешало мне получить огромное удовольствие от статьи, а также подчерпнуть из неё много полезного.
Статья хороший пример "промышленного" подхода к программированию.
Прекрасно видно что время затраченное на дизайн игры и рисование всех этих чудовищных диаграмм не прошло зря.
Всё это используется и в конце концов ускоряет и облегчает процесс написания игры.
Особое спасибо за приправленный юмором стиль.
плохо знаю java и вообще не знаю kotlin
Пусть такая мелочь, как незнание какой-то конкретной технологии, не становится препятствием на пути к вашей мечте (ну или не конкретно вашей — я ко всем обращаюсь). Замените java на basic, а kotlin на malborge — суть от этого не поменяется.
Выбирайте те инструменты, с которыми вам удобнее.
Мой комментарий был к тому, что не зная ни Java не Kotlin и не собираясь в них углубляться в ближайшм будущем из статьи можно надёргать всякого полезного.
Кстати, если кто "внезапно" изберёт целевой платформой именно malbolge то с его или её мечтой мы скорее всего не познакомимся никогда.
Более мейнстримовые brainfuck или олдскульный intercal дадут хоть какой-то шанс.
убежал патентовать идею...
Конкретно по примеру из статьи: даже не знаю, как тут можно улучшить. В руке у нас 10 активных позиций, каждая может быть или выбрана, или нет, что дает 1024 возможных варианта. В тесте рассмотрены только некоторые (как казалось, наиболее характерные). В защиту скажу, что тест очень помог при реализации метода (а процесс реализации помог найти ошибки в тесте — возможно, это обоюдный процесс).
Ну или я лось, и всё можно было сделать гораздо проще — чем не вариант?
Если писать тесты "правильно", то они будут фактически повторять реализацию проверяемой функции и сравнивать две эти реализации.
На мой взгляд такой подход вреден, т.к:
1) необходимо выполнить двойной объём работы,
2) если ошибка кроется в логике или неправильном понимании требований, обе реализации будут содержать одну и ту же ошибку.
А тесты в виде набора правил входные данные -> выходные данные:
1) простые, быстро пишутся,
2) практически невозможно допустить ошибку,
3) выходные данные придумываются ещё до написания функции (берутся из бизнес-требований, считаются на бумажке или другой реализацией), поэтому не подвержены логическим ошибкам, допущенным при написании функции.
Ошибки в тестах не могут остаться незамеченными и привести к серьёзным последствиям, ведь обнаружив несоответствие, вы сначала проверите тестируемую функцию, а затем и сами тесты.
Вот конкретное требование из примера в статье:
нужно взять из руки три кубика: один синий или зеленый, второй фиолетовый или желтый, третий синий или белый
Как проверить, правильно ли написано правило для такого рода требований? Кроме предложенного «обезьяньего» варианта брать кубики по очереди и говорить «окей»/«не окей» я ничего путного придумать не могу.
А вы можете?
Ну и ближе к теме статьи, хе-хе.
В любом случае, реализация какой-нибудь фичи займёт больше времени, чем освоение этой же фичи уже реализованной в готовом движке.
Ну а по поводу ассетов — никто не запрещает рисовать всю графику самостоятельно, как предполагается при разработке своего движка. Просто готовые ассеты могут позволить существенно ускорить работу и получить качественную графику для своей игры быстро и недорого.
Готовые движки как раз тем и хороши, что не нужно тратить время и силы на реализацию фичей для реализации идей. Есть идея — тут же её реализовал и оценил как она в игре.
Их акторсистем, это та же самая ECS с ерархией.
Советую взять более лайтовый движок, чисто для изучения популярных архитектур. Освоив идею граф-сцены и компонентов, переходить на такие монстры как UE4 и Unity становиться на уровень легче. Но для UE4 лучше еще изучить паттерн Акторов, который он так же использует.
Но честно скажу, в Ue4 для 2D сильно перегруженно. У UE4 2D, это как у cocos2d-x 3D.
У первого 2D не удобен для индти. У второго функционал очень скуден и документация страдает для 3D.
Игра не готова, она в процессе (замечания и предложения весьма приветствуются). Полезные ссылки есть в конце статьи в одноименном разделе (такая большая надпись ССЫЛКА!).
readme.txt
, я об этом предупреждал. В качестве временного решения переключитесь на вкладку «Advanced» и нажмите кнопку «Generate script». Сохраните полученный sh-файл где-нибудь и запускайте из терминала — должно работать.К сожалению, у меня нет мака, чтобы опробовать на нем разные решения. Открыть из командной строки терминал и передать в него команду на выполнение почему-то получилось только через
osascript
: osascript -e "tell application \"Terminal\" to do script \"<COMMAND>\""
Но из кода java-приложения запустить эту команду не выходит (видимо, из-за двойных кавычек и необходимости их экранировать).
Если кто-то может оказать помощь в этом вопросе, буду несказанно благодарен.
Да, что-то я не очень внимательный в последнее время, все куда-то спешу :)
Сгенирировал скрипт, сохранил, ввожу строчку в терминал. Оно открывает новый терминал и выдает такую вот ошибку
-bash: syntax error near unexpected token `newline'
ввожу строчку в терминалКакую конкретно? Вот эту?:
/bin/bash dice.sh
Оно открывает новый терминалНе должно. Приложение должно запускаться в текущей сессии терминала.
Пожалуйста, пришлите скрипт.
Я не программист, поэтому могу показаться несколько туповатым в этих вопросах =)
Вот эту строчку
osascript -e "tell application \"Terminal\" to do script \"<COMMAND>\""
Вот сам сгененированный скрипт
#!/bin/sh
/Library/Internet\ Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java -Dfile.encoding=UTF-8 -Duser.language=ru -cp "/Users/dmitry/Desktop/all/temp/DiceStories/engine/dice-1.0.jar:/Users/myname/Desktop/all/temp/DiceStories/stories/*" org.alexsem.dice.MainKt "/Users/dmitry/Desktop/all/temp/DiceStories/saves"
Если вы сохранили скрипт, например, себе на рабочий стол (с именем
dice.sh
), то в терминале нужно написать следующее:/Users/dmitry/Desktop/dice.sh
Чуть-чуть поиграл, ничего не понял, тут вникать нужно, знать правила настольных игр и т.д. Напоминает старые игры в которые нужно еще разобраться как играть. А я уже слишком привык к казуалкам, где думать и вникать практически не нужно.
Спасибо за статью!
Я тайный фанат Kotlin поэтому не рассматривайте как критику мое наблюдение, но не понятнее ли будет как во втором варианте?
fun draw(): Die = dice.pollFirst()
fun draw(): Die = dice.pollFirst()
Или синтаксис не позволит?
А про игры — полностью согласен, это захватывающе!, с теплом вспоминаю свои первые поделки-игры на Basic на ZX Spectrum (Sinclair), и там было ascii так же.
fun draw() = dice.pollFirst()
Если честно, не понял, в чем разница. Сравните с полноценным «джавовским» аналогом:
fun draw(): Die {
return dice.pollFirst()
}
и решите, что понятнее лично вам. Так и пишите.
Благо, синтаксис достаточно гибкий, чтобы разные варианты допускать.
Почему бы не использовать готовый игровой движок? Ответ прост: мы ничего про него не знаем, а игру хотим уже сейчас. Представьте образ мысли среднестатистического программиста: «Хочу делать игру! Там будет мясо, и взрывы, и прокачка, и можно грабить корованы, и сюжет бомбезный, и такого вообще никогда и нигде больше не было! Начну писать прямо сейчас!.. А на чем? Посмотрим, что у нас сейчас популярно… Ага, X, Y и Z. Возьмем Z, на нем сейчас все пишут...». И начинает изучать движок. А идею бросает, потому что на нее уже времени не хватает. Fin.Т.е. по вашему написать игровой движок с нуля быстрее чем почитать документацию к тому же анрилу где примерно половина работы уже выполнена? Я нахожу это крайне сомнительным.
Поясню свою позицию.
Я отнюдь не против использования готовых движков. Наоборот, они дают огромное преимущество в скорости и качестве по сравнению с собственными велосипедами (особенно если разработчик имеет хорошие навыки работы с ними). Но сам по себе движок — не панацея. Да, он поможет настроить игровой цикл, обеспечит графический вывод, ввод, взаимодействие различных объектов, физику там… Ну и всё. Основную логику работы все равно придется писать самому (и это хорошо, иначе все игры были бы похожи одна на другую).
Вот вам простой пример. Скачал как-то на мобилку интересную игру (обойдемся без конкретных названий). Весит 64Мб. Работает с тормозами и батарейку кушает как голодный африканский крокодил. А игры-то: пара статичных двухмерных спрайтиков по экрану перемещается без особых эффектов и анимации — казалось бы, чему тут тормозить?
А все потому что разработчик решил свою игру на Unity написать — ну и потянулась вся эта махина в его проект. Я с Unity крепко не работал, не знаю, может так и надо. Может, разработчик не позаботился об оптимизации и чего-то важного не сделал (читай: плохо знает инструмент), но в одном уверен: реализуй он такую же функциональность на обычном canvas'е (стандартными средствами), игра бы весила 300кб и летала быстрее, чем армейский вертолет (такой опыт у меня был, я знаю о чем говорю).
Это я все к чему? Не нужно, как мне кажется, забивать гвозди микроскопом. Если пишете клон сапера, Unreal Engine вам, скорее всего, не нужен. А даже если и нужен, то будьте людьми, не забывайте об оптимизации.
(Ну или читайте отзывы игроков на странице магазина и как-то реагируйте.)
Обычно перед выпуском, после прототипирования, создают либо шаблон экспорта, либо пересборку нужных модулей движка. Скорее всего, данный фрукт просто подключил библиотеки System, Scurity из net core и всякие веб и аналитические сервисы.
Я не юзаю юнити. Но на годоте том же. Чистый движок без спрайтов весит 2мб, если использовать свой шаблон. А если использовать стандартный шаблон — чистый движок весит 15-20мб на андройде ( в зависимости от типа сборки и отладочной инфы)
Так же он разанлокал фпс, из за чего, батарея летит в хлам
Люди, не обманывайте себя. Вы делаете не игру мечты, а игру, которая будет хорошо продаваться — это разные вещи.
А что, если я мечтаю сделать игру, которая будет хорошо продаваться? *thinking face*
Даёшь «Рвотный Глаз Топор» в каждый дом! :)
А потом ты еще свои скрипты начинаешь интегрировать. Что бы ускорить разработку. Начинаешь редакторы карт изобретать, генераторы сценариев и прочее…
А если еще и кросплатформенным его делаешь — ух… AdMob, FireBase куча всяких сервисов…
А так есть такие кросплатформенные движки как Wolf Engine, Ascid, Godot, cocos2d-x. Бинарник чистого движка весит 2-5 мб. Не такая большая плата за 100500 готовых велосипедов. (у godot надо правда свой прекомпилированный шаблон создать, для такого веса)
Все свои проекты я перевел из велосипедов на движки.
Категоричного отношения ни в статье, ни в комментариях высказано не было (не пойму, почему сложилось такое мнение). К сожалению, люди, которые пишут про движки, не уточняют, какую конкретно часть функциональности с их помощью удалось реализовать. Уверен, ни один продвинутый движок не способен придумать за вас интересную игру. Вместе с тем готовую интересную игру несложно перенести на продвинутый движок.
Потому в статье и не делается упор на работу с движками.
Все движки имеют схожий принцип…
По поводу тому, что они решили.
Например. Физика…
В начале ты создаешь банальный перебор мешей и трасировку лучей.
Потом, когда их много — делаешь quad_tree/cube_tree с чанками. Дабы уменьшить перебор.
Потом все это дело отлаживаешь… отлаживаешь… очень долго отлаживаешь… несомненно, лучше взять хотя бы box2d.
Физика — первое решение
Интерполяция параметров. Для создания плавных анимаций и прочего. Например ни одним своим велосипедом мне не удалось превзойти гибкость того же godot, в котором ты абсолютно что угодно можешь заанимировать или размазать во времени.
Система сигналов/ивентов — часто, создавая свой движок, для создания слабой связности, реализация этой подсистемы заставляет переписать логику раза три-четыре.
Ерархия обьектов — можно пойти по классической ECS. Но часто, нужна группировка сущностей. Наследование родительских координат и т.д. Из за этого, ты опять же вынужден пересматривать по несколько раз свою архитектуру, если пишешь велосипед. Использовать GraphScene, ECS или гибридный двух этих паттернов? Или god object (антипаттерн) создать на подобии того, что есть в Unity?
Графическая подсистема. Dx, OpenGL, GL ES, Vulkan…
В итоге, я пришел к тому, что что-бы я не делал. Всегда есть что-то уже готовые и на уровень практичнее.
Даже такая мелочь как viweport, для адаптации разрешения под любой формат — реализация этого — не такой уж и простой шаг…
Костная анимация спрайтов, дерево анимаций, машины состояний.
До тех пор, пока ты придерживаешься базового концепта своей игры — свой велосипед будет не плох. Но как только начнешь реализовывать фичи. Именно фичи и новые игромеханики — начнется тонная проблем и бесконечный цикл переписывания движка. И за место того, что бы делать игру — ты будешь делать движок. А когда изучишь все эти аспекты, из чего строиться движок и какие паттерны — поймешь, что все ты изобрел очередной клон какого нибудь. MonoGame + Nez, Wolf engine, Ascid, Cocos2d-x, и т.д
Опыт конечно не сомненный, но время потрачено просто чудовищно.
Даже не смотря на то, что многие говорят «В своем движке ты можешь делать все что угодно» — это отчасти лож. В голове ты все не удержишь, а связность различных систем движка, рано или поздно встанут тебе боком и ты начнешь много и част перепсывать. А если ты успеешь что-то создать на нем — то сохранение совместимости со старым проектом — обойдется тебе боком. А если документировать все и обращаться к документации постоянно — это мало чем будет отличаться, от постоянного обращения к документации того же unity.
Как создать игру, если ты ни разу не художник