Недавно у нас с другом зашел разговор о карточных играх. Он сказал, что умеет играть только в покер, но и то давно этого не делал, потому что забыл все комбинации. Вот и поговорили… Я вспомнил, что пару лет назад я написал пять карточных игр, включая покер Техасский Холдем, где в любой момент в процессе игры можно посмотреть не только собранные комбинации, но и все потенциально возможные варианты с еще не открытыми картами. Это вполне могло бы стать обучающим пособием и помочь освежить в памяти правила в процессе игры с ботами.
Я решил заняться рефакторингом своего старого кода, а также, подправить графику. Дизайн мне всегда давался с трудом, это не мое. Рассчитывая хоть на какое-то вдохновение, я включил саунд-трек из GTA San-Andreas, тот, что с кантри-музыкой, с радио K-Rose. Мне кажется, что он хорошо передает атмосферу Лас-Вегаса. Я там никогда не был, но точно передает! Клянусь своей звездой шерифа. (Если что — она пластиковая, так что, не жалко...) И даже не поленился зайти в саму легендарную игру и прокатиться по Лас-Вентурасу, виртуальному прототипу мировой игорной столицы.
Да, я в курсе, что Лас-Вегас находится в Неваде, а не в Техасе. Но подобные игры ассоциируются, все-таки, прежде всего, с Вегасом. Техасский Холдем был привезен туда и после этого обрел широкую популярность. Вегас — это продюсер для игр.
Пару лет назад я почему-то разместил свою игру только в магазине Windows Store, который не пользуется большой посещаемостью. Хотя, возможно, скоро, в связи с прекращением поддержки Windows 7 и массовым переходом на 10, этот магазин приложений получит второе дыхание. Желаем ему удачи и держим за него кулачки в Вегасе. Но речь в статье не об этом, а о втором дыхании моей игры. Она написана на чистом Javascript, и я решил, что сегодня она вполне могла бы работать в качестве браузерного расширения для Chrome и Firefox из соответствующих магазинов дополнений, а также в виде сборки под Windows 7-10 на базе Chrome.
Игра называется «Покер 3 мешка» («Poker 3 Bags») и включает пять игр: «Покер Техасский Холдем», «Подкидной дурак», «Чешский дурак», «Три палки» и мою авторскую игру «3 мешка». Доступны только игры с ботами на локальном компьютере.
Кантри
Так вот, по поводу кантри-музыки. Мелодии из GTA San-Andreas навели меня на мысль о том, что неплохо было бы добавить в игру немного ковбойской тематики: ведь, Покер Техасский Холдем здесь будет главной игрой. Я разместил ковбойскую шляпу и пистолеты на заставке во время раскладывания карт.
Firefox
А также — маленькую иконку шляпы слева от названия игры в главном меню.
Google Chrome
И еще шляпа будет отображаться на аватарке победителя. Общий дизайн, этакий клоунский, я решил принципиально не менять.
Улучшения
Помимо графических элементов, в игре преобразился и код. Я перевел все на новую версию своего движка. Впрочем, движок — это слишком громко сказано по отношению к данной игре. Движок поддерживает 3D графику, а здесь — только полеты спрайтов игральных карт по плоскости. Но зато я оптимизировал анимацию и сделал ее многопоточной. (Конечно же, в javascript нет реальной многопоточности, по крайней мере, при работе с окном браузера. Параллельность достигается методом последовательного перебора итераций всех анимаций при каждом вызове.)
Стало больше возможностей. Во-первых, появилось внутриигровое меню, из которого теперь можно управлять масштабом изображения. Например:
var scaleValue=0.5;
var scale = 'scale('+scaleValue+')';
document.body.style.webkitTransform = document.body.style.msTransform = document.body.style.transform = scale;
Это позволило вписать изображение в окно браузера при любом доступном размере. Функция работает совместно с событием изменения размера окна, предварительно вычисляется нужный масштаб. Последний можно подстроить и вручную. Раньше у меня на компьютере эта игра выглядела слишком мелко, а на телефоне — слишком крупно и появлялись полосы прокрутки. Наконец, эта проблема решена. Правда, теперь, вероятно, придется прикрутить к игре второй интерфейс — портретный, для мобильных устройств, особенно, для телефона… Размер браузерной строки, отъедающей огромную часть экрана на телефоне, тоже не радует. Но есть кнопка разворачивания игры на полный экран.
Android 7.0 и Windows 8.1
Второе. Я доработал покер Техасский Холдем. Теперь доступна ставка «ва-банк» («all-in»), которой раньше не было, а также, выбор размера ставки вручную. Фишки во всех играх стали двигаться более реалистично и в соответствии со своим номиналом: то есть, например, если сделать ставку 15, то на стол от игрока уедут две фишки — 5 и 10, образуя там некую кучу. Раньше двигалась просто одна условная фишка. Кроме того, теперь могут играть не 4, а до 10 игроков. Ну и прочие мелкие улучшения, на которых, пожалуй, не стоит останавливаться.
Техническая часть
Как я уже упомянул, игра написана на чистом Javascript без использования каких-либо сторонних библиотек (даже JQuery не используется). Есть только одна, моя, библиотека, которая реализует функции отображения интерфейса на теге canvas. Собственно, весь игровой контент — это часть интерфейса. В последнем у меня существует такое понятие как «меню с подложкой». Например, можно для меню «Выход», состоящего из единственной одноименной кнопки, использовать в качестве «подложки» сам игровой стол. И достаточно будет отобразить это меню, чтобы на канвасе появился стол и кнопка. Причем, кнопка не обязательно должна лежать на подложке — можно и рядом. Или, например, подложки может не быть вовсе. Кроме того, для каждого меню можно отображать сопутствующие спрайты, или «сателлиты», не являющиеся кнопками. Для них, равно как и для кнопок, задаются относительные координаты.
Дерево документа (DOM) представляет собой растянутые на величину окна браузера два блока canvas с абсолютным позиционированием. Все спрайты, как того и требует canvas, отображаются при помощи drawImage(). На нижнем слое лежит фон (градиент) и элементы интерфейса, а верхний слой используется для анимации. Конечно, можно было бы и ограничиться всего двумя слоями, но я решил добавить еще два. Так в моем ui-движке конструируется DOM:
m3d.ui.initHtml([
m3d.ui.htmlCanvas('canvbk'),
m3d.ui.htmlControlsHand(),
m3d.ui.htmlDiv('help', 0,0),
m3d.ui.htmlCanvas('canvblack')
]);
- htmlCanvas — это слой с канвасом по размеру окна браузера; его имя ('canvbk') используется для того, чтобы можно было отключить слой, если нужно (в случае с этим элементом не требуется никогда). Данный блок — для отображения фонового градиента и интерфейса.
- htmlControlsHand — это такой же блок с канвасом, расположенный уже выше первого, только на него еще навешиваются обработчики клика и тача. Имя не требуется, подобный элемент должен быть в DOM только один. Он же в данном приложении используется для анимации спрайтов (но можно и любой другой или несколько одновременно).
- htmlDiv — это простой div-элемент с id='help', также, на все окно, с абсолютным позиционированием. Используется для отображения правил игры. Он может включаться и выключаться (при поиске по id и установке display='block', display='none' или можно так: m3d.ui.layersDiv.help.div.style.display='block'; ). Для слоев типа htmlDiv задаются какие-то начальные размеры (ширина, высота). Но они далее меняются в коде, в зависимости от контента, который туда будет помещаться, поэтому в начале можно задать (0,0).
- htmlCanvas('canvblack') — еще один canvas, лежащий поверх всех. Он используется просто для эффекта затенения и «прояснения» картинки при входе и выходе из игр. А затем выключается.
Таким образом, постоянно включенными остаются только два нижних слоя. Все элементы, заданные через m3d.ui.initHtml, обрабатываются функцией ресайза и при изменении размера окна браузера подстраиваются под него.
Движок анимации тоже свой. Его функция заключается в изменении параметров, от заданных начальных до конечных значений, за заданное время. Это могут быть, например, координаты по двум осям (для 3D — по трем) и угол вращения. Вообще, количество параметров для одной анимации не ограничено, и можно придумать формулу изменения чего угодно. Наконец, в коллбек-функцию, где производится позиционирование спрайта, передаются текущие значения всех параметров с частотой, зависящей от вычислительной мощности системы. Может падать fps, но общее время анимации будет неизменно. Верхний канвас принимает события клика (и тача для мобильных устройств) с определением по координатам, на какую кнопку интерфейса пришлось нажатие.
Анимация работает так. Объект, который требуется двигать, удаляется с нижнего слоя (объект должен быть «сателлитом», который просто выключается), весь интерфейс, то есть, все открытые «меню с подложкой» перерисовываются (соответственно, сателлита там уже нет, он удален), объект поднимается на верхний слой, там движется, затем исчезает и, наконец, падает на нижний слой, где либо привязывается к другому «меню с подложкой» как сателлит, либо — к тому же, но с другими относительными координатами. Меню на нижнем слое снова перерисовывается. Функция совмещения контента слоев отдана на откуп браузеру, он это делает нативно. DOM в процессе игры никак не изменяется и всегда состоит, собственно, из двух канвасов, наложенных один на другой. Разве что при изменении размера окна браузера, весь контент перерисовывается 1 раз, уже в новом масштабе.
Все работает в Windows и Android в Chrome и Firefox. Как с локального сервера, так и из файловой системы путем открытия index.html. В IE11 уезжает верстка. Похоже, что там как-то неправильно определяются размеры канвасов или масштаб, что приводит к появлению полос прокрутки. Хотя, сама игра работает нормально. Я не стал с этим разбираться: вряд ли кто-то будет пользоваться данным устаревшим браузером. В древней версии Edge все работает нормально.
IE11
В iOS (+MacOS) и Linux не тестировал, но не вижу причин, чтобы там не работало, поскольку все сделано очень просто.
По поводу локализации. Поддерживаются 2 языка — русский и английский. Переключаются по клику на флажок в главном меню. Технически это реализовано в виде двух js-файлов с ассоциативными массивами фраз на разных языках, плюс — различные картинки, в том случае, если какой-то текст встроен в изображение: например, утопленный или градиентный текст.
Поделись с миром
Я не смог придумать ничего лучше, кроме как пойти в магазины браузерных расширений для Chrome и Firefox. Ну и еще сделал сборку под Windows на базе Chrome.
Данная версия игры — это, скорее, демка. Она требует дальнейшей доработки. Планируется триальная версия, с тремя играми, на 30 дней. И платная версия, с пятью играми, без ограничений. В последней также будет возможность делать ставку «all-in» в покере, а также, там будет учитываться старшинство карт комбинаций при определении победителя. Сейчас в демоверсии — три игры и нет временных ограничений. Позже данная демоверсия превратится в триальную и будет выпущена еще одна версия, уже полная.
Браузерное расширение
Итак, первым делом я решил разместить игру в магазинах дополнений Chrome и Firefox. У меня есть аккаунты разработчика и некоторый опыт, поскольку я уже размещал там там одно свое браузерное расширение. Кстати, если у кого-то есть ChromeOS, то было бы интересно узнать, работает ли моя игра там. У меня возможности проверить нет.
Есть два варианта отображения контента расширения — в окне поверх интерфейса браузера или в отдельной вкладке. Поскольку контент занимает довольно большую площадь и будет сильно загораживать текущую открытую вкладку, то я выбрал второй вариант.
В создании браузерного расширения на основе веб-странички, которую, по сути, и представляет собой моя игра, нет ничего сложного. Нужно только добавить файл манифеста, иконки и скриншоты. В Chrome Webstore можно добавить также видео с игровым процессом, что я и сделал. Затем снял еще одно видео, уже с Firefox:
Браузерное дополнение Firefox
Объем архива составил 4,8 Мб. Игра в распакованном виде — 5,2 Мб. Большую часть объема, конечно же, заняла графика. Код самой игры абсолютно одинаковый для обоих браузеров, отличается только десятком строк обвязки, отвечающей за открытие вкладки с игрой по клику на иконку игры на панели браузера справа от командной строки.
Поскольку дополнение не требует никаких особых разрешений вообще и ему не нужен доступ ни к какому серверу и персональным данным, то модерация в обоих магазинах прошла практически мгновенно, в день размещения.
Исполняемый файл под Windows и другие версии
Сборку на движке Chrome я создал при помощи простейшей утилиты под Windows Web2Exe и загрузил в магазины Itch и Indiexpo, в которых уже присутствует одна из моих игр. Размер такой сборки составил 115 Мб. А после упаковки программой для создания инсталляторов дистрибутив для скачивания получился объемом 40 Мб.
Сборка под Windows 7 — 10
В Магазине Windows Store в виде приложения Windows 10 я пока эту версию игры не размещал, хотя у меня там есть аккаунт разработчика. Я уже давно, пару лет назад, снес Visual Studio. Причем, там была интересная история. У меня на планшете лицензионная Windows 8.1 и она меня полностью устраивает. А на компьютере — Windows 10. Начиная с какой-то версии Visual Studio — вот здесь я уже точно не помню — либо вообще не дает создать javascript-приложение с поддержкой Windows 8.1, либо не хочет встраивать в него рекламу, если оно рассчитано, кроме «десятки», еще и на более старую Windows 8.1 (а хотелось бы иметь потенциальную возможность монетизации). В общем, я уже забыл, что именно там было, но какая-то проблема точно была связана с ограничениями поддержки 8.1. А понятно же, что свою игру из этого магазина скачаю только я, и мне бы хотелось иметь возможность поиграть в нее на своем планшете. Сам магазин, по-моему, никак не продвигает приложения. И вот я еще не решил, так ли сильно я хочу снова ставить огромную Visual Studio на 32Гб MicroSD карточку на планшете… Аккаунт разработчика работает только с него. А, может быть, взвесив все за и против и учитывая количество посетителей магазина Microsoft, просто продолжать писать код в подобии блокнота и не связываться с гигантскими средами разработки вообще? Жаль, что там нельзя просто загрузить архив с приложением через форму на сайте, как это реализовано, например, для браузерных расширений.
В ближайшее время я планирую разместить игру как i-frame приложение в социальных сетях ВКонтакте и Facebook. По их правилам требуется еще прикрутить в игре какие-нибудь социальные функции типа таблицы рейтингов лучших игроков и так далее.
Возможно, еще стоит посмотреть в сторону Google Play Market. Насколько я знаю, там теперь можно размещать PWA (Progressive Web Apps). Но у меня нет аккаунта разработчика и я с этим пока еще не разбирался. С другой стороны, PWA можно разместить и на своем сайте, с которого игра будет устанавливаться на телефон, создаваться иконка, и все будет выглядеть как обычное Android-приложение. В Стор, скорее всего, имеет смысл идти только с большим рекламным бюджетом, которого у меня нет. В общем, игры на мобильных устройств пока еще нет. Думаю, что я просто размещу ее на сайте, чтобы играть через браузер и устанавливать как приложение PWA, чтобы не зависеть от подключения к сети.
Да, это радует, что Google Play так же, как и Microsoft Store, дает возможность загружать приложения, написанные на Javascript. Мне в свое время эта фича понравилась в магазине Microsoft. Жаль, что последний не особо популярен. А так удобно — загрузил туда всего 5,2 Мб (то есть, javascript-код и картинки) — и готово. Без всяких там больших обвязок и дополнительных библиотек. А браузер используется из установленных в системе. В идеале еще бы предоставить пользователю возможность выбирать, какой браузер будет работать в качестве «плеера» для игры. Microsoft, как я помню, при скачивании такого приложения из магазина предлагал только IE11. Во всяком случае, та, старая версия моей игры запускалась именно в нем. Впрочем, сейчас, когда они переходят на движок от Google, возможно, разницы уже нет. Кстати, Chrome лучше, чем IE11, работает с 3D графикой WebGL… Но это уже не касается игры, о которой идет речь в этой статье.
Итог
В целом, эта игра — тренажер. Онлай-игры нет, можно только попрактиковаться с ботами. Главное здесь — просмотр комбинаций, которые вы собрали и можете потенциально собрать. Для этого достаточно нажать на кнопку меню со знаком вопроса или на свои карты. Готовые комбинации отмечены зеленым кружком справа, потенциально возможные содержат в своем составе затемненные карты, которые еще могут прийти из колоды. Наконец, учитывая наличие в комплекте и других игр, данную программу можно использовать, например, в качестве заменителя наскучивших пасьянсов. Программа автономна как в виде сборки под Windows, так и в виде браузерного дополнения, и для своей работы не требует подключения к Интернет.
Напоследок: чеклист
Места, где хотелось бы разместиться, и где это уже сделано:
+ Магазины браузерных расширений
— Главные магазины игр под Windows (Steam)
+ Второстепенные магазины игр под Windows
— Мобильные сторы
— Социальные сети
— Веб-сайт
Add-on в Firefox
Автор: Юрий