Привет, Анон. Меня зовут Влад. И я, если не единственный, то как минимум первый разработчик игр для макабы. За моей спиной уже целый один крупный проект (http://vk.com/zog_thread) игры для данной платформы. И вот, я решил поделиться с вами информацией о том, как же всё-таки можно создавать игры для макабы и какие имеются подводные камни. Немного предыстории. Разрабатывать игры для макабы я начал около полугода назад, когда Абу открыл нам api. Идея была простой. На борде регулярно всплывали игровые треды с рулеточками, именуемые Захвати Странанейм-тред, в которых я также, как и многие из вас, принимал участие. Но играть всегда было не удобно, ведь уследить за большим количеством сообщений очень сложно. Поэтому было решено, во чтобы то ни стало упростить управление этой игрой. Так и началось моё первое знакомство с макабой. С тех пор игра эволюционировала, в ней появился отличный редактор уровней, трансляцию на ютубе, от которой наши модераторы очень бугуртили, заменила автоматическая отправка карты в тред, прокси и прочие костыли заменил простой плагин CORS Everywhere. В общем, много чего изменилось и за всё это время я получил огромный опыт в разработке игр для макабы. Сегодня, на примере разработки очередной игры для макабы мы разберём основные этапы разработки и сложности, с которыми может столкнуться программист, разрабатывающий игру для владельцев девайсов, поддерживающих макабу. Вопросы можете задавать по ходу. Буду постепенно описывать этапы разработки.
Начнем мы конечно же с выбора языка программирования для нашего приложения для макабы. Самым оптимальным вариантом будет клиентский javascript. Оптимален он по нескольким причинам: 1) Двач прежде всего сайт и с сайтом проще всего взаимодействовать с помощью сайта. Именно по этой причине ведущие CMS предлагают удобную панель управления внутри сайта, а не вне его с помощью отдельной программы. 2) Не нужно открывать множество приложений. Достаточно открыть всего лишь браузер с двумя вкладками и в вашем распоряжении уже оказывается как клиент, так и сервер вашей игры. 3) Асинхронность. Учитывая, что мы работаем с интернетом, асинхронность безусловно будет плюсом при работе нашего приложения. Это не все, но основные преимущества использования клиентского JS для написания игр под makaba engine.
Как обычно устроены игры и приложения для makaba? Есть ОП, который выполняет роль сервера и есть множество клиентов, которые этим сервером управляют. Управляют они им, как правило, по средством специальных команд. В ответ на команды, ОП отправляет результат и пользователи продолжают игру. Игры под makaba, как правило, многопользовательские. Поэтому отличным вариантом будет равноправность нескольких персонажей. Ведь таким образом пользователи будут конкурировать друг с другом, а значит игра будет интересней и соберет большее количество фанатов и наблюдателей. Также, чтобы игра была интересной, вместо простых ответов текстом лучше всего использовать динамичные иллюстрации, как например пикрелейтед. В этот раз мы пойдем несколько дальше, чем это принято и совершим революцию в мире приложения для makaba. Вместо скучных статичных иллюстраций мы будем использовать интересные и красивые динамичные иллюстрации, проще говоря, грофен будет анимирован.
Какой геймплей подойдет для игры лучше всего? Учитывая особенности макабы, игра должна быть: 1) Простой в управлении. 2) Медленной. Лучше всего пошаговой. 3) Автономной. То есть пользователи не должны зависить друг от друга. Так, например, какой-нибудь 3d yoba шутер будет не лучшим решением для приложения по первому пункту. Какой-нибудь Товер дефенс не подойдет по второму пункту, ибо пользователь не будет успевать реагировать на полчища противников. Мафия не подойдет по третьему пункту, ведь один пользователь будет в теории знать больше другого, а этого не может быть по определению. Что касается команд. В игру следует внести элемент случайности, дабы играть было интересней и игра не зависила от одних лишь команд и того как быстро анон может ввести их.
Вернёмся к разработке. Мы уже определились с жанром игры JRPG и в целом с геймплеем. У нас есть идея, которая оптимально подходит под все описанные выше критерии и даже некоторый прототип интерфейса - пикрел. С чего же следует начать? А начать следует с установки необходимой среды в ваш браузер. Так как в 2ch API напрочь отсутствует поддержка CORS, нам понадобится искусственно внедрить её. К счастью, есть отличный плагин CORS Everywhere, который я уже упомянул ранее. Зачем CORS? Дело в том, что браузерам запрещают скачивать информацию с некоторых URL, а затем передавать её, если на то нет разрешения, то есть определённого заголовка в CORS. По этой причине становится проблемотично взаимодействовать с макабой. Также нам понадобится jQuery, дабы упростить написание нашего приложения.
Как будет устроен игровой процесс?Chekunov!VladgUJPdI23/02/16 Втр 18:28:53#6№234082
Пользователь создаёт новый тред или подключает уже имеющийся. Приложения начинает анализировать ответы в треде, интерпритируя их и строя на основе их результат, который будет через некоторое время/количество постов отправлен в тред. В нашем случае приложение будет пытаться интерпритировать вводимые команды и создавать на их основе анимацию, которую через некоторое время оно отправит в тред.
Так как в нашем приложении будет использоваться анимация, нам следует выбрать один из всевозможных вариантов её реализации, а именно: 1) Webm. Есть поддержка звука, но при этом большой размер выходного файла, а также долгое время генерации. 2) Gif. Для нашего приложения будет наиболее оптимальным использование GIF, ведь следует учитывать, что изображение будет передаваться через интернет, а не у всех наших пользователей столь мощное железо и интернет-соединение, чтобы генерировать WebM. Как же сгенерировать GIF? А в этом нам поможет замечательный фреймворк от Yahoo. Gifshot, вот демонстрация его возможностей: https://yahoo.github.io/gifshot/demo.html
Перейдём от слов к делу и наконец приступим к написанию нашего первого приложения для макабы. Для начала создадим общую файловую структуру, общепринятую в большинстве веб приложений. Создадим папки img, css и js, в которых соответственно будут находиться картинки нашей игры, стили интерфейса нашей игры и общая программная логика. В корне также требуется создать файл index.html. Это и будет в итоге место, откуда мы будем запускать нашу игру. Его мы заполним следущими тегами: <!DOCTYPE html><html><head><title>Моё первое приложение для makaba</title></head><body></body></html> Затем мы подключим jquery, добавив соответственный тег в head. Также нам нужно установить плагин Cors Everywhere в наш браузер. Лично я использую FF и всячески призераю хромо-майкрософто-оперо-сафари-блядков. Возможно, под ваш браузер есть альтернативный плагин, способный включить постоянный CORS, но я советую использовать именно FireFox, дабы в дальнейшем избежать некоторых неточностей.
Дабы избежать проблем с отображением кириллических символов, следует сохранить ваш index.html и другие файлы, которые мы будем создавать далее, в кодировке UTF-8. Также внутри head мы допишем: <meta charset="utf-8"> Тем самым мы дадим понять нашему браузеру, что приложение использует именно эту кодировку.
Получение информации с бордыChekunov!VladgUJPdI23/02/16 Втр 19:09:30#12№234122
Итак, анончик, давай же попробуем получить, например, первый пост этого треда. Для этого заполним body нашего index.html следущим кодом: $.ajax({ url : 'https://2ch.hk/gd/res/234027.json', async : false, dataType : 'json', crossDomain: true, success : function(data) { console.log(data.threads[0].posts[0].comment) } }); Некоторые ключевые значения я выделил ЖЫДНЫМ: 1) Это буква нашей доски. 2) Это номер нашего треда. 3) Это номер сообщения в треде. Итак, теперь, открыв наш файл в браузере, предварительно включив CORS Everywhere и открыв консоль, мы увидем, что в наше консоль вывелось первое сообщение этого треда.
>>234135 Защекунов это ты так своего отца называть привык? Что касается хеллоуворлда, очевидно, что пилился он так долго именно из-за нехватки времени, отчасти из-за проектирования описываемой игры.
Основной объект игрыChekunov!VladgUJPdI23/02/16 Втр 19:24:31#18№234158
Создадим основной объект игры, добавив в head следущий код: <script> var gm={ data:{},/Данные пользователей/ load:function(){/События при старте/}, timer:false,//Таймер draw:function(){/Событие отрисовки нашего ответа/} inter:function(){/Событие интерпретации полученной информации/} } </script> Описанный ранее код можно закоментировать, так как в ближайшее время он нам не понадобится.
Данные игроковChekunov!VladgUJPdI23/02/16 Втр 19:33:22#19№234166
Основываясь на прототипе мы можем уже заполнить некоторые данные игроков. Создадим в нашем объекте данных data, объект players и заполним его: players:[{name:"Влад",//Имя pclass:0,//Класс lvl:12,//Уровень health:0.9,//Здоровье coin:200,//Монеты score:200,//Очки helmet:0,//Идентификатор шлема plat:0,//Идентификатор хз как назвать, в общем, верхней одежды legs:0,//Идентификатор штанов boots:0,//Идентификатор обуви sprite:{//Спрайт персонажа x:0, y:0, frame:0}, enemy:{//Данные противника pclass:0,//Идентификатор вида противника lvl:4,//Уровень противника health:1,//Здоровье противника sprite:{//Спрайт противника x:0, y:0, frame:0 }}}]
Теперь на основе наших данных, давайте отрисуем нашу игру. Добавим canvas в body с width=500 и height=200, подключим его к нашему коду в load и добавим отрисовку интерфейса в функцию draw. >gm.ctx=document.getElementById("canvas").getContext("2d") Пока просто отрисуем фон и зададим некоторые размеры. >gm.ctx.fillStyle="#211e33";gm.ctx.fillRect(0,0,500,200); Нужно также не забыть связать load с загрузкой нашего приложения: >window.onload=function(){gm.load();} И, конечно же, добавить нашу переменную ctx в объект gm. Дабы видеть результат в load добавим отрисовку: >gm.draw(); Обновив страничку мы увидим прямоугольник 500х200, который будет в итоге клиентским интерфейсом нашей игры.
Продолжим отрисовку интерфейса, нарисовав левую панель со списком пользователей, монетами, очками и полосой здоровья. Создадим спрайт sprite.png пикрелейдед и поместим его в наш img каталог. Заполним функцию draw следующим кодом: gm.ctx.fillStyle="#110f1a"; gm.ctx.fillRect(0,0,500,200); gm.ctx.fillStyle="#ffffff"; gm.ctx.fillRect(95,0,500,200); gm.ctx.font="10px Pixel Cyr"; gm.ctx.fillText("Игроки:",27,12); gm.ctx.mozImageSmoothingEnabled = false; gm.ctx.imageSmoothingEnabled=false var img = new Image(); img.src = 'img/sprite.png';//Загружаем спрайт img.onload = function(){ for(var i=0;i<gm.data.players.length;i++){ gm.ctx.fillStyle="#211e33"; gm.ctx.fillRect(1,20+i26,93,25); gm.ctx.fillStyle="#ffffff"; gm.ctx.font="8px Pixel Cyr"; gm.ctx.fillText(gm.data.players[0].name, 35, 30+i26); gm.ctx.font="10px Pixel Cyr"; gm.ctx.fillText(gm.data.players[0].coin, 14, 31+i26); gm.ctx.fillText(gm.data.players[0].score, 14, 41+i26); gm.ctx.drawImage(img,0,0,5,5,5,25+i26,5,5); gm.ctx.drawImage(img,0,5,5,5,5,35+i26,5,5); gm.ctx.fillStyle="#a30d15"; gm.ctx.fillRect(35,35+i26,55,5); gm.ctx.fillStyle="#0da913"; gm.ctx.fillRect(35,35+i26,Math.ceil(55*gm.data.players.health),5);}} Как видите, теперь список наших пользователей отображается на странице. Однако, есть одна проблема. К тексту применился anti-aliasing. Из-за этого вместо одного белого цвета такста у нас также присутствуют и промежуточные цвета, что, конечно, скажется на размере файла, как это пофиксить, я расскажу позже, когда мы дойдем до этапа создания gifки.
Добавляем некоторые элементы в спрайт. Создаём массив объектов mobs, добавляя первого противника: >mobs:[{ >name:"Червь-пидор" >}], Также несколько дополняем событие draw и получается пикрелейтед.
>>238698 Примечание Для примера в массив объектов игроков players были добавлены ещё 3 дубликата нашего персонажа, дабы видеть как всё это будет прорисовываться.
Создадим объект с объектами массивов параметров вещей и добавим туда некоторые объекты, которые затем поместим на спрайт: items:{ helmets:[{ name:"Бумажный пакет", x:24,//Расположение на спрайте y:0, width:8, height:8, xo:4,//Offset на отрисовке yo:0 },{ name:"Маска Гая Фокса", x:24, y:8, width:8, height:9, xo:4, yo:0 }], plats:[], legs:[], boots:[] },
Также добавим на спрайт персонажа по умолчанию и несколько его поз, а также свяжем предметы, персонажа и их параметры в нашем draw. Так, что спрайт будет как первый пикрелейтед, а интерфейс как второй пикрелейтед. Я несколько поменял игроков для разнообразия.
Выбор команд для игрыChekunovOP!VladgUJPdI27/02/16 Суб 22:47:09#31№239609
Настало время придумать команды. Команды должны быть не сильно сложными, чтобы игрок не мучался их вводить. Исходя из задумки нашей игры, я выделил несколько основных команд: >1)Создать персонажНейм >2)ПерсонажНейм Похиляться >3)ПерсонажНейм защититься >4)ПерсонажНейм ударить >5)Купить предметНейм На основании этих наработок команд мы будем разрабатывать дальнейшую логику игры. Создавать персонажа на даббл/траппл, остальные команды скорее всего на четность/нечетность, дабы играть было проще. Разве что, покупку на даббл/триппл оставить.
>>239613 Потому что это будет уже не игра под макабу. Туториал не про это. Цель туториала не просто создать сетевую игру, а написать собственную ПЕРВУЮ ИГРУ ДЛЯ УСТРОЙСТВ С ПОДДЕРЖКОЙ MAKABA.
>>239609 Теперь сделаем аналогичный спрайту персонажа, спрайт червя-пидора - единственного, на данный момент, враждебного моба. Также отрисуем его в функции draw. Мы ещё вернёмся к отрисовке, но пока, этап предварительно отрисовки завершен и можно начать заниматься общей логикой игры.
>>239609 >1)Создать персонажНейм Теперь сделаем объект act для всех функций, связанных с игровым процессом и добавим в него функции createChar, которая будет добавлять игрока и checkUserName, которая будет проверять на повторение имя игрока. Ведь управлять игроком пользователь будет именно благодаря его имени.
Я тут немного подумал и решил, что при каждой проверке треда будет интерпритироваться действие, затем это действие в случае успеха ролла, будет добавляться в некоторый стек действия игрока. Когда хотя бы у одного игрока этот стек содержит более 5 действий, мы начинаем их реализовываться, создавая кадры для нашей gif и отправлять её в тред.
>>239609 >>2)ПерсонажНейм Похиляться Для этого сделаем функцию healChar с параметрами playerId (идентификатор персонажа), frame (номер кадра, ведь на одном кадре мы размещаем сразу несколько персонажей, а кадр у нас не единственный) и health (процент восстановления здоровья).
>>234137 [code] Итак, анончик, давай же попробуем получить, например, первый пост этого треда. Для этого заполним body нашего index.html следущим кодом: $.ajax({ \turl : 'https://2ch.hk/gd/res/234027.json', \tasync : false, \tdataType : 'json', \tcrossDomain: true, \tsuccess : function(data) { \t\tconsole.log(data.threads[0].posts[0].comment) \t} }); Некоторые ключевые значения я выделил ЖЫДНЫМ: 1) Это буква нашей доски. 2) Это номер нашего треда. 3) Это номер сообщения в треде. Итак, теперь, открыв наш файл в браузере, предварительно включив CORS Everywhere и открыв консоль, мы увидем, что в наше консоль вывелось первое сообщение этого треда. [/code]
>>240869 Что касается frame, это главный элемент функции, на его основе мы определяем, что именно делать, прибавлять здоровье или же рисовать анимацию, а если анимацию, то какой именно её этап. Поэтому проверку frame мы поместим сразу в тело функции.
>>239609 >3)ПерсонажНейм защититься Подумав, я решил, что самым оптимальным было бы реализовать это через бафы. То есть, персонаж побеждает и получает возможность защититься, происходит анимация защиты и у него появляется баф защиты на несколько ходов, слегка или даже сильно уменьшающий урон, наносимый ему противниками.
Бамп, пока ничего не сделал. Думаю, в ближайшее время следует добавить в функцию создания игрока массив бафов с количеством ходов, на которые эти бафы распространяются, а также отображать иконки этих самых бафов.
Немного предыстории. Разрабатывать игры для макабы я начал около полугода назад, когда Абу открыл нам api. Идея была простой. На борде регулярно всплывали игровые треды с рулеточками, именуемые Захвати Странанейм-тред, в которых я также, как и многие из вас, принимал участие. Но играть всегда было не удобно, ведь уследить за большим количеством сообщений очень сложно. Поэтому было решено, во чтобы то ни стало упростить управление этой игрой. Так и началось моё первое знакомство с макабой. С тех пор игра эволюционировала, в ней появился отличный редактор уровней, трансляцию на ютубе, от которой наши модераторы очень бугуртили, заменила автоматическая отправка карты в тред, прокси и прочие костыли заменил простой плагин CORS Everywhere. В общем, много чего изменилось и за всё это время я получил огромный опыт в разработке игр для макабы.
Сегодня, на примере разработки очередной игры для макабы мы разберём основные этапы разработки и сложности, с которыми может столкнуться программист, разрабатывающий игру для владельцев девайсов, поддерживающих макабу.
Вопросы можете задавать по ходу. Буду постепенно описывать этапы разработки.