Jump to content

animations won't work in Sprite object ?


metalNumb
 Share

Recommended Posts

Hey all. 

Here's the problem that i am having. I have this player class called "Avatar", and i am trying to add some animations to that sprite created. Here's what i mean. 

function Avatar(game,spriteTag,x,y) {    // Initialize Player    Phaser.Sprite.call(this,game,x,y,spriteTag); //Calls SPRITE constructor ONLY    this.animations.add('move',[0,1,2,3,4,5,6,7,8,9]);    game.physics.arcade.enable(this);    this.health = null ;    this.energy = null ;}Avatar.prototype.constructor = Avatar;Avatar.prototype = {    moveRight: function () {        this.body.velocity.x = +500;        this.animations.play('move',35,true);    },....}Avatar.prototype = Object.create(Phaser.Sprite.prototype);

Without animations added, this works fine. In the main code i just create an instance of the Avatar object, but with the animations added it gives this error.

Uncaught TypeError: Cannot read property 'add' of undefined                                   phaser.js: 52890

Does this mean that the property "animations" won't get inherited to the extended class Avatar for some reason ? Maybe because Sprite.call only calls the constructor ? I'm not sure about the structure of the phaser code though.

 

How could this be fixed ?

 

Appreciate your help. 

Thanks in advance. 

Link to comment
Share on other sites

It looks like you're overwriting the prototype rather than extending it - your code should be something more like this:

function Avatar(game,spriteTag,x,y) {    // Initialize Player    Phaser.Sprite.call(this,game,x,y,spriteTag); //Calls SPRITE constructor ONLY    this.animations.add('move',[0,1,2,3,4,5,6,7,8,9]);    game.physics.arcade.enable(this);    this.health = null ;    this.energy = null ;}Avatar.prototype = Object.create(Phaser.Sprite.prototype);Avatar.prototype.constructor = Avatar;Avatar.prototype.moveRight = function () {    this.body.velocity.x = +500;    this.animations.play('move',35,true);};...
Link to comment
Share on other sites

Can you please explain it more why adding the constructor line after object creation line makes it extending rather than overriding ?

I know the difference in usual OOP but i don't get it in prototyping terms. (Sorry I'm a Total newbie in prototyping :rolleyes:  )

 

Thanks for the reply !!!  :D

Link to comment
Share on other sites

Can you please explain it more why adding the constructor line after object creation line makes it extending rather than overriding ?

 

Best explained with your original code:

// Here we're setting the existing prototype's constructorAvatar.prototype.constructor = Avatar;// Now we're totally replacing the entire prototype with a new objectAvatar.prototype = {    moveRight: function () {        this.body.velocity.x = +500;        this.animations.play('move',35,true);    },....}// And now we're totally replacing the entire prototype again, this time with the Phaser.Sprite prototypeAvatar.prototype = Object.create(Phaser.Sprite.prototype);

The onTextureUpdate function comes from the PIXI.Sprite object that Phaser.Sprite extends, but the way you're extending the Sprite object is killing off the prototype. If you ensure that rather than replacing the whole prototype with a new object you instead add each new method to the prototype individually, you should hopefully find it works.

 

When you extend an object in JavaScript using Phaser's method, you are doing the following:

  • Create a new constructor object (a function)
  • Give that new constructor the prototype of the object you're extending (the 'super' object)
  • Ensure the constructor for the extended object is set to the new function and not the super object's constructor function, otherwise instantiating it will cause the super object's constructor to run automatically instead of your extended one
  • Now that your object has the correct constructor and inherits all of the super object's prototypes, you can add your own and overwrite any that already exist, but you must do this per property, rather than totally replacing the whole prototype

Then when you instantiate the new extended object, you have a properly extended object with the right constructor, all you have to do then is call the 'super' object's constructor somewhere to initialise all of its values and so on.

Link to comment
Share on other sites

Thank you so much ! 

This makes complete sense and you did a GREAT job explaining that !

 

This is my code now. 

function Avatar(game,spriteTag,x,y) {    // Initialize Player    Phaser.Sprite.call(this,game,x,y,spriteTag); // Calls SPRITE constructor ONLY    this.animations.add('move',[0,1,2,3,4,5,6,7,8,9]);    game.physics.arcade.enable(this);    this.health = null ;    this.energy = null ;}Avatar.prototype = Object.create(Phaser.Sprite.prototype);              // SUPERAvatar.prototype.constructor = Avatar;Avatar.prototype.update = function(){};Avatar.prototype.moveRight = function () {        this.body.velocity.x = +500;        this.animations.play('move',35,true); };

But now i still have this error : 

TypeError: this.game.onPause is undefined

 and it seems that this line causes it, because when i comment it out it works fine. 

this.animations.add('move',[0,1,2,3,4,5,6,7,8,9]);
Link to comment
Share on other sites

Here's the error in more detail... This is a different error that is generated while using CHROME.

The Error in above posts is generated while using FIREFOX.   :huh:

-- Uncaught TypeError: Cannot read property 'add' of undefined    phaser.js:52890 Phaser.Animation                                              phaser.js:52350  Phaser.AnimationManager.add                                   phaser.js:52350 Avatar                                                        Avatar.js:10                                                               myTrialGame.Game_Slim.create                                  Game_Slim.js:30  **THIS IS MAIN FILE** Phaser.StateManager.loadComplete                              phaser.js:18686  Phaser.StateManager.preUpdate                                 phaser.js:18459  Phaser.Game.updateLogic                                       phaser.js:26512  Phaser.Game.update                                            phaser.js:26464  Phaser.RequestAnimationFrame.updateRAF                        phaser.js:46326 _onLoop                                                       phaser.js:46310
Link to comment
Share on other sites

Well i figured that the property animations does not even exist in the created object.

That is the reason for the error.  ( i tried checking this.animations value in the constructor and also in the main code and it is undefined )

 

Can somebody please explain to me why animations is undefined ?

Although i think i extended the Sprite without overriding the animations property or something. 

 

Is there something i am missing here ? :huh:

 

I have tried creating an AnimationManager for my sprite object in the main code but that didn't work either.

Gave me THIS error...

Uncaught TypeError: Cannot read property 'getFrameIndexes' of null

Please help.  :unsure:

Link to comment
Share on other sites

Thanks for taking the time and testing it for me. :rolleyes:

 

Well i am using the latest version phaser v2.2.1.

And the Avatar class is in another file beside the main one ( if that would make any difference). 

 

But i am glad that it worked though and there are no other issues in my code.  :)

Link to comment
Share on other sites

  • 2 weeks later...
  • 3 months later...

I had the same issue (without the prototype problem problem). I had done everything right but I hadn't used this.add.exisiting to tell my object to consider the animation a part of the overall game.

 

this.game.add.existing(this);

 

After adding this it suddenly decided to work! Complete working animation class/prototype below:

 

'use strict';
 
var Bar = function (game, spriteRef, x, y) {
    Phaser.Sprite.call(this, game, x, y, spriteRef);
    this.game.physics.enable(this, Phaser.Physics.ARCADE);
 
    this.animations.add("anim1",[6,5,4,3,2,1,2,3,4,5]);
    this.animations.play("anim1", 4, true); 
    this.game.add.existing(this); // Solved the problem
};
 
Bar.prototype = Object.create(Phaser.Sprite.prototype);
Bar.prototype.constructor = Bar;
Link to comment
Share on other sites

  • 7 months later...
  • 1 year later...

The error I was receiving was:

Quote

Uncaught TypeError: Cannot read property 'getFrameIndexes' of null

And I ended up with a different issue. I am extending a Sprite and my animations are in a textureAtlas/Spritesheet. The issue is that the animation uses frames, but the animation.add() does not know which spritesheet/textureAtlas the frames are from. I solved this issue by including the below code in the constructor.

this.loadTexture(spriteSheetOrTextureAtlasKey);

And now when I `add` an animation the `frames` array is pointing to the correct key.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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