Разработка игры Egret: Стрельба

внешний интерфейс

Некоторое время назад, для продвижения нового официального аккаунта, была разработана небольшая игра под названием "Мастер стрельбы" (которая была оффлайн), после выхода она дала хорошие результаты и успешно привлекла множество поклонников для официального аккаунта. Позвольте мне поделиться с вами процессом разработки этой игры.

анализ спроса

Сама игра на самом деле очень проста, это всего лишь игра-стрелялка, которая реализует проекцию баскетбольного мяча, движение корзины, столкновение между баскетбольным мячом и корзиной, запись в таблице лидеров после игры и идентификацию публичный аккаунт. Однако, поскольку игра является 2D-игрой, она имеет эффект имитации 3D (баскетбольный мяч отдаляется от нас все дальше и дальше и после броска проникает в сетку), и в то же время обнаружение столкновений между баскетбольным мячом и мячом корзина должна быть выполнена, и должен быть смоделирован плавный и естественный эффект отскока, поэтому вам нужно продолжать заполнять отверстие.

Технический отбор

Учитывая скорость разработки, очень важно найти зрелый и хорошо документированный движок для разработки игр HTML5.Большинство людей в Китае используют Cocos2d-x-js или Egret, Phaser или Hilo, в которых отсутствуют относительно удобные инструменты разработки. производительность Cocos в Интернете не идеальна, поэтому я, наконец, выбрал Egret 2D.

Что касается физического движка, Egret рекомендует использовать движок P2, так как его производительность лучше, чем у Box 2D или Matter.js, но недостатком является отсутствие китайских документов, я сейчас в процессе перевода, адресный штамп 👉Китайская документация P2

Реализовать идеи

  • Псевдо 3D-движение

    1. Отображение близко к большому и далекому к маленькому

Визуальный фокус устанавливается с начальным положением (или дном) баскетбольного мяча в качестве источника, а коэффициент масштабирования баскетбольного мяча рассчитывается в соответствии с положением баскетбольного мяча по оси Y во время движения баскетбольного мяча. Формула расчета: следующим образом:

 ``scale = (curY - startY) / ( endY - startY);``

Кроме того, в мире физики любое твердое тело является физической моделью той же формы и размера, а это означает, что мы можем масштабировать текстуру баскетбольного мяча, но не твердое тело баскетбольного мяча.
Чтобы сделать размер баскетбольного мяча точным при столкновении баскетбольного мяча и корзины, мы можем рассчитать пропорцию баскетбольного мяча, когда он достигает корзины (положение корзины определено, и пропорция должна быть зафиксирована) в соответствии с формула масштабирования на рисунке выше, в начальном положении Сохраняйте текстуру баскетбольного мяча и твердое тело в таком соотношении, чтобы, когда баскетбольный мяч перемещается к кольцу, размер точно соответствовал фактическому размеру его твердого тела.

  1. Взаимодействие между баскетбольным мячом и кольцом

    Когда баскетбольный мяч поднимается, в двухмерном физическом мире баскетбольный мяч и корзина фактически находятся в одной плоскости, и твердые тела мяча и корзины по умолчанию сталкиваются. быть больше корзины при подъеме и меньше корзины при падении.

    Чтобы решить первую проблему, можно использовать группировку коллизий, предоставляемую 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 обновляет кадр, она выполняет четыре шага. Создавая игру, вы должны четко помнить, что делают четыре шага.

    1. Мы запускаем EnterFrame, после чего движок выполняет логику игры. И сбросить событие EnterFrame.
    2. Выполните очистку. Сотрите все изображения предыдущего кадра.
    3. Ядро Egret обходит все объекты DisplayObject в вашей игровой сцене и пересчитывает преобразования всех объектов отображения.
    4. Если вы коснулись холста, то знаете, что на этом шаге все изображения будут нарисованы на холсте.

渲染示意图
Схема визуализации

Поняв механизм рендеринга 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, если браузер его не поддерживает.