Jump to content

Extending Phaser Prototype Objects


Kam100
 Share

Recommended Posts

Hello, I just joined the forum. I was looking for a "Help" section to post my question, but I didn't seem to find one, so I'm posting this here. If this is not the right place, I apologize in advance. I'll try to keep this as succinct as possible. This is pretty basic but I have no idea why is it not working.

Here is relevant part of the working code, done in the way the website teaches us to do:

function create() {
  starfield = game.add.tileSprite(0, 0, 800, 600, 'stars');

  ship = game.add.sprite(300, 400, 'ship');
  ship.health = 100;
  ship.scale.set(2);
  ship.smoothed = false;
  ship.animations.add('fly', [0,1,2,3,4,5], 10, true);
  ship.play('fly');
  ship.anchor.set(0.5);

  game.physics.arcade.enable(ship);

  shipTrail = game.add.emitter(ship.x, ship.y + 10, 1000);
  shipTrail.width = 40;
  shipTrail.makeParticles('emitter');
  shipTrail.setXSpeed(-30, 30);
  shipTrail.setYSpeed(400, 180);
  shipTrail.setRotation(50,-50);
  shipTrail.setAlpha(1, 0, 500);
  shipTrail.setScale(0.05, 0.4, 0.05, 0.4, 100, Phaser.Easing.Quintic.Out);
  shipTrail.start(false, 500, 5);
}

The variable starfield is the background, the ship is the player, and the shiptrail is just an effect that follows the ship around. Their movement is updated in the Update function, but that's irrelevant, so not shown. The code above works perfectly as it is intended, since everything is displayed normally. What I'm trying to accomplish is pretty simple: Instead of using all of the code used above, I'd simply do:

function create() {
  starfield = new Background(game);
  ship = new Ship(game);
  shipTrail = new Emitter(game, ship);
}

on my main file, while having a secondary javascript file that'd take care of those three objects settings. So I came up with this:

function Ship (game) {
  Phaser.Sprite.call(this, game, 300, 400, 'ship');

  this.health = 100;
  this.scale.set(2);
  this.smoothed = false;
  this.animations.add('fly', [0,1,2,3,4,5], 10, true);
  this.play('fly');
  this.anchor.set(0.5);

  game.physics.arcade.enable(this);
}

Ship.prototype = Object.create(Phaser.Sprite.prototype);
Ship.constructor = Ship;

//----------------------------------------------

function Background (game) {
  Phaser.TileSprite.call(this, game, 0, 0, 800, 600, 'stars');
}

Background.prototype = Object.create(Phaser.TileSprite.prototype);
Background.constructor = Background;

//----------------------------------------------

function Emitter (game, ship) {
  Phaser.Particles.Arcade.Emitter.call(this, game, ship.x, ship.y + 10, 1000)

  this.width = 40;
  this.makeParticles('emitter');
  this.setXSpeed(-30, 30);
  this.setYSpeed(400, 180);
  this.setRotation(50,-50);
  this.setAlpha(1, 0, 500);
  this.setScale(0.05, 0.4, 0.05, 0.4, 100, Phaser.Easing.Quintic.Out);
  this.start(false, 500, 5);
}

Emitter.prototype = Object.create(Phaser.Particles.Arcade.Emitter.prototype);
Emitter.constructor = Emitter;

For some reason, only the emitter effect keeps displaying onscreen after doing this. The ship goes invisible and the background goes black. No errors in the console log. Any help?

Link to comment
Share on other sites

There's nothing wrong, that I can see, with how you're extending the Sprites. The only thing I can't see in the above code is where you add them to the game.

They're created properly, but just don't appear to be added to the display list anywhere? Something like:

var ship = new Ship();

this.add.existing(ship);

 

Link to comment
Share on other sites

6 hours ago, rich said:

There's nothing wrong, that I can see, with how you're extending the Sprites. The only thing I can't see in the above code is where you add them to the game.

They're created properly, but just don't appear to be added to the display list anywhere?

Thanks for the reply. I didn't know of this game.add.existing method. And it now works for me, thanks. I still have a doubt though: I didn't have to use game.add.existing(starfield), game.add.existing(ship), and  game.add.existing(shiptrail) on the first code box of my first post in order for the sprites to appear in-game. The moment I did game.add.tileSprite/sprite/emitter they were already automatically added into the screen. So why does game.add.existing needs to be used when creating sprites through extending Phaser's prototype objects? All I needed to do was add "game.add.existing(this);" on both my Ship and Background functions on the secondary javascript file, and everything worked as originally intended.

Link to comment
Share on other sites

When you type "game.add.sprite", Phaser's internal GameObjectFactory knows the class of the thing you're trying to create: it's Phaser.Sprite. It makes one of those, sets some properties, adds it to the world, then hands it back to you.

When you create your own custom class, you can't really use the GameObjectFactory anymore. You have to add the things you create yourself because Phaser no longer knows what constructor to use.

Does that make sense?

Link to comment
Share on other sites

44 minutes ago, drhayes said:

When you type "game.add.sprite", Phaser's internal GameObjectFactory knows the class of the thing you're trying to create: it's Phaser.Sprite. It makes one of those, sets some properties, adds it to the world, then hands it back to you.

When you create your own custom class, you can't really use the GameObjectFactory anymore. You have to add the things you create yourself because Phaser no longer knows what constructor to use.

Does that make sense?

Yes it does, thanks for the answer. I'm glad it was an easy fix.

Link to comment
Share on other sites

game.add.existing() is really just game.world.add(). :)

You can even go nuts and extend GameObjectFactory:

GameObjectFactory.prototype.ship = function (x, y, key, frame, group){
    if (group === undefined) { group = this.world; }

    return group.add(new Ship(this.game, x, y, key, frame));
};

// …

var ship = game.add.ship(300, 400, 'ship');

 

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...