Tutorial: Facebook Instant Game progress bars with Cocos Creator

Facebook Instant Games progress bars with Cocos Creator

Introduction and getting help

You are welcome to post to the Cocos Creator category on the Cocos forums to talk about any issues you encounter during the development process. This tutorial does not teach how to code.

Please prepare your development environment before starting this tutorial. If you are having trouble with our tutorial, please take a look at the following documentation:

Preparing the development environment:


Let’s get started

After publishing a Facebook Instant Game with Cocos Creator, we found that the progress bar will wait, for some time, from 0, and then fly directly to 100. This user experience is not very good and may affect perceived performance and app store reviews.

1

FBInstant interface for setting a progress bar

FBInstant.setLoadingProgress (a percentage) reports the initial loading progress of the game. This a number between 0 and 100 and can return a void. Example:

FBInstant.setLoadingProgress(50); // Assets are 50% loaded

When calling FBIstant.startGameAsync(), the Facebook SDK will execute FBIstant.setLoadingProgress(100) to directly set the progress bar to 100%.
Calling SetLoadingProgress() will only have an effect after FBInstant.initializeAsync() succeeds.

The process of ccc setting the progress bar by default

Cocos Creator sets the progress bar to use cc.loader.onProgress by default, which is called by all global resource loads. The returned CompleteCount and totalCount are both 1, resulting in incorrect progress settings.

function setLoadingDisplay() {
    // Loading splash scene
    cc.loader.onProgress = function (completedCount, totalCount, item) {
        var progress = 100 * completedCount / totalCount;
        FBInstant.setLoadingProgress(progress);
    };
}

Taking a look at the loading process, binding onProgresssetLoadingDisplay() will only be called after loading multiple JavaScript files and running the game. The previous bulk of the waiting time will always display 0%. This time can also be optimized.

Optimization

After fbinstant.6.2.js loads, call FBInstant.initializeAsync, and then call FBInstant.setLoadingProgress() at each step above, so that the loading process can be seen.

First, find the published directory, modify the <body> in index.html, call fbinstant.6.2.js to load and initialize FBInstant.initializeAsync(), then set the progress calling FBInstant.setLoadingProgress(10);, then load settings.js and set the progress calling FBInstant.setLoadingProgress(20);. Finally, call main.js.

<body>
  <canvas id="GameCanvas" oncontextmenu="event.preventDefault()" tabindex="0"></canvas>
  <!-- Add -->
  <script type="text/javascript">
    // Load javascript
    var loadSingleScript = function (src, callback) {
        var s = document.createElement('script');
        s.async = false;
        s.src = src;
        s.charset = 'utf-8';
        s.addEventListener('load', function () {
            s.parentNode.removeChild(s);
            s.removeEventListener('load', arguments.callee, false);
            callback();
        }, false);
        document.body.appendChild(s);
    };
    function setting_js_load() {
        // load settings.js
        FBInstant.setLoadingProgress(20);
        loadSingleScript("main.js", function () { });
    }
    function fb_js_load() {
      console.log('fb_js_load')
      FBInstant.initializeAsync()
        .then(function () {
            // Set the progress bar after initialization
            FBInstant.setLoadingProgress(10);
            loadSingleScript("src/settings.js", setting_js_load);
        })
    }
  </script>
  <script src="https://connect.facebook.net/en_US/fbinstant.6.2.js" onload="fb_js_load()">
  </script>
  <!-- Add end-->

  <!-- Remove -->
  <!-- <script src="https://connect.facebook.net/en_US/fbinstant.6.2.js"></script> <script src="src/settings.js" charset="utf-8"></script> <script src="main.js" charset="utf-8"></script> -->
  <!-- Remove end-->
</body>

Last, modify main.js to remove the original initialization and binding onProgress(). Find the corresponding position and set the progress bar. Example:

(function () {
    'use strict';
    // Set the progress bar after loading main.js
    FBInstant.setLoadingProgress(30);

    function boot() {
        // Progress bar after cocos2d-js.js is loaded
        FBInstant.setLoadingProgress(40);
            // omit this code
        }
        // omit this code 
        
        // Remove binding
        // function setLoadingDisplay () {
        // // Loading splash scene
        // cc.loader.onProgress = function (completedCount, totalCount, item) {
        // var progress = 100 * completedCount / totalCount;
        // FBInstant.setLoadingProgress(progress);
        // };
        // }

        var onStart = function () {
            //cc.game.run post the progress bar
            FBInstant.setLoadingProgress(50);
            // remove the binging 
            if (cc.sys.isBrowser) {
                 // removing binding
                // setLoadingDisplay();
            }
            // omit this code 
            cc.director.preloadScene(launchScene,
                function () {
                    // progress bar after loading 
                    FBInstant.setLoadingProgress(60);
                    // omit this code 
                }
            );
        };
        // omit this code 
    }

    if (window.document) {
        // omit this code 
        var engineLoaded = function () {
            // Remove the original initialization
            // FBInstant.initializeAsync()
            // .then(function () {
            document.body.removeChild(cocos2d);
            cocos2d.removeEventListener('load', engineLoaded, false);
            if (typeof VConsole !== 'undefined') {
                window.vConsole = new VConsole();
            }
            boot();
            // });
        };
        // omit this code 
    }
})();

When the index.html and main.js are modified as above, they can be placed in the project’s build template directory. They will be automatically copied to the release directory after the next build release. This means they don’t need to be modified again.

1 Like