Setting text to a sprite [and container not working]

I want to put names over players head, but I’ve been searching for a while. The thing I found said to use containers, but it gives me theres no such thing as container error (phaser@3.15.1)

What is the simplest way to move text with the character (without literally moving the text, because then I need to move everything twice)

Btw I started doing Phaser stuff today, so I don’t know much.

Hello @Terobero and welcome to Phaser 3. I would use a container in your case.

Have a look at the this official example about containers (sprite and text).

For more informations about containers have a look at my cheatsheet. You will find links to the official code and at the bottom links to some references, f.e. the Phaser 3 Dev Log #120 which was also about containers.

1 Like

A container is the simplest way to go. Can you post the code that is throwing the error?

game.js:64 Uncaught TypeError: Cannot read property ‘container’ of undefined
at addPlayer (game.js:64)
at game.js:33
at Array.forEach ()
at r. (game.js:32)
at r.emit (index.js:83)
at r.onevent (index.js:83)
at r.onpacket (index.js:83)
at r. (index.js:83)
at r.emit (index.js:83)
at r.ondecoded (index.js:83)

This is a part of the code:

function create() {
var self = this;
this.socket = io();
this.otherPlayers = this.physics.add.group();
this.socket.on(‘currentPlayers’, function (players) {
Object.keys(players).forEach(function (id) {
if (players[id].playerId === self.socket.id) addPlayer(self, players[id]);
else addOtherPlayers(self, players[id]);
});
});
this.socket.on(‘newPlayer’, function (playerInfo) {
addOtherPlayers(self, playerInfo);
});
this.socket.on(‘disconnect’, function (playerId) {
self.otherPlayers.getChildren().forEach(function (otherPlayer) {
if (playerId === otherPlayer.playerId) otherPlayer.destroy();
});
});
this.cursors = this.input.keyboard.createCursorKeys();
}

function update() {
if (this.player) {
if (this.cursors.left.isDown) this.player.setAngularVelocity(-150);
else if (this.cursors.right.isDown) this.player.setAngularVelocity(150);
else this.player.setAngularVelocity(0);
if (this.cursors.up.isDown) this.physics.velocityFromRotation(this.player.rotation + 1.5, -100, this.player.body.acceleration);
else if (this.cursors.down.isDown) this.physics.velocityFromRotation(this.player.rotation + 1.5, 100, this.player.body.acceleration);
else this.player.setAcceleration(0);
this.physics.world.wrap(this.player, 5);
}
}

function addPlayer(self, playerInfo) {
self.player = self.physics.add.image(playerInfo.x, playerInfo.y, ‘player’).setOrigin(0.5, 0.5).setDisplaySize(100, 100);
var container = this.add.container(400, 300);
if (playerInfo.team === ‘blue’) self.player.setTint(0x0000ff);
else self.player.setTint(0xff0000);
self.player.setDrag(100);
self.player.setAngularDrag(100);
self.player.setMaxVelocity(200);
}

Took me a bit to see what was going on. Because you are calling addPlayer from the forEach it is taking it out of scope. You can either bind the forEach like this:

Object.keys(players).forEach(function (id) {
if (players[id].playerId === self.socket.id) addPlayer(self, players[id]);
else addOtherPlayers(self, players[id]);
}.bind(this));

or since you are setting self to this

You can simply say self.add.container since self refers to the scene.

Does that make sense?

3 Likes

Changing this to self fixed it, that would never have come to my mind, thanks for pointing that out. : )