With Cocos2d-html5, is there any way to “quit” the engine and re-initialize its state so you can later restart the engine. We are using a Cocos2d game in a single page web app. If the user navigates to another page, we want to programmatically remove the canvas div and attempt to exit the Cocos2d engine. Unfortunately, it seems there’s no good way to do this and attempting to load a new game causes errors.
How can you cleanly unload a scene and quit the engine?
We are using V3.1 and tried several approaches, none of them seem to work. For example:
- Trying to reset many variables that are held in the cc object (detailed below). This approach forces you to reset variables that look private as they start with _ and are not in the documentation.
- picking, choosing and rewriting some of CCBoot.js but this appeared complicated and not sustainable for engine updates as so much of it is depended upon throughout the library.
Other approaches I thought of but all sound like a hack:
3. Null the whole cc object and somehow run the script again but that might mean stripping out a script tag or module and adding and running it again.
4. Wrap the cc object in another object so it is easier to reset. CCBoot.js looks like it might attach some things to the window object.
I have got furthest with the first approach but am stuck with context issues. When leaving the canvas, before I remove it from the DOM I call these:
// Remove anything that might possibly keep a reference to the old context
cc.textureCache.removeAllTextures();
cc._drawingUtil = null;
cc.stencilBits = null;
// Purge the cc.director, schedules, event listeners, running scene, animations, cached data.
cc.director.purgeDirector();
// Remove references to the context
cc._renderContext = null;
cc.webglContext = null;
window.gl = null;
cc._mainRenderContextBackup = null;
// Remove reference to DOM elements
cc._canvas = null;
cc.container = null;
cc._gameDiv = null;
// Reset CCBoot variables that might stop us from re-initialising
cc._rendererInitialized = false;
cc._setupCalled = false;
cc._renderType = -1;
Then when we restart on the second or subsequent time call
// Reset all system and flag variables
cc._initSys(cc.game.config, cc.game.CONFIG_KEY);
cc.game.run();
And here are the kind of errors I get. It looks like it's not properly resetting the context:
WebGL: INVALID_OPERATION: bindTexture: object not from this context
WebGL: INVALID_OPERATION: texImage2D: no texture
WebGL: INVALID_OPERATION: uniformMatrix4fv: location is not from current program
WebGL: INVALID_OPERATION: vertexAttribPointer: no bound ARRAY_BUFFER