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.
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?
Changing this to self fixed it, that would never have come to my mind, thanks for pointing that out. : )