piotr Posted November 28, 2016 Share Posted November 28, 2016 How do populate and retrieve data to and from the sprite's data object? Let's say I want to save Player's stats (speed, attack, health) in it and then retrieve it later. var Player = function (game) { this.data = { 'speed': 1, 'attack': 1, 'health': 1 }; Phaser.Sprite.call(this, game, 0,0); }; Player.prototype = Object.create(Phaser.Sprite.prototype); Player.prototype.constructor = Player; Player.prototype.update = function() { console.log(this.data.speed); }; Link to comment Share on other sites More sharing options...
rich Posted November 28, 2016 Share Posted November 28, 2016 Just like you've done it, but move the 'this.data' assignment to be after 'Phaser.Sprite.call), as that will effectively overwrite the data property you created. The constructor 'call' should usually be one of the first things you do. Link to comment Share on other sites More sharing options...
piotr Posted November 29, 2016 Author Share Posted November 29, 2016 Thanks! It worked. Is this because 'Phaser.Sprite.call' calls the data object constructor in order for me to be able to use it? Link to comment Share on other sites More sharing options...
rich Posted November 29, 2016 Share Posted November 29, 2016 Yeah 'call' sets up a lot of stuff. All kinds of default properties and values. So if you do something like: this.x = 100; this.y = 200; this.data = { bob: 'hello' }; and THEN do 'call', all of that will be overwritten, because they are properties set by the Sprite constructor. Link to comment Share on other sites More sharing options...
piotr Posted November 29, 2016 Author Share Posted November 29, 2016 Thanks, make sense. A followup question: how'd then retrieve data with a boolean condition? var Player = function (game, bool) { this.isCatcher = bool; Phaser.Sprite.call(this, game, 0,0); this.data = { catcherData: { speed: 2000, attack: 200, health: 20, }, throwerData: { speed: 1000, attack: 100, health: 10, }, getData: function() { this.isCatcher? catcherData : throwerData; } }; }; Player.prototype = Object.create(Phaser.Sprite.prototype); Player.prototype.constructor = Player; Player.prototype.update = function() { console.log(this.data.speed); }; Link to comment Share on other sites More sharing options...
drhayes Posted November 30, 2016 Share Posted November 30, 2016 Inside your "getData" function "this" refers to your data object, not your Player object. Because of how JS closures work (and depending on how you want it to work), you could reference "bool" directly inside your "getData" function. You wouldn't be able to switch the player from catcher to thrower dynamically after construction, but maybe that's what you want? If you *do* want to change isCatcher dynamically, you'll probably have to maintain a parent property inside your data object for your "getData" object to pick. Or, better yet, make "getData" a function of the Player object itself, rather than the data object. Make sense? EDIT: Also, if these data never change, consider creating them entirely outside your Player class as globals or something. Just a thought. Link to comment Share on other sites More sharing options...
piotr Posted November 30, 2016 Author Share Posted November 30, 2016 Thanks @drhayes. I'm sorry I wasn't really clear about my intentions, but you guessed them all. Yes, I want to change isCatcher dynamically after creation (I have 2 player objects that could be either a catcher or a thrower). Yes, data should change during gameplay: those are supposed to be player's stats that update on item collection or damage taken and so on... I'd like to access data with one variable depending on the bool: e.g. if player is catcher then this.data.speed is 2000, and if player is not catcher (or is thrower) then this.data.speed is 1000. I wanted to avoid if/else checks on isCathcher everytime I need to access the data object. I moved 'getData' out as function of the player object, 'this.data.speed' is still undefined. Of course 'this.data.throwerData.speed' returns 1000, but the whole point of this is to avoid using '.throwerData'. and '.catcherData' Hope my explanation is clear Link to comment Share on other sites More sharing options...
drhayes Posted December 1, 2016 Share Posted December 1, 2016 There's this underused JS feature called getters/setters: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get Works everywhere. You could stick a getter on your data object called "stats" which returns "catcherData" or "throwerData" based on some other data flag, like "isCatcher" or something? piotr 1 Link to comment Share on other sites More sharing options...
piotr Posted December 2, 2016 Author Share Posted December 2, 2016 Yay, It worked! @drhayes didn't know about JS getters and setters. Thanks a lot! Here's the working code: var Player = function (game, bool) { this.isCatcher = bool; Phaser.Sprite.call(this, game, 0,0); this.data = { catcherData: { speed: 2000, attack: 200, health: 20, }, throwerData: { speed: 1000, attack: 100, health: 10, }, }; Object.defineProperty(this.data, 'stats', { get: function(){ if(this.isCatcher) { return this.data.catcherData; } else { return this.data.throwerData; } }.bind(this) }); }; Player.prototype = Object.create(Phaser.Sprite.prototype); Player.prototype.constructor = Player; Player.prototype.update = function() { console.log(this.data.stats.speed); //outputs 2000 if 'isCatcher' is true, otherwise outputs 1000 }; drhayes 1 Link to comment Share on other sites More sharing options...
drhayes Posted December 2, 2016 Share Posted December 2, 2016 ?? Link to comment Share on other sites More sharing options...
Recommended Posts