Open JakeLin opened 10 years ago
Good point, I think we need this feature, it's very useful in some case
@pandamicro Do you have any thoughts on the cc.game.setFrameRate(30)
issue? Thanks.
@JakeLin Unfortunately I can't reproduce the effect by calling cc.game.setFrameRate(30)
, and I can't find the init
function in your code. Can you point it out ?
@pandamicro ,Thanks for looking at this issue. If you look at my code at https://raw.githubusercontent.com/JakeLin/cocos2d-meteor/master/cocos2d-js-v3.0.js
var ccInit = ccInit || {}; ccInit.init = function () { //all cocos2d js file };
You may find a object called ccInit
and it has an init
method.
In my game project. I put all my logic (Scene, Layer, etc) within
Template.game.rendered = function() {
// init cocos2d
ccInit.init();
// all logic are placed below the init() method.
var GameLayer = cc.Layer.extend({
// ...
});
// Scene
var GameScene = cc.Scene.extend({
onEnter: function () {
this._super();
// add a layer to the scene
gameLayer = new GameLayer();
this.addChild(gameLayer);
}
});
// Start the game
cc.game.onStart = function(){
//load resources
cc.LoaderScene.preload([], function () {
cc.director.runScene(new GameScene());
cc.director.setDisplayStats(true); // show FPS
// http://discuss.cocos2d-x.org/t/how-to-set-fps/3349/2
// this method doesn't work
// cc.director.setAnimationInterval(1.0/fps);
}, this);
};
// cc._setupCalled = false; // hack for Meteor. actually, doesn't work
// cc.game.config['showFPS'] = true; // doesn't work either
cc.game.run('gameCanvas'); // that works because I have reinited the engine by using ccInit.init();
cc.game.setFrameRate(fps); // that causes problem, it will decrease the FPS every time. for example, 1st time, 30. 2nd time, 15, 3rd 10, 4th 7.5. 5th 5...
};
You can treat Template.game.rendered
as same as document.ready() in jQuery. I put all cocos2d game code below ccInit.init();
which is at https://raw.githubusercontent.com/JakeLin/cocos2d-meteor/master/cocos2d-js-v3.0.js . cc.game.run('gameCanvas');
starts working since I have reinited the engine by using ccInit.init();
, However, cc.game.setFrameRate(fps);
causes problem, it will decrease the FPS every time. for example, 1st time, 30. 2nd time, 15, 3rd 10, 4th 7.5. 5th 5...
Thanks for your time, I could like to fix it if I have time, the architecture of cocos2d-js seems quite complicated already. I think we need some refactoring to improve the engine.
Thanks Jake
Hi Guys, I am using AngularJS and have same issue. And I think we have more tough problems in the case, like "how to resume scene when user back to page", "how to make project.json for each game. (we can only have one project.json file for now in cocos2d-html5)". I am trying to work on this issue. SPA is more and more popular, hope cocos will catch it up. ^_^
Thanks Ken
I have a workaround on this issue, and can restart game after router page changed in Angularjs.
if (cc._renderType === cc._RENDER_TYPE_WEBGL)
cc._renderContext = cc.webglContext = cc.create3DContext(localCanvas, {
'stencil': true,
'preserveDrawingBuffer': true,
'antialias': !cc.sys.isMobile,
'alpha': false
});
if (cc._renderContext) {
win.gl = cc._renderContext; // global variable declared in CCMacro.js
cc._drawingUtil = new cc.DrawingPrimitiveWebGL(cc._renderContext);
cc._rendererInitialized = true;
cc.textureCache._initializingRenderer();
cc.shaderCache._init();
} else {
cc._renderContext = new cc.CanvasContextWrapper(localCanvas.getContext("2d"));
cc._drawingUtil = cc.DrawingPrimitiveCanvas ? new cc.DrawingPrimitiveCanvas(cc._renderContext) : null;
}
if (cc._renderType === cc._RENDER_TYPE_WEBGL) {
cc._renderContext = cc.webglContext = cc.create3DContext(localCanvas, {
'stencil': true,
'preserveDrawingBuffer': true,
'antialias': !cc.sys.isMobile,
'alpha': false
});
if (cc._renderContext) {
win.gl = cc._renderContext; // global variable declared in CCMacro.js
cc._drawingUtil = new cc.DrawingPrimitiveWebGL(cc._renderContext);
cc._rendererInitialized = true;
cc.textureCache._initializingRenderer();
cc.shaderCache._init();
} else {
cc._renderContext = new cc.CanvasContextWrapper(localCanvas.getContext("2d"));
cc._drawingUtil = cc.DrawingPrimitiveCanvas ? new cc.DrawingPrimitiveCanvas(cc._renderContext) : null;
}
}
else {
cc._renderContext = new cc.CanvasContextWrapper(localCanvas.getContext("2d"));
cc._drawingUtil = cc.DrawingPrimitiveCanvas ? new cc.DrawingPrimitiveCanvas(cc._renderContext) : null;
}
cc._setupCalled = false;
cc.game._prepareCalled = false;
cc.game._prepared = false;
cc.EGLView && (cc.EGLView._instance = null);
cc.game.onStart = function(){
if(!cc.sys.isNative && document.getElementById("cocosLoading")) //If referenced loading.js, please remove it
document.body.removeChild(document.getElementById("cocosLoading"));
// Pass true to enable retina display, disabled by default to improve performance
cc.view.enableRetina(false);
// Adjust viewport meta
cc.view.adjustViewPort(true);
// Setup the resolution policy and design resolution size
cc.view.setDesignResolutionSize(800, 450, cc.ResolutionPolicy.SHOW_ALL);
// The game will be resized when browser size change
cc.view.resizeWithBrowserSize(true);
//load resources
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new HelloWorldScene());
}, this);
};
cc.game.run();
But there is only one project.json file, so can't support multi-games configration for now, still working on it
Thanks Ken
OK, we can use cocos for mutil-games in Angularjs now.
cc._setupCalled = false;
cc.game._prepareCalled = false;
cc.game._prepared = false;
cc.EGLView && (cc.EGLView._instance = null);
cc.loader._jsCache = {}; // remove js cache
//load different jsList for each game. You can wrap it like json.
//also for modules
if($stateParams.gameId==1) {
cc.game.config.jsList = [
"./classdojo/games/demo/src/resource.js",
"./classdojo/games/demo/src/app.js"
];
}
else {
cc.game.config.jsList = [
"./classdojo/games/demo2/src/resource.js",
"./classdojo/games/demo2/src/app.js"
];
}
cc.game.onStart = function(){
if(!cc.sys.isNative && document.getElementById("cocosLoading")) //If referenced loading.js, please remove it
document.body.removeChild(document.getElementById("cocosLoading"));
// Pass true to enable retina display, disabled by default to improve performance
cc.view.enableRetina(false);
// Adjust viewport meta
cc.view.adjustViewPort(true);
// Setup the resolution policy and design resolution size
cc.view.setDesignResolutionSize(800, 450, cc.ResolutionPolicy.SHOW_ALL);
// The game will be resized when browser size change
cc.view.resizeWithBrowserSize(true);
//load resources
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new HelloWorldScene());
}, this);
};
cc.game.run();
Thanks Ken
well done @gaokun
One more issue about system event.
We must registerSystemEvent
after restart, but cc.inputManager was registered by last setup
.
And cc.inputManager is not loaded when cc.game.run()
so I hacked the cc._setup
function:
cc.myHackSetup = function() {
var setupString = cc._setup.toString();
function forDebug() {
//make a breakpoint here for debug cc._setup
//console.log('hack cc._setup function');
cc.inputManager._isRegisterEvent = false;
}
setupString = setupString.replace('if (cc._renderContext)','forDebug();\nif(false)');
setupString = 'cc._setup = '+setupString;
eval(setupString);
};
The code above just support canvas render model.
I will update this topic when I get any progress on this. Thanks Ken
is there a better solution that does not involve the hack?
I am using Meteor and I found a serious issue with cocos2d-js at the moment. Most of the new JavaScript frameworks such as Meteor and Angular.js will use client side routing system. It means when the user navigates from one page to the other page, the page doesn't hard load the entire HTML. It may use something like ajax to retrieve the content and dynamically update the DOM without reloading the entire HTML again. It comes a problem with cocos2d-js in that case. cocos2d-js has a global variable called
cc
. If the browser reloads the entire HTML, all javascript files (or cached files) will be reloaded (re-executed), the variablecc
will be re-init again. But if we use some Javascript frameworks like Meteor or Angular.js. the variablecc
will remain the same. And when we try to init the game (another game in the second page) by usingcc.game.run('gameCanvas');
. Some of properties (for instance,_setupCalled
) had been set before (when we inited the first game). And we can't start the game on the new page because_setupCalled
is true. Cocos2d can't setup the Canvas properly.I have tried to wrapped all the source code in one
init()
method, and call this method in document.ready() method. The code is open source on https://github.com/JakeLin/cocos2d-meteorIt seams working, but I get another issue with
cc.game.setFrameRate(30)
. Every time, I call this method, the FPS will decrease about half. For example, the first game is 30, the second game is 15, the third one is 10, the forth one is 7.5. I can't find out the reason when I dive into the source code. Could you please give some hints?Thanks Jake