Представьте, новые возможности вашего игрового проекта готовы, протестированы и работают как положено, радуги и кавайные единороги наводняют ваше воображение, а улыбка расползается от щеки к щеке. Но… подождите, вдруг вы понимаете, что только что протестировали сборку для разработки, вы не тестировали производственную сборку, где Google Closure Compiler делает все свое волшебство, минимизируя, запутывая код и вызывая сбой некоторых вещей, которые отлично работают в сборке для разработки. До свидания, единороги :(

Принимая во внимание, что создание рабочей версии проекта — это не то, что вы делаете каждый день, это означает, что вы забываете о большинстве ошибок, которые вы получаете, а также запутываете весь код, изменяя 'this.myDescriptiveVariableName' на ' this.ck» может превратить задачу проверки того, что все работает нормально, в испытание, когда появляется загадочная ошибка.

Этот пост представляет собой руководство по основным проблемам, с которыми я столкнулся при экспорте проектов pixi.js с помощью Google Closure Compiler и его решений.



Использование новой библиотеки

Если вы добавили новую библиотеку, вы можете получить сообщение об ошибке, подобное этому:

Пример:ОШИБКА — переменная MSDFText не объявлена
message = new MSDFText.MSDFText(textString, textOptions);

Решение:

  • Создайте файл extern (в данном примере это будет файл msdftext-externs.js) и добавьте его в папку externs компилятора Google Closure вашего проекта. В этом примере это будет код для добавления в файл:
var MSDFText = {
 “MSDFText”: function(){}
}
  • Обязательно добавьте путь к новому файлу externs, созданному для объекта, другие файлы externs определены для Google Closure Compiler.
  • В идеальном мире было бы нормально, если бы библиотеки включали свои собственные файлы externs, обновленные и готовые к использованию, но это не всегда так. С другой стороны, есть некоторые генераторы externs, где вы предоставляете библиотеку и получаете сгенерированный файл externs, некоторые работают нормально, а некоторые нет.
  • Я также получил эту ошибку с новыми функциями pixi.js, такими как NineSlicePlane,некоторые фильтры, такие какcolorMatrix,и когда была добавлена ​​поддержка анимированных частиц. Решение для применения такое же, добавьте в файл pixi-externs.js:
// NineSlicePlane example, add this to "mesh" object
"NineSlicePlane": function () { }
// ColorMatrix pixi filter example, add this to "filters" object
"ColorMatrixFilter": {
 "contrast": function () { },
 "brightness": function () { },
 "hue": function () { },
 "saturate": function () { },
 "desaturate": function () { }
},
// Animated particles example
// Uncaught TypeError: Cannot read property ‘hasLoaded’ of undefined // (value.baseTexture.hasLoaded)
// Add “particleConstructor” and “AnimatedParticle” to "particles"
"particles": {
    "Emitter": {
        "scale": {
            "minimumScaleMultiplier": { }
        },
 "speed": {
            "minimumScaleMultiplier": { }
        },
 "spawnRect": {
            "x": { },
 "y": { },
 "w": { },
 "h": { }
        },
 "elapsed": { },
 "particleConstructor": function() { }
    },
 "AnimatedParticle": function() { }
}

Специальные параметры библиотек

При попытке доступа к определенному свойству из библиотеки:

Пример из MSDFText: Uncaught TypeError: Не удается прочитать свойство fontSize неопределенного

textObject.fontData.fontSize=25;

Решение А:

  • Замените все textObject.fontData на textObject[‘fontData’]:
textObject['fontData'].fontSize=25;

Решение Б (рекомендуется):

  • В файле externs библиотеки добавьте свойства:
var MSDFText = {
 "MSDFText": function(){},
 "numberFont": {},
 "fontData": {}
};


Параметры анимации TweenLite.to

Проблема, с которой я столкнулся, заключается в том, что анимация, созданная с помощью TweenLite.to, не обеспечивает ожидаемой простоты.

Решение:

  • Это связано с тем, что имя параметра ease (или другое, такое как alpha или что-то еще) не заключено в кавычки и не определено в каком-либо файле externs.js, связанном с TweenLite. Вы можете решить это, как описано в приведенном выше случае, но будьте осторожны, если вы используете свойства объекта из модели или представления, определенных в коде вашего проекта, вы не должны использовать кавычки.
TweenLite.to(myObjectToAnimate, seconds,{'y':posY, 'ease': 'Elastic.easeOut' });

Сбой при записи объектов

Если мы читаем данные, переданные нашей игре с сервера в формате JSON, точечная нотация приводит к сбою Google Closure Compiler. Вместо этого нам нужно использовать нотацию с квадратными скобками, чтобы свойство читалось как строка (Google Closure Compiler не запутывает строки).

Пример:Uncaught TypeError: невозможно прочитать свойство gameEnded неопределенного

this.bc.ll=s[o.ut].gameEnded

Решение:

  • В этом примере этот нечитаемый текст на самом деле выглядит следующим образом: this.gameModel.gameEnded=data[GameData.STATE].gameEnded, где мы сохраняем свойство gameEnded, полученное из данных сервера. .
this.gameModel.gameEnded=data[GameData.STATE][‘gameEnded’];

Тихий сбой сеттеров

Ошибки нет, в моем случае проблема возникла из-за функции, целью которой было определить текстовую строку и вывести ее на экран. Текст не был напечатан в игре.

Проблема связана с тем, что Google Closure Compiler не полностью совместим с функциями установки, которые делают больше, чем просто присваивают переменной значение. На самом деле соответствующая функция удалена из кода, потому что Closure Compiler считает, что это не используется: в окончательном сгенерированном коде нет ни следа функции, ни вызовов этой функции.

Эта проблема возникает не со всеми сеттерами, поэтому я не мог понять конкретную причину этого.

// Definition of setter
set myText(value)
{
    value = value.toString();
    if(!this._myText)
    {
        this._myText=
            this.createPixiText(
                value,
                this._myTextLayout,
            );
    }
    else
    {
        this._myText= value;
    }
}

// Call to setter
this.myText= "hello world!";

Этот код, чтобы быть совместимым с компилятором Google Closure, необходимо преобразовать в это:

// Function definition
setMyText(value)
{
    value = value.toString();
    if(!this._myText)
    {
        this._myText=
            this.createPixiText(
                value,
                this._myTextLayout,
            );
    }
    else
    {
        this._myText= value;
    }
}
// Call to function
this.setMyText("hello world!");

Я надеюсь, что это руководство сэкономит время и избавит вас от головной боли, а также позволит каваи-единорогам снова свободно летать 🦄