cocos2d-iphone jsb & cocos2d-html5 compatibility: ctor, init, associateWithNative
I'm writing a cross-platform game with cocos2d (iphone jsb + cocos2d-html5) and I'm wondering how to actually make it cross-platform. Code that would work with -html5 won't necessarily work with -iphone jsb and vice versa.
Currently I'm stuck at the following (related) questions:
- What's the difference between ctor and init?
- When should I overload ctor, and when should I overload init?
- When I should I call _super() from ctor and/or init?
- When should I call .init() from ctor if I overload do ctor?
- How should I instantiate objects? With var inst = new Obj(); inst.init();? Or just var inst = new Obj();? I understand there are .create() methods which make sense, but I'm asking in the case of me writing my own create methods.
- When should I use associateWithNative?
I had some code that worked with the html5 version, but then I got an error saying the object was already initialized on the iPhone jsb version, so clearly I was getting something wrong. I've tried look at the MoonWarriors code but it seems to never use associateWithNative, which I thought was required, and it sometimes overloads ctor, sometimes not, sometimes calls init from the ctor, sometimes not, etc...
For me it's hard to find the way out too, I have the same problem, I developed the game mostly testing on browser & now I also have lots of issues & cannot port it to iOS,.
As far as your question goes:
- ctor calls constructor for the class, init initializes the new object.
- You should overload ctor when subclassing, init when doing custom initialization behavior for the object of the class your subclassing.
- I'd say always, although I also noticed that this is not everywhere present at the MoonWarriors demo.
- I think that's not a good practice.
- var inst = new Obj(); & then inst.init() or the other way is to call var inst = Obj.create();
- associateWithNative should be called in ctor
About creating objects from a class you've created, e.g. if you have a var Warrior which has _hp as a private property & you want to assign it at creation, there are 3 ways as far as I understood:
var myWarrior = new Warrior(hp);
& then you set the _hp in the constructor ctor:function(hp)..
var myWarrior = new Warrior(); myWarrior.init(hp);
& then you set the _hp in the initialization init:function(hp)..
3.With Factory Method:
var myWarrior = Warrior.create(hp);
& then you set the _hp in the create method which would be after the declaration of the var Warrior & it will create a new object & initialize it properly.
EDIT: Also starting from cocos2d-iphone-2.1-rc2 you'll no longer need to override ctor in order to place associateWithNative since from that build on that call is not needed.
ad 1-5. I've found out that overwriting ctor - even though might seem more convenient especially for somebody coming from JS world at the moment might cause problems when compiling cocos2d-js code on other platforms - if you stumble on ERROR in *: Invalid Proxy object error it might be because of the overwriting the ctor method (was in few cases for me). Also sometimes constructor methods on native classes will expect parameters that you overwrite/handle on your end for classes that inherit from native classes and it might cause some conflicts as well.
Apart of that all the differences were described by Kex - I'd say looking at provided samples and cocos2d source the safest and "Cocos2d way" would be to use combination of init methods and static factory create.
ad 6. It is no longer required to use the associateWithNative method (you can read more here: cocos2d-js-devel)