Проблемы с загрузкой кеша Phaser

Делаю игру в фазере. Я загружаю фоновое изображение, и его информация (расположение файла) хранится в файле JSON. Когда я пытаюсь загрузить его, фон черный и пустой, а в консоли я получаю:

Phaser.Cache.getImage: ключ «background0» не найден в кэше.

Вот соответствующий отрывок из моего кода:

function create() {

    //>Load JSON file and background images found inside the file
    $.getJSON("levels.json", function(json) {
        for (var i = 0; i < json.levels.length; i++) {
            game.load.image('background' + i.toString(), json.levels[i].background);
        }
        game.load.start();
   });

    back_layer = game.add.group();
    var i = 0;
    var level_finished = 0;

    $.getJSON("levels.json", function(json) {
        if (i < json.levels.length) {
            console.log("Level " + (i + 1).toString());
            var current_background = back_layer.create(0, 0, 'background' + i.toString());

            check = setInterval(function() {
                if (level_finished == 1) {
                    i++;
                    current_background.destroy();
                    clearInterval(check);
                }
            }, 500)
        }
    });
}

А вот файл JSON:

{"levels":[
    {
        "background": "assets/img/Back.png",
        "portals": [
            {
                "locationX": 400,
                "locationY": 450,
                "toX": 100,
                "toY": 200,
                "spinSpeed": 1
            },
            {
                "locationX": 50,
                "locationY": 200,
                "toX": 100,
                "toY": 450,
                "spinSpeed": 2
            }
        ]
    }
]}

Тестирование с помощью Chrome, Firefox и Opera, и каждый раз, когда я открываю страницу, кажется, что случайно возникает ошибка или загружается фон и все работает нормально. Я использую WAMP для локального размещения страницы.


person Melkor    schedule 31.12.2016    source источник


Ответы (2)


Способ загрузки ресурсов (JSON, изображений и т. Д.) Phaser заключается в использовании game.load.* API в функции preload (или той, которую вы для этого указали). В вашем случае код должен быть:

// Use your game instance here
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create });

function preload() {
    // Load JSON file describing the level
    game.load.json('levels', 'levels.json');
}

// The function below will be automatically invoked by Phaser when
// the assets in the preload() function finished loading
function create() {
    var json = game.cache.getJSON('levels');

    // Enque the load of the background images found inside the level file
    for (var i = 0; i < json.levels.length; i++) {
        game.load.image('background' + i.toString(), json.levels[i].background);
    }

    // Specify loadComplete() as a callback to be called when all assets finished loading
    game.load.onLoadComplete.add(loadComplete, this);

    // Load the newly enqued assets
    game.load.start();
}

// The function below will be automatically invoked by Phaser when
// the assets in the create() function finished loading
function loadComplete() {
    var json = game.cache.getJSON('levels');

    back_layer = game.add.group();
    var i = 0;
    var level_finished = 0;

    if (i < json.levels.length) {
        console.log("Level " + (i + 1).toString());
        var current_background = back_layer.create(0, 0, 'background' + i.toString());

        check = setInterval(function() {
            if (level_finished == 1) {
                i++;
                current_background.destroy();
                clearInterval(check);
            }
        }, 500)
    }
}

Причина, по которой у вас случайное поведение (иногда оно работает нормально, иногда нет), заключается в том, что вы используете jQuery ($.getJSON()) вместо встроенной системы Phaser для загрузки файла JSON.

Поскольку jQuery не связан с Phaser, они не синхронизируются (и не упорядочиваются во время вызовов). Как следствие, иногда $.getJSON() загружает файл JSON достаточно быстро, чтобы он был готов, когда вызывается метод create() Phaser. В этом случае все работает как положено. Когда $.getJSON() работает недостаточно быстро, create() будет вызываться до загрузки файла JSON, что приведет к ошибке.

person Fernando Bevilacqua    schedule 04.01.2017
comment
Спасибо за ответ, действительно помогло! Однако в первый раз, когда я запускаю игру перед обновлением страницы, я получаю сообщение об ошибке «Phaser.Loader - активная загрузка отменена / сброс», обновление исправляет это, но это не идеально. - person Melkor; 06.01.2017
comment
Вы пытаетесь загрузить какие-либо другие активы, кроме тех, которые вы указали в примере? Вероятно, это вызвано тем, что Phaser что-то загружает во время загрузки других ресурсов. Вы можете попытаться предотвратить появление предупреждающего сообщения, вызвав game.load.reset() или game.load.reset(true) (полный сброс) в начале функции create(). - person Fernando Bevilacqua; 09.01.2017
comment
Я загружаю изображения в функцию предварительной загрузки. Добавление сброса к функции создания не изменило ошибок. У меня тоже индикатор ошибки не определен. Paddle - это спрайт, определенный в loadComplete. Однако, когда я пытаюсь получить к нему доступ из обновления, я получаю сообщение об ошибке, что оно не определено. - person Melkor; 10.01.2017
comment
Попробуйте объявить paddle (и любую другую переменную, которая будет использоваться более чем одной функцией) в той же области, где в примере объявлена ​​переменная game. Это должно сделать переменные доступными для всех функций и предотвратить указанную вами ошибку. - person Fernando Bevilacqua; 10.01.2017
comment
Это не изменило ошибку, я создал новый вопрос для решения этой проблемы здесь, спасибо за вашу помощь! - person Melkor; 10.01.2017

Загрузка ресурсов в Phaser выполняется асинхронно, и если вы попытаетесь получить к чему-либо доступ сразу после того, как запросили что-то для загрузки, в этом случае произойдет сбой. Переместите логику предварительной загрузки в preload() (другой метод Phaser.State, как и create()) - Phaser гарантирует, что после вызова вашего create() метода все, что запрошено в preload(), будет загружено.

person Kamen Minkov    schedule 01.01.2017
comment
Я переместил логику фоновой загрузки в предварительный загрузчик, но у меня та же проблема - иногда загружается, а иногда нет. - person Melkor; 01.01.2017