If you do not try to move to another location, the player sees the other player and his movement, otherwise the player sees only the player, but not his movement. I tried to clear the groups, but it didn't help. I want you to see the movement of the other player when you switch the scene, if there is one there. I use phaser 3, mysql2.
Client code
const socket = io();
class BaseScene extends Phaser.Scene {
constructor(key) {
super({ key });
this.spawned = false;
this.otherPlayers = {};
this.nicknames = {};
}
create() {
const self = this;
this.cursors = this.input.keyboard.createCursorKeys();
this.otherPlayers = this.physics.add.group();
}
update() {
if (this.player && this.player.body) {
let moved = false;
if (this.cursors.left.isDown) {
this.player.setVelocityX(-160);
moved = true;
} else if (this.cursors.right.isDown) {
this.player.setVelocityX(160);
moved = true;
} else {
this.player.setVelocityX(0);
}
if (this.cursors.up.isDown) {
this.player.setVelocityY(-160);
moved = true;
} else if (this.cursors.down.isDown) {
this.player.setVelocityY(160);
moved = true;
} else {
this.player.setVelocityY(0);
}
if (moved) {
socket.emit('playerMovement', { x: this.player.x, y: this.player.y });
}
}
}
}
class FirstScene extends BaseScene {
constructor() {
super('first');
}
create() {
super.create();
this.add.text(10, 10, 'LOCATION 1');
socket.emit('createPlayer');
socket.on('playerCreated', (playerData) => {
addPlayer(this, playerData);
this.trigger = this.add.rectangle(400, -12, 100, 100, 0xffffff).setDisplaySize(50, 50);
this.physics.add.existing(this.trigger, true);
this.physics.add.collider(this.player, this.trigger, (player, trigger) => {
socket.emit('TriggerFirstScene', player);
});
});
socket.on('playerMoved', (playerData) => {
playerMoved(this, playerData);
});
socket.on('newPlayer', (players) => {
addOtherPlayer(this, players);
});
socket.on('TriggerFirstScene', (playerData) => {
this.scene.switch('second');
});
}
update() {
super.update();
}
}
class SecondScene extends BaseScene {
constructor() {
super('second');
}
create() {
super.create();
this.add.text(10, 10, 'LOCATION 2');
socket.emit('createPlayer2');
socket.on('playerCreated2', playerData => {
addPlayer(this, playerData);
this.trigger = this.add.rectangle(400, -12, 100, 100, 0xffffff).setDisplaySize(50, 50);
this.physics.add.existing(this.trigger, true);
this.physics.add.collider(this.player, this.trigger, (player, trigger) => {
socket.emit('TriggerSecondScene', this.player);
});
socket.on('TriggerSecondScene', (playerData) => {
this.scene.switch('first');
});
});
socket.on('playerMoved2', (playerData) => {
playerMoved(this, playerData);
});
socket.on('newPlayer2', (players) => {
addOtherPlayer(this, players);
});
}
update() {
super.update();
// other none duplicate code
// ...
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 700,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 }
}
},
scene: [FirstScene, SecondScene]
};
const game = new Phaser.Game(config);
function addPlayer(self, playerData) {
self.player = self.physics.add.image(playerData.x, playerData.y, 'player').setDisplaySize(100, 100);
self.player.setCollideWorldBounds(true);
self.player.playerId = playerData.playerId;
}
function addOtherPlayer(self, players) {
players.forEach((playerData) => {
const existingPlayer = self.otherPlayers.getChildren().find((otherPlayer) => otherPlayer.playerId === playerData.id);
if (!existingPlayer) {
this.otherPlayer = self.physics.add.sprite(playerData.x_position, playerData.y_position, 'player').setDisplaySize(100, 100);
this.otherPlayer.playerId = playerData.id;
self.otherPlayers.add(otherPlayer);
}
});
}
function playerMoved(self, playerData) {
self.otherPlayers.getChildren().forEach((otherPlayer) => {
if (playerData.playerId === otherPlayer.playerId) {
otherPlayer.setPosition(playerData.x, playerData.y);
}
});
}
Server code
io.on('connection', (socket) => {
console.log('A user connected');
if (socket.handshake.session && socket.handshake.session.user) {
socket.on('createPlayer', async () => {
try {
const userId = socket.handshake.session.user.id;
socket.emit('currentUserId', userId);
const [rows] = await pool.query('SELECT `id`, `nickname`, `login`, `password`, `age`, `x_position`, `y_position`, `clan`, `post`, `location`, `created_at` FROM `users` WHER WHERE id = ?', [userId]);
if (rows.length > 0) {
let playerData = {
playerId: userId,
x: rows[0].x_position,
y: rows[0].y_position,
nickname: rows[0].nickname,
};
socket.emit('playerCreated', playerData);
const [rows2] = await pool.query('SELECT `id`, `nickname`, `age`, `x_position`, `y_position`, `location`, `created_at` FROM users WHERE id != ? AND location = ?', [userId, 1]);
socket.emit('newPlayer', rows2)
} else {
}
} catch (error) {
console.error(error);
}
});
socket.on('createPlayer2', async () => {
try {
const userId = socket.handshake.session.user.id;
socket.emit('currentUserId', userId);
const [rows] = await pool.query('SELECT `id`, `nickname`, `age`, `x_position`, `y_position`, `location`, `created_at` FROM `users` WHERE id = ? AND location = ?', [userId, 2]);
if (rows.length > 0) {
let playerData = {
playerId: userId,
x: rows[0].x_position,
y: rows[0].y_position,
nickname: rows[0].nickname,
};
socket.emit('playerCreated2', playerData);
const [rows2] = await pool.query('SELECT `id`, `nickname`, `age`, `x_position`, `y_position`, `location`, `created_at` FROM users WHERE id != ? AND location = ? ', [userId, 2]);
socket.emit('newPlayer2', rows2)
} else {
}
} catch (error) {
console.error(error);
}
});
socket.on('playerMovement', async (data) => {
try {
const userId = socket.handshake.session.user.id;
const { x, y } = data;
await pool.query('UPDATE users SET x_position = ?, y_position = ? WHERE id = ?', [x, y, userId]);
socket.broadcast.emit('playerMoved', { playerId: userId, x, y });
} catch (error) {
console.error(error);
}
});
app.get('/game.html', async (req, res) => {
res.render('game', { user: req.session.user });
});
server.listen(3000, (err) => {
if (err) {
console.error('Error starting the server:', err);
} else {
console.log('Server is running on http://localhost:3000');
}
});
Well honestly I don't really understand, what you want to achieve with your code, it is far to complicated.
THAT said there are some issue here:
FirstScenetoSecondScene, the socket eventsplayerMovedmight trigger (I'm not 100% sure if phaser will not put them to sleep or not), BUT they are triggering on theFirstScene, sinceplayerMoved(this, playerData);is scoped in theFirstScene.SecondSceneyou are only quering the players in the location 2, and I can't see any code "moving" the player to that new location.A Code structure that would be more readable / structured / easy to debug:
(Simply have one Scene, that manages the other scenes)