Jump to content

How to keep attributes on objects?


dominate
 Share

Recommended Posts

I am passing from KineticJs to PixiJs. In KineticJs every object has 

setAttr(), getAttr()

so that it is possible to keep user data on objects, which helps later to search over objects on a stage depends on their attributes. I did not see in PixiJs such mechanism yet. How do I do?

 

Yes, sure, it is just possible to extend my javascript variable as I wish, but does PixiJs have a native mechanism for this?

Link to comment
Share on other sites

PIXI.DisplayObject.prototype.getAttr = function(name) { if (!this.attrs) return; return this.attrs[name] };PIXI.DisplayObject.prototype.setAttr = function(name, value) { if (!this.attrs) this.attrs = {}; this.attrs[name] = value; };
Irony?

I assume there's some reason to avoid dynamically adding members to Pixi.js classes (maybe using a transpiler with stricter requirements?), but surely that also rules out dynamic patching member functions to add the features, and the OP seemingly doesn't want to diff the library to add the code... or I've misunderstood everything in this thread (that is most possible I guess)

Link to comment
Share on other sites

Thanks for the replies. @chg right, I prefer not to add my code to native pixi code since I do not know how the objects are treated, especially when cloning, copying etc. But the code posted is what I exactly needed. I hope to see in newer versions such mechanism.

 

The thing I wonder is why I could not find this question before. Did not anybody need such thing?

 

Then, how do you organize the display objects? This is my real problem. Maybe I could ask this in a new post, but let me first try here.

 

What I need is, "self-knowing" objects. For example, in a card game, there are 4 players. Every player has 1 hand of 13 cards.

Every card is shown with a Sprite. User clicks on one card. Then how do I know the type of card clicked? Simply, I prefer to keep an "id" attribute on it: "DIAMONDS_JACK". This seems to me the shortest way to do it: The display object is conscious about itself. Especially when the data is not so complex so what does not need maintain a model.

 

Another issue is organizing the related objects. I need your comments and help on this. I do not know the better practice for this.

For every player I create a PIXI.Container, let say playerView, so that in each of it I can keep the display objects of that specific player.

Then, I need to get an object within the playerView, say a text which holds the name of player, which is drawn on a Rectangle a nameplate, i.e.

 

playerView -> nameplate -> text

 

I could do:

 

1- Write a "find" function which searches for me the display object that I want on the children of the container, i.e. find(playerView, '.playername'); which looks for a child (or grandchild etc.) in playerView that has the attribute "name" equals to "playername".

 

2- From the beginning keep a map which holds every display object in a hierarchy, so that I can get whatever I want without searching, i.e., "map.playerViews['player1'].nameplate.text". But the trade-off is to maintain such huge map which could easily go out of control, and I should refer to objects with a variable name, and also there is already hold such hierarchy in playerView, etc.

 

How do you do that? How do you organize your display objects so that later get exactly what you want?

 

I see in three.js getObjectByName and getObjectById. Do not you think there is need of this also in pixi.js?

 

Please let me know if I need to make a new post.

Link to comment
Share on other sites

People often do this by extending the sprite class (creating a Card class) that includes that kind of information. What player it belongs to, what kind of card it is, game specific behavior, etc. Then you can build all those find-by utilites on top of pixi. OFten using whatever data structure will be best for locating your objects based on the data you will use for lookup.

Link to comment
Share on other sites

The thing I wonder is why I could not find this question before. Did not anybody need such thing?

There's a related* question in the Phaser forums at the moment actually (*again, assuming I don't completely misunderstand this thread): http://www.html5gamedevs.com/topic/19732-noob-question-best-practice-to-store-objects/

 

I recommend this thread because the topic of that thread concerns itself with some alternatives (extending the Pixi.js renderable object vs having a custom object that has the Pixi.js sprite as a property).

 

But this is Javascript and being the dynamic hot mess that that it is there is nothing (at least that comes to mind) stopping you from just telling particular sprites - right sprite you have this property now and then it just does ("expando properties"), it's a language feature hence why I thought you'd only need a setter if using a stricter type system.

Every card is shown with a Sprite. User clicks on one card. Then how do I know the type of card clicked? Simply, I prefer to keep an "id" attribute on it: "DIAMONDS_JACK". This seems to me the shortest way to do it: The display object is conscious about itself. Especially when the data is not so complex so what does not need maintain a model.

Do you actually want an id attribute though in that example, or is that a solution you are think in terms of because you have seen it? (the hammer nail expression)

If you could add any properties you liked to keep track of a card I might prefer to use two, one for the suit and a number for the card eg. 1 for Ace through to 13 for King, that would seem to me to be easier still...

Link to comment
Share on other sites

But this is Javascript and being the dynamic hot mess that that it is there is nothing (at least that comes to mind) stopping you from just telling particular sprites - right sprite you have this property now and then it just does ("expando properties"), it's a language feature hence why I thought you'd only need a setter if using a stricter type system.

 

To be clear "expando properties" are properties added to native objects (DOM elements for example), these V8 object behave a bit differently than normal js object. For us, adding properties to say PIXI.Sprite repeatedly can change the Hidden Class or even fall back to Hash Table mode and make it slow to call methods with that object, and slow to access the properties.

 

Fun Reading: http://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html

Link to comment
Share on other sites

That's fair... I was thinking it'd change the hidden class and have minor impact (I was starting to think maybe noone cared about such things though) but I hadn't considered the possibly that it could make accessing properties go through a hash map, which is a rather undesirable possibly performance-wise for a bunch of sprites. "Hot mess" was meant to be a nod to acknowledging the ugliness of what was meant to be a worst case option of a quick and dirty hack... (aka how I tried to stop worrying about performance and learn to love the bomb)

That blog post is a great read! There truly aren't enough Javascript resources that give c++ and assembly code illustrating what is going on, thanks!!! Pure gold!

Link to comment
Share on other sites

Use Entity->Component architecture. Create a "entity" which will have many components inside, that define behaviour of object. One of components must be a sprite or container, I prefer to use "entity.view". Also components have to know their entity, so "view.entity" must point to the "real" object. Store entities in separate tree or whatever you use. Believe me, that architecture will save you a lot of time.

Link to comment
Share on other sites

Use Entity->Component architecture. Create a "entity" which will have many components inside, that define behaviour of object. One of components must be a sprite or container, I prefer to use "entity.view". Also components have to know their entity, so "view.entity" must point to the "real" object. Store entities in separate tree or whatever you use. Believe me, that architecture will save you a lot of time.

Do not you think that this is a waste, since the pixi container already has this hierarchical structure? And won't it be hard-to-maintain, when, although not in my case, you have let say 100, 1000 entities?

Link to comment
Share on other sites

People often do this by extending the sprite class (creating a Card class) that includes that kind of information. What player it belongs to, what kind of card it is, game specific behavior, etc. Then you can build all those find-by utilites on top of pixi. OFten using whatever data structure will be best for locating your objects based on the data you will use for lookup.

 

So you suggest putting pixi object to another javascript variable (or extending), instead of putting a property to pixi object, right?

Link to comment
Share on other sites

I mean extend the object:

function Card(texture) {    PIXI.Sprite.call(this, texture);    this.suit = DIAMONDS;    this.value = 9;}Card.prototype = Object.create(PIXI.Sprite.prototype);Card.prototype.constructor = Card;Card.prototype.playCard = function () { /* ... */ };

Now you have your own object you can put whatever properties on (in the constructor) that you want. And in no way do you change the pixi sprite hidden class. At the same time our functions become polymorphic but with only a few of these types you may not even notice.

Link to comment
Share on other sites

Do not you think that this is a waste, since the pixi container already has this hierarchical structure? And won't it be hard-to-maintain, when, although not in my case, you have let say 100, 1000 entities?

 

Ok, second option: just extend Container or Sprite and store everything there. Difference explained here: http://www.html5gamedevs.com/topic/19745-attach-callback-to-whenever-a-sprite-is-rendered/?p=111953

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...