Flash постепенно отвергается Adobe в пользу HTML5 и JavaScript;
. Советы, описанные ниже, направлены на то, чтобы помочь разработчикам игр HTML5 избегать распространенных ошибок при конвертации флеш-игр в JavaScript, а также сделать весь процесс разработки максимально плавным. Все, что вам нужно, — это базовые знания JavaScript, WebGL и рамки Phaser.
Изменение дизайна игры с SWF на JavaScript может дать лучший пользовательский интерфейс, который, в свою очередь, придает ему современный вид. Но как это сделать? Вам нужен специальный конвертер для JavaScript, чтобы избавиться от этой устаревшей технологии? Ну, преобразование Flash в HTML5 может быть куском пирога — вот что может сказать опытный разработчик JavaScript-игр.
. Преобразование игры на другую платформу — отличная возможность улучшить ее, исправить ее проблемы и увеличить аудиторию. Ниже перечислены несколько вещей, которые можно легко сделать и заслуживают рассмотрения:
Поддержка мобильных устройств Преобразование из Flash в JavaScript позволяет охватить более широкую аудиторию — пользователей мобильных устройств поддержка сенсорных экранов обычно должна быть реализована в игре. К счастью, как Android, так и iOS-устройства теперь также поддерживают WebGL, поэтому можно легко добиться 30 или 60 FPS-рендеринга. Во многих случаях 60 FPS не вызовут никаких проблем, которые со временем улучшатся, поскольку мобильные устройства становятся все более и более эффективными.
Улучшение производительности Когда дело доходит до сравнение ActionScript и JavaScript, последнее быстрее. Помимо этого, преобразование игры — хороший повод пересмотреть алгоритмы, используемые в игровом коде.
Исправление ошибок и улучшение игрового процесса Наличие новых разработчиков, изучающих исходный код игры может помочь исправить известные ошибки или обнаружить новые и очень редкие. Это сделало бы игру менее раздражающей для игроков, что заставит их тратить больше времени на вашем сайте и побудить их попробовать другие игры.
Добавление веб-аналитики В Помимо отслеживания трафика, веб-аналитика также может быть использована для сбора информации о том, как игроки ведут себя в игре и где они застревают во время игры.
Добавление локализации Это увеличится аудитория и важна для детей из других стран, играющих в вашу игру. Или, может быть, ваша игра не на английском языке, и вы хотите поддержать этот язык?
02. Достигните 60 FPS
Когда дело доходит до разработки JavaScript-игр, может возникнуть соблазн использовать HTML и CSS для игровых кнопок, виджетов и других элементов графического интерфейса. Наш совет — быть осторожным здесь. Это противоречиво, но на самом деле использование элементов DOM менее эффективно в сложных играх, и это приобретает большее значение для мобильных устройств. Если вы хотите достичь постоянной 60 FPS на всех платформах, может потребоваться отставка из HTML и CSS.
Неактивные элементы GUI, такие как бары здоровья, патроны или счетчики очков, могут быть легко реализованы в Phaser используя обычные изображения (класс «Phaser.Image»), используя свойство «.crop» для обрезки и класс «Phaser.Text» для простых текстовых меток.
. Интерактивные элементы, такие как кнопки и флажки, могут быть реализованы с использованием встроенного класса «Phaser.Button». Другие, более сложные элементы могут состоять из разных простых типов, таких как группы, изображения, кнопки и текстовые метки.
03. Загрузка пользовательских шрифтов
Если вы хотите визуализировать текст с помощью пользовательского векторного шрифта (например, TTF или OTF), вам необходимо убедиться, что шрифт уже загружен браузером перед тем, как передать какой-либо текст. Phaser v2.6 не предоставляет решения для этой цели, но можно использовать другую библиотеку — Web Font Loader.
Предполагая, что у вас есть файл шрифта и на вашем веб-сайте есть веб-загрузчик шрифтов, ниже это простой пример загрузки шрифта. Создайте простой файл CSS, который будет загружен Web Font Loader (вам не нужно включать его в свой HTML):
@ font-face {
// Это имя вы будете использовать в JS
font-family: «Gunplay»;
// URL-адрес файла шрифта, может быть относительным или абсолютным
src: url ('../ fonts / gunplay.ttf') format ('truetype');
font-weight: 400;
}
Теперь определите глобальную переменную с именем WebFontConfig. Проще всего этого будет достаточно:
var WebFontConfig = {
'classes': false,
'timeout': 0,
'active': function () {
// Шрифт успешно загружен ...
},
'custom': {
«семьи»: ['Gunplay'],
// URL-адрес ранее упомянутого CSS
'urls': ['styles/fonts.css']
}
};
Не забудьте указать код в активном обратном вызове, показанном выше. Вот и все!
04. Сохраните игру
Теперь мы находимся в средней точке нашего преобразования Flash в JavaScript — пришло время позаботиться о шейдерах. Чтобы настойчиво хранить локальные данные в ActionScript, вы должны использовать класс «SharedObject». В JavaScript простая замена — это localStorage API, который позволяет хранить строки для последующего извлечения, выжившие перезагрузки страниц.
Сохранение данных очень просто:
var progress = 15;
localStorage.setItem ('myGame.progress', progress)
Обратите внимание, что в приведенном выше примере переменная «progress», которая является числом, будет преобразована в строку.
Загрузка также проста, но помните, что полученные значения будут нитями или нулями, если они не существуют.
var progress = parseInt (localStorage.getItem ('myGame.progress')) | | 0;
Здесь мы гарантируем, что возвращаемое значение является числом. Если это не существует, то 0 будет присвоено переменной «progress».
Вы также можете хранить и извлекать более сложные структуры, например JSON:
В некоторых случаях объект «localStorage» недоступен. Например, при использовании протокола file: // или при загрузке страницы в частном окне. Вы можете использовать оператор «try and catch», чтобы ваш код продолжал работать и использовать значения по умолчанию, которые показаны в следующем примере:
try {
var progress = localStorage.getItem ('myGame.progress');
} catch (исключение) {
// localStorage недоступен, используйте значения по умолчанию
}
Еще одна вещь, которую следует помнить, состоит в том, что сохраненные данные сохраняются для каждого домена, а не для каждого URL-адреса. Поэтому, если существует риск того, что многие игры размещаются в одном домене, тогда лучше использовать префикс (пространство имен) при сохранении. В приведенном выше примере «myGame». является префиксом, и вы обычно хотите заменить его именем игры.
Если ваша игра встроена в iframe, то localStorage не будет сохраняться в iOS. В этом случае вам нужно будет хранить данные в родительском iframe.
05. [1945905]
Пользовательский шейдер по умолчанию может использоваться для замены метода тонирования в Phaser и PixiJS. Танки мигают белым при попадании
Когда Phaser и PixiJS визуализируют ваши спрайты, они используют простой внутренний шейдер фрагмента. Он не имеет много функций, поскольку он предназначен для скорости. Однако вы можете заменить это шейдер для ваших целей. Например, лет u может использовать его для проверки overdraw или поддержки дополнительных функций для рендеринга. Ниже приведен пример того, как предоставить свой собственный шейдер фрагмента по умолчанию для Phaser v2.
function preload () {
this.load.shader ('filename.frag', 'shaders / filename.frag');
}
function create () {
var renderer = this.renderer;
var batch = renderer.spriteBatch;
batch.defaultShader =
новый PIXI.AbstractFilter (this.cache.getShader ('filename.frag'));
batch.setContext (renderer.gl);
}
06. Изменение способа тонирования
Пользовательский шейдер по умолчанию может использоваться для замены методов тонирования в режиме Phaser и PixiJS. Тонирование в Phaser и PixiJS работает путем умножения пикселей текстуры на заданный цвет. Умножение всегда затемняет цвета, что, очевидно, не является проблемой; это просто отличается от тонировки Flash. Для одной из наших игр нам нужно было выполнить тонирование, подобное Flash, и решил, что можно использовать настраиваемый шейдер по умолчанию. Ниже приведен пример такого фрагментарного шейдера:
// Специфический вариант оттенка, похожий на флеш-оттенок, который добавляет
// к цвету и не умножается. Отрицательный цвет
// необходимо, чтобы этот шейдер работал правильно, т. е. устанавливал
// sprite.tint to 0, чтобы превратить весь спрайт в белый.
прецизионный lowp float;
переменная vec2 vTextureCoord;
изменение vec4 vColor;
равномерный пробоотборник2D uSampler;
void main (void) {
vec4 f = texture2D (uSampler, vTextureCoord);
float a = clamp (vColor.a, 0.00001, 1.0);
gl_FragColor.rgb = f.rgb * vColor.a + clamp (1.0 - vColor.rgb / a, 0.0, 1.0) * vColor.a * f.a;
gl_FragColor.a = f.a * vColor.a;
}
Этот шейдер освещает пиксели, добавив базовый цвет в оттенок. Чтобы это работало, вам нужно предоставить негативы цвета, который вы хотите. Поэтому, чтобы получить белый цвет, вам нужно установить:
sprite.tint = 0x000000; // Это окрашивает спрайт в белый цвет
Sprite.tint = 0x00ffff; // Это дает красный
07. Inspect overdraw
На рисунке слева показано, как игрок видит игру, а справа — эффект применения overwraw shader to the same scene
Замена стандартного шейдера также может быть использована для помощи при отладке. Ниже мы объяснили, как overdraw можно обнаружить с помощью такого шейдера.
Overdrawing происходит, когда многие или все пиксели на экране отображаются несколько раз. Например, многие объекты занимают одно и то же место и оказываются друг над другом. Сколько пикселей, которые GPU может отображать в секунду, описывается как скорость заполнения.
Существует простой способ узнать, сколько раз каждый пиксель на экране записывается путем замены глобального фрагмента по умолчанию shader в PixiJS и Phaser с этим:
Этот шейдер освещает обрабатываемые пиксели. Число 7.0 указывает, сколько записей требуется для отображения белых пикселей; вы можете настроить этот номер по своему вкусу. Другими словами, более легкие пиксели на экране были написаны несколько раз, а белые пиксели были написаны как минимум семь раз.
Этот шейдер также помогает находить оба «невидимых» объекта, которые по какой-то причине все еще отображаются, и спрайты которые имеют чрезмерные прозрачные области вокруг, которые необходимо удалить (графический процессор все еще нуждается в обработке прозрачных пикселей в ваших текстурах).
08. Почему физики двигатели ваши друзья
Левая часть изображения — это сцена из игры, а правая сторона показывает то же самое сцена с наложением отладки физики Phaser, отображаемым сверху
Физический движок — это промежуточное программное обеспечение, которое отвечает за моделирование физических тел (как правило, жесткой динамики тела) и их столкновений. 2D или 3D пространства, но n от обоих. Типичный физический двигатель обеспечит:
Движение объекта путем задания скоростей, ускорений, суставов и двигателей
Обнаружение столкновений между различными типами фигур
Расчет столкновения ответы, то есть, как два объекта должны реагировать, когда они сталкиваются.
Существует плагин Phaser, который хорошо работает для этой цели. Box2D также используется в игровом движке Unity и GameMaker Studio 2.
В то время как физический движок ускорит вашу разработку, вам придется заплатить цену: снижение производительности во время выполнения. Обнаружение столкновений и вычисление ответов — задача, требующая большого количества ресурсов. Вы можете ограничить несколько десятков динамических объектов в сцене на мобильных телефонах или ухудшить качество изображения, а также снизить частоту кадров ниже 60 FPS.
09. Экспорт звуков
Если у вас есть звуковые эффекты Flash-игры внутри файла .fla, то экспортировать их из графического интерфейса невозможно (по крайней мере, не в Adobe Animate CC 2017) из-за отсутствия параметров меню, обслуживающих этот цель. Но есть еще одно решение — специальный скрипт, который делает именно это:
function normalizeFilename (name) {
// Преобразует имя camelCase в имя snake_case
return name.replace (/ ([A-Z]) / g, '_ $ 1'). replace (/ ^ _ /, '') .toLowerCase ();
}
function displayPath (path) {
// Делает путь к файлу более понятным
return unescape (path) .replace ('file: ///', '') .replace ('|', ':');
}
fl.outputPanel.clear ();
if (fl.getDocumentDOM (). library.getSelectedItems (). length> 0)
// Получить только выбранные элементы
var library = fl.getDocumentDOM (). library.getSelectedItems ();
еще
// Получить все предметы
var library = fl.getDocumentDOM (). library.items;
// Запросить пользователя для каталога назначения экспорта
var root = fl.browseForFolderURL ('Выберите папку.');
var errors = 0;
for (var i = 0; i <library.length; i ++) {
var item = library [i];
if (item.itemType! == 'sound')
Продолжить;
var path = root + '/';
if (item.originalCompressionType === 'RAW')
path + = normalizeFilename (item.name.split ('.') [0]) + '.wav';
еще
path + = normalizeFilename (item.name);
var success = item.exportToFile (путь);
если (! успех)
ошибки + = 1;
fl.trace (displayPath (путь) + ':' + (успех? 'OK': 'Error'));
}
Как использовать скрипт для экспорта звуковых файлов:
Сохраните код выше как .jsfl файл на вашем компьютере.
Откройте файл .fla с Adobe Animate.
Выберите «Команды»> «Выполнить команду» в верхнем меню и выберите сценарий в открывшемся диалоговом окне.
Теперь появляется другой файл диалога для выбора каталога назначения экспорта.
Все готово! Теперь вы должны иметь WAV-файлы в указанном каталоге. Осталось только преобразовать их, например, в MP3, OGG или AAC.
10. Как использовать MP3-файлы
Хороший старый формат MP3 вернулся, так как некоторые патенты истекли, и теперь каждый браузер может декодировать и воспроизводить MP3. Это делает разработку немного легче, так как, наконец, нет необходимости готовить два отдельных аудиоформата. Раньше вам нужны, например, файлы OGG и AAC, в то время как теперь MP3 будет достаточным.
Тем не менее, есть две важные вещи, которые вам нужно запомнить о MP3:
MP3s необходимо декодировать после загрузки, что может занять много времени, особенно на мобильных устройствах. Если вы заметили паузу после загрузки всех ваших активов, это, вероятно, означает, что MP3-файлы декодируются
. Беззаботно воспроизводящиеся петлевые MP3-файлы немного проблематичны. Решение состоит в том, чтобы использовать mp3loop, читайте больше в этой статье, опубликованной Compu Phase.
Эта статья была первоначально опубликована в выпуске 277 журнала веб-дизайна Creative Web Designer. Здесь выдается номер 277 или . .