Jump to content

Access sprite's data object


piotr
 Share

Recommended Posts

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

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

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

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

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

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?

Link to comment
Share on other sites

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
};

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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