Некоторое время назад, для продвижения нового официального аккаунта, была разработана небольшая игра под названием "Мастер стрельбы" (которая была оффлайн), после выхода она дала хорошие результаты и успешно привлекла множество поклонников для официального аккаунта. Позвольте мне поделиться с вами процессом разработки этой игры.
анализ спроса
Сама игра на самом деле очень проста, это всего лишь игра-стрелялка, которая реализует проекцию баскетбольного мяча, движение корзины, столкновение между баскетбольным мячом и корзиной, запись в таблице лидеров после игры и идентификацию публичный аккаунт. Однако, поскольку игра является 2D-игрой, она имеет эффект имитации 3D (баскетбольный мяч отдаляется от нас все дальше и дальше и после броска проникает в сетку), и в то же время обнаружение столкновений между баскетбольным мячом и мячом корзина должна быть выполнена, и должен быть смоделирован плавный и естественный эффект отскока, поэтому вам нужно продолжать заполнять отверстие.
Технический отбор
Учитывая скорость разработки, очень важно найти зрелый и хорошо документированный движок для разработки игр HTML5.Большинство людей в Китае используют Cocos2d-x-js или Egret, Phaser или Hilo, в которых отсутствуют относительно удобные инструменты разработки. производительность Cocos в Интернете не идеальна, поэтому я, наконец, выбрал Egret 2D.
Что касается физического движка, Egret рекомендует использовать движок P2, так как его производительность лучше, чем у Box 2D или Matter.js, но недостатком является отсутствие китайских документов, я сейчас в процессе перевода, адресный штамп 👉Китайская документация P2
Реализовать идеи
-
Псевдо 3D-движение
- Отображение близко к большому и далекому к маленькому
Визуальный фокус устанавливается с начальным положением (или дном) баскетбольного мяча в качестве источника, а коэффициент масштабирования баскетбольного мяча рассчитывается в соответствии с положением баскетбольного мяча по оси Y во время движения баскетбольного мяча. Формула расчета: следующим образом:
``scale = (curY - startY) / ( endY - startY);``
Кроме того, в мире физики любое твердое тело является физической моделью той же формы и размера, а это означает, что мы можем масштабировать текстуру баскетбольного мяча, но не твердое тело баскетбольного мяча.
Чтобы сделать размер баскетбольного мяча точным при столкновении баскетбольного мяча и корзины, мы можем рассчитать пропорцию баскетбольного мяча, когда он достигает корзины (положение корзины определено, и пропорция должна быть зафиксирована) в соответствии с формула масштабирования на рисунке выше, в начальном положении Сохраняйте текстуру баскетбольного мяча и твердое тело в таком соотношении, чтобы, когда баскетбольный мяч перемещается к кольцу, размер точно соответствовал фактическому размеру его твердого тела.
-
Взаимодействие между баскетбольным мячом и кольцом
Когда баскетбольный мяч поднимается, в двухмерном физическом мире баскетбольный мяч и корзина фактически находятся в одной плоскости, и твердые тела мяча и корзины по умолчанию сталкиваются. быть больше корзины при подъеме и меньше корзины при падении.
Чтобы решить первую проблему, можно использовать группировку коллизий, предоставляемую P2, чтобы избежать коллизий.
В P2 твердому телу требуется одна или несколько форм для определения формы твердого тела, а форма имеет два атрибута: CollisionGroup и CollisionMask.Первый определяет группировку столкновений формы, а второй определяет, какие группы столкновений формируют форму. столкнется с. Следует отметить, что значение CollisionGroup — от Math.pow(2,0) до Math.pow(2,32).Группировка столкновений для фигур);
// 创建篮球刚体的形状 ballShape = new p2.Circle({radius: GlobalData.ballRadius / factor}); // 设置篮球的碰撞分组 ballShape.collisionGroup = this.FLYBALL; // 这样设置 collisionMask 篮球就能与篮筐交互,注意多个分组分隔的是 | 不是 || ballShape.collisionMask = this.BASKET | this.GROUND;Поэтому, когда баскетбольный мяч поднимается, установите его группу столкновения на FLYBALL, а его маску столкновения на землю. В это время баскетбольный мяч будет сталкиваться только с землей, а не с корзиной. Когда он падает, установите его группу на DROPBALL, а CollisionMask — это земля и корзина, в этот момент баскетбольный мяч столкнется с корзиной.
Чтобы решить вторую проблему, идея аналогична: установите подъем баскетбольного мяча на максимальное значение при подъеме и обменяйте значение глубины с корзиной при падении;
-
Идентификация по QR-коду
На веб-страницах WeChat часто необходимо предоставить функцию распознавания QR-кода при длительном нажатии, но QR-код должен быть реальным изображением.QR-код, встроенный в Canvas, не поддерживает распознавание при длительном нажатии.Чтобы WeChat мог распознавать Для изображений просто наложите изображение на холст. Схематическая диаграмма выглядит следующим образом:
При установке картинки размер нужно рассчитать и масштабировать в соответствии с размером браузера и фактическим размером Canvas, чтобы картинка выглядела так, как будто она вместе с Canvas;
-
текстовая копия
В требованиях к игре пользователю необходимо нажать кнопку, чтобы скопировать фрагмент текста и отправить его на официальный аккаунт, однако, поскольку у браузера разные разрешения на копирование текста, на рынке есть решение использоватьZeroClipBoard, но это не было учтено при разработке, используется document.execCommand('copy') и из-за совместимости выполняется откат.Когда браузер не поддерживает это, пользователю предлагается долгое нажатие на выделенный текст для копирования , В настоящее время это также связано с тем, что холст не поддерживает выделение текста, текст необходимо обрабатывать как QR-код и размещать на холсте;
оптимизация производительности
-
Оптимизация рендеринга
Каждый раз, когда Egret обновляет кадр, она выполняет четыре шага. Создавая игру, вы должны четко помнить, что делают четыре шага.
- Мы запускаем EnterFrame, после чего движок выполняет логику игры. И сбросить событие EnterFrame.
- Выполните очистку. Сотрите все изображения предыдущего кадра.
- Ядро Egret обходит все объекты DisplayObject в вашей игровой сцене и пересчитывает преобразования всех объектов отображения.
- Если вы коснулись холста, то знаете, что на этом шаге все изображения будут нарисованы на холсте.
Поняв механизм рендеринга Egret, мы знаем, с чего начать.
Во-первых, так как DisplayObject необходимо каждый раз обходить, невидимые объекты должны быть очищены, а создание объектов также требует накладных расходов, поэтому мы можем создать пул повторного использования для повторного использования невидимых объектов, что может уменьшить часть накладные расходы.;
Во-вторых, то, как Canvas определяет точки касания, состоит в том, чтобы пройти по всем точкам, чтобы определить, какая точка нажата.Когда мы устанавливаем сенсорный слой, мы должны перемещать его как можно выше, а не устанавливать его на объект, что может уменьшить накладные расходы, вызванные по обходу. .
Кроме того, в процессе разработки игры у меня под рукой было только iOS-устройство, и в процессе тестирования я обнаружил, что на Android-устройстве наблюдается серьезное явление выпадения кадров; когда я изменил размер холста с 6401136 до 480После 800 ситуация с заиканиями значительно улучшилась.Предполагается, что накладные расходы на рендеринг также увеличатся из-за слишком большого количества канвасов.Поэтому канвасу можно задать меньший размер в пределах допустимого диапазона, а браузер может масштабировать канвас до уменьшить накладные расходы на рендеринг.
-
рендеринг грязного прямоугольника
В случае сложного интерфейса пользовательского интерфейса алгоритм полноэкранного обновления будет обновлять все объекты пользовательского интерфейса 60 раз в секунду, а рендеринг грязного прямоугольника может обнаруживать измененные объекты и отображать только измененные объекты. В случае рендеринга грязного прямоугольника, в зависимости от того, что изменяет рисунок, в крайних случаях рисунок пропускается напрямую.В случае сложного пользовательского интерфейса очень легко достичь полного кадра.
Egret по умолчанию включает рендеринг грязных прямоугольников, но когда все экранные объекты постоянно двигаются, производительность в этом случае не очень хорошая. На этом этапе нам нужно отключить рендеринг грязных прямоугольников.
this.stage.dirtyRegionPolicy = "off"; -
WebGL-рендеринг
WebGL обеспечивает аппаратный 3D-ускоренный рендеринг для HTML5 Canvas, добавляя привязку JavaScript к OpenGL ES 2.0. Egret Engine2D поддерживает режим рендеринга WebGL. Просто включите рендеринг WebGL, чтобы получить аппаратное ускорение.
Egret автоматически переключится в режим рендеринга Canvas при включенном режиме рендеринга WebGL, если браузер его не поддерживает.