Problem with inheritance in cocos2d-html5

Hello everyone,

I noticed a problem when using John Resig’s inheritance and I wanted to share my issue in here (even though I could by-pass it).
To reproduce it, simply follow the few steps below:
1/ extend the class sprite:
var Player = cc.Sprite.extend({
ctor:function (fileName) {
cc.associateWithNative( this, cc.Sprite );
this.initWithFile(fileName);
});
2/ create 2 instances of that class using files with different size (by that I mean different width and height)
3/ call getQuad() on both (you may have to add the sprites to a layer before doing this step)
4/ compare the returned quads -> they are the same
5/ the hack : add “this.*quad = cc.V3F_C4B_T2F_QuadZero;" after “cc.associateWithNative;” to overwrite the class instance
Now, why is this happening? Because the variable "*quad” of the Sprite class is a class variable, not an instance variable.
The following article explains it very well : http://stackoverflow.com/questions/14132697/weird-issue-on-properties-with-john-resig-simple-inheritence
I think that the current architecture is kind of broken in term of OO approach. There should be a difference in the way class variables and instance variables are declared (instance variables should be declared during the initialisation, not as class members).

I am looking forward to reading your comments on this issue.
Cheers~~

Thanks for reporting this bug, Noel.

We will test it and solve it before next release.

If I have some result I will post it here.

Hi Shun Lin,

Thank you for your reply. Even if it is not critical, I think it is an interesting issue.

Any news on this topic?

Hi,

This is true for almost all OO inheritance in Javascript, what ever you declare ends up in the prototype.

if an instance writes a value, then a new value will exists for that instant,
if an instance try to read a value, if that instance does not have its own value, it will read from the prototype

the problem arrise when a variable is declared as an object (including Arrays)

For example
instance.position.x = 10
you might think this changes the position of that instance, but actually, this only changes the prototype

this breaks down to
# reads “instance” from local or window stack
# reads “position” from “instance”’s prototype
# write to “x” of the “position” object

remember that the position object references to the instance’s prototype, so therefor, any other instance that does not have its own position property will reads from prototype, which was changed

As for ._quad property, it is unused in the current version, it will work fine in JSB, next Cocos2d-html5 release, we will have WebGL support, and we will also implement quad

Hi Hao Wu,

Thank you for your reply.

Well, I know the issues with OO inheritance in Javascript, and it is hard to get the same behaviour we can get when using objective-c.

Here is how I use getQuad in my code with cocos2d-html5 2.1.1, it might inspire others (“this” is a cc.Sprite):

// get hit box based on the actually displayed pixels
var quad = this.getQuad(); // make sure you use the hack described in my first post
var boundingBox = this.getBoundingBox();
var originX = boundingBox.x + quad.bl.vertices.x;
var originY = boundingBox.y + quad.bl.vertices.y;
var width = quad.br.vertices.x - quad.bl.vertices.x;
var height = quad.tl.vertices.y - quad.bl.vertices.y;
var hitBox = cc.rect(originX, originY, width, height);
return hitBox;