破坏Phaser.Game实例的正确方法是什么?

时间:2017-06-24 23:44:54

标签: javascript phaser-framework

在创建然后销毁Phaser.Game实例的简单案例中,似乎存在内存泄漏。下面是一个完整的工作示例:单击按钮创建实例,再次单击以销毁它。反复单击该按钮会导致内存使用量不受限制地增长。对于我应该做的相位生命周期,我是否还有一些缺失?

我将此作为代码片段而不是jsfiddle发布,因为您需要查看内存分析器或类似内容以查看问题,因此jsfiddle只会使问题复杂化。

<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<title>test</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/phaser-ce/2.8.1/phaser.js">
</script>
</head>
<body>
   <button id="button">Click</button>
   <div id="canvas"></div>
   <script>
      window.onload = function() {
         var d, n, game;

         d = document.getElementById('button');
         n = document.getElementById('canvas');

         function preload() {
         }
         function create() {
         }
         function update() {
         }
         function handler() {
            if(game) {
                    game.destroy();
                    game = null;
            } else {
                    game = new Phaser.Game(800, 600, Phaser.AUTO, n, {
                            preload:        preload,
                            create:         create,
                            update:         update
                    });
            }
         }
         d.onclick = handler;
      };
   </script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

回答(至少部分)我自己的问题,问题出在Phaser.CanvasPool中。每当创建新的Phaser实例时,都会创建一个新的画布并将其添加到池中。销毁实例dows不会从池中删除画布或将其标记为可重复使用。

你可以通过在调用game.destroy()后设置Phaser.CanvasPool.pool = []等粗略的东西来解决这个问题,但是如果你有多个phaser实例,它就不会起作用。

如果有人知道正确的工作流程应该是什么,我很想知道--- Phaser.CanvasPool是移相器与PIXI的联系点之一,所有这些似乎都记录不清

编辑:发现内存泄漏的来源。它的Phaser.Utils.Debug.boot(),每次调用时都会向池添加一个新的画布,默认情况下,每次创建和启动一个移相器实例时都会这样。

启用enableDebug时,问题仅影响WebGL渲染的画布(这是默认设置)。

为了完整性,这里是上面代码的编辑版本,它禁用了调试,因此没有出现内存泄漏:

<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<title>test</title>
<script src="http://cdnjs.cloudflare.com/ajax/libs/phaser-ce/2.8.1/phaser.js"></script>
</head>
<body>
<button id="button">Click</button>
<div id="canvas"></div>
<script>
window.onload = function() {
    var d, n, game;

    d = document.getElementById('button');
    n = document.getElementById('canvas');

    function preload() {
    }
    function create() {
    }
    function update() {


    }
    function handler() {
            if(game) {
                    game.destroy();
                    game = null;
            } else {
                    game = new Phaser.Game({
                            width:          800,
                            height:         600,
                            renderer:       Phaser.AUTO,
                            parent:         n,
                            enableDebug:    false,
                            state:          {
                                    preload:        preload,
                                    create:         create,
                                    update:         update
                            },
                    });
            }
    }
    d.onclick = handler;
};
</script>
</body>
</html>