У меня есть две сцены. Я переключаюсь между ними, когда сталкиваюсь с триггером. Но при попытке вернуться на первую сцену второй сцены игрок замирает и больше не двигается. Пробовал чистить переменные, но не получается... В консоли ошибок нет. Как я могу это исправить?
Дальнейшее объяснение:
Я хочу свободно переключать сцены. Загрузите первый, когда он сталкивается с триггером во второй сцене, или загрузите первый, когда он сталкивается с триггером во второй сцене. Но после загрузки второй сцены, в случае столкновения с триггером, игрок просто зависает и не двигается.
Это клиентский код.
class FirstScene extends Phaser.Scene {
constructor() {
super({ key: 'first' });
}
init(data) {
console.info('Updating FirstScene');
}
preload() {
this.load.image('player', 'assets/player.png');
this.load.image('otherPlayer', 'assets/player.png');
this.load.image('mouse', 'assets/mouse.png');
}
create() {
cursors = this.input.keyboard.createCursorKeys();
let self = this;
socket.on('currentPlayers', players => {
Object.keys(players).forEach(playerId => {
if (playerId === this.socket.id) {
addPlayer(this, players[playerId]);
} else {
addOtherPlayers(this, players[playerId]);
}
});
});
socket.on('newPlayer', playerInfo => {
addOtherPlayers(this, playerInfo);
});
socket.on('disconnectPlayer', playerId => {
otherPlayers[playerId].destroy();
delete otherPlayers[playerId];
});
socket.on('playerMoved', playerInfo => {
otherPlayers[playerInfo.playerId].x = playerInfo.x;
otherPlayers[playerInfo.playerId].y = playerInfo.y;
});
socket.on('mouseSpawned', mouseInfo => {
const mouse = this.add.sprite(mouseInfo.x, mouseInfo.y, 'mouse').setDisplaySize(50, 50);
mouse.id = mouseInfo.id;
mice[mouse.id] = mouse;
});
addPlayer(this, { x: 400, y: 500 }); // temp location
const trigger = this.add.rectangle(400, -12, 100, 100, 0xffffff).setDisplaySize(50, 50);
// Define the collider after the player has been created
this.physics.add.existing(trigger);
trigger.body.setImmovable(true);
this.physics.add.collider(player, trigger, () => {
this.scene.switch('second');
});
}
update() {
if (player) {
if (cursors.left.isDown) {
player.setVelocityX(-160);
} else if (cursors.right.isDown) {
player.setVelocityX(160);
} else {
player.setVelocityX(0);
}
if (cursors.up.isDown) {
player.setVelocityY(-160);
} else if (cursors.down.isDown) {
player.setVelocityY(160);
} else {
player.setVelocityY(0);
}
socket.emit('playerMovement', { x: player.x, y: player.y });
}
}
}
class SecondScene extends Phaser.Scene {
constructor() {
super({ key: 'second' });
}
preload() {
this.load.image('player', 'assets/player.png');
this.load.image('otherPlayer', 'assets/player.png');
this.load.image('mouse', 'assets/mouse.png');
this.load.image('background', 'assets/background.png');
}
create() {
cursors = this.input.keyboard.createCursorKeys();
let self = this;
this.add.sprite(0, 0, 'background').setOrigin(0, 0);
socket.on('currentPlayers', players => {
Object.keys(players).forEach(playerId => {
if (playerId === this.socket.id) {
addPlayer(this, players[playerId]);
} else {
addOtherPlayers(this, players[playerId]);
}
});
});
socket.on('newPlayer', playerInfo => {
addOtherPlayers(this, playerInfo);
});
socket.on('disconnectPlayer', playerId => {
otherPlayers[playerId].destroy();
delete otherPlayers[playerId];
});
socket.on('playerMoved', playerInfo => {
otherPlayers[playerInfo.playerId].x = playerInfo.x;
otherPlayers[playerInfo.playerId].y = playerInfo.y;
});
socket.on('mouseSpawned', mouseInfo => {
const mouse = this.add.sprite(mouseInfo.x, mouseInfo.y, 'mouse').setDisplaySize(50, 50);
mouse.id = mouseInfo.id;
mice[mouse.id] = mouse;
});
addPlayer(this, { x: 400, y: 500 }); // temp location
const trigger = this.add.rectangle(400, -12, 100, 100, 0xffffff).setDisplaySize(50, 50);
// Define the collider after the player has been created
this.physics.add.existing(trigger);
trigger.body.setImmovable(true);
this.physics.add.collider(player, trigger, () => {
this.scene.switch('first');
});
}
update() {
if (player) {
if (cursors.left.isDown) {
player.setVelocityX(-160);
} else if (cursors.right.isDown) {
player.setVelocityX(160);
} else {
player.setVelocityX(0);
}
if (cursors.up.isDown) {
player.setVelocityY(-160);
} else if (cursors.down.isDown) {
player.setVelocityY(160);
} else {
player.setVelocityY(0);
}
socket.emit('playerMovement', { x: player.x, y: player.y });
}
}
}
const config = {
type: Phaser.AUTO,
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 }
}
},
scene: [FirstScene, SecondScene]
};
const game = new Phaser.Game(config);
const socket = io();
let cursors;
let otherPlayers = {};
let mice = {};
let player;
function addPlayer(self, playerInfo) {
player = self.physics.add.image(playerInfo.x, playerInfo.y, 'player').setDisplaySize(200, 200);
player.setCollideWorldBounds(true);
}
function addOtherPlayers(self, playerInfo) {
const otherPlayer = self.add.sprite(playerInfo.x, playerInfo.y, 'otherPlayer').setDisplaySize(200, 200);
otherPlayer.playerId = playerInfo.playerId;
otherPlayers[playerInfo.playerId] = otherPlayer;
}
Я хочу свободно переключать сцены. Загрузите первый, когда он сталкивается с триггером во второй сцене, или загрузите первый, когда он сталкивается с триггером во второй сцене. Но после загрузки второй сцены, в случае столкновения с триггером, игрок просто зависает и не двигается.
update называется? Вы пытались установить точку останова и выполнить код с помощью отладчика?
FWIW Такое ощущение, что update() { может быть в одном месте с параметром player и вызывается, а не в двух, чтобы сделать его более СУХИМ.
@Kory проверьте консоль браузера на наличие ошибки. Приложения Phaser зависают при возникновении ошибки
@Kory, зависание также может быть вызвано бесконечным циклом, поскольку триггер находится в одном и том же месте, а игрок помещается в положение, в котором может произойти столкновение.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ну, я предполагаю, что ошибка возникает из-за того, что player создается/устанавливается в сцене first, а не больше в сцене second, И в функции update смысла second вы обращаетесь к переменной player. (Или это может быть бесконечный цикл для одной и той же позиции триггера в обеих сценах)
Лучшим решением было бы использовать свойство игрока, а не глобальную переменную. как this.player = .... вам нужно будет создать проигрыватель в каждой сцене и/или передать данные, которыми нужно поделиться.
Информация: Если зависает игра/приложение Phaser, лучшим решением будет проверить консоль браузера на наличие ошибок. Таким образом, вы можете найти причину проблемы, довольно быстро.
Здесь работает урезанная версия вашего кода с вышеупомянутой коррекцией (минус материал сокета):
document.body.style = 'margin:0;';
const TEMP_LOCATION = { x: 20, y: 20 };
class FirstScene extends Phaser.Scene {
constructor() {
super({ key: 'first' });
}
init(data) {
console.info('Updating FirstScene');
}
create() {
this.add.text(10,10, 'SCENE 1');
this.cursors = this.input.keyboard.createCursorKeys();
addPlayer(this, TEMP_LOCATION);
const trigger = this.add.rectangle(400, -12, 100, 100, 0xffffff).setDisplaySize(50, 50);
// Define the collider after the player has been created
this.physics.add.existing(trigger, true);
this.physics.add.collider(this.player, trigger, () => {
this.scene.switch('second');
});
}
update() {
if (this.player) {
if (this.cursors.left.isDown) {
this.player.setVelocityX(-160);
} else if (this.cursors.right.isDown) {
this.player.setVelocityX(160);
} else {
this.player.setVelocityX(0);
}
if (this.cursors.up.isDown) {
this.player.setVelocityY(-160);
} else if (this.cursors.down.isDown) {
this.player.setVelocityY(160);
} else {
this.player.setVelocityY(0);
}
}
}
}
class SecondScene extends Phaser.Scene {
constructor() {
super({ key: 'second' });
}
create() {
this.add.text(10,10, 'SCENE 2');
this.cursors = this.input.keyboard.createCursorKeys();
addPlayer(this, TEMP_LOCATION); // temp location
const trigger = this.add.rectangle(400, -12, 100, 100, 0xffffff).setDisplaySize(50, 50);
// Define the collider after the player has been created
this.physics.add.existing(trigger, true);
this.physics.add.collider(this.player, trigger, () => {
this.scene.switch('first');
});
}
update() {
if (this.player) {
if (this.cursors.left.isDown) {
this.player.setVelocityX(-160);
} else if (this.cursors.right.isDown) {
this.player.setVelocityX(160);
} else {
this.player.setVelocityX(0);
}
if (this.cursors.up.isDown) {
this.player.setVelocityY(-160);
} else if (this.cursors.down.isDown) {
this.player.setVelocityY(160);
} else {
this.player.setVelocityY(0);
}
}
}
}
const config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 }
}
},
scene: [FirstScene, SecondScene]
};
const game = new Phaser.Game(config);
function addPlayer(self, playerInfo) {
self.player = self.physics.add.image(playerInfo.x, playerInfo.y, 'player');
self.player.setCollideWorldBounds(true);
} <script src = "//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>Я бы порекомендовал создать собственную пользовательскую сцену, для наследования от которой дублирование может выглядеть так:
Некоторая очистка кода:
class BaseScene extends Phaser.Scene {
constructor(key) {
super({ key });
}
create() {
this.cursors = this.input.keyboard.createCursorKeys();
addPlayer(this, TEMP_LOCATION);
// and other duplicate code
// ...
}
update() {
if (this.player) {
if (this.cursors.left.isDown) {
this.player.setVelocityX(-160);
} else if (this.cursors.right.isDown) {
this.player.setVelocityX(160);
} else {
this.player.setVelocityX(0);
}
if (this.cursors.up.isDown) {
this.player.setVelocityY(-160);
} else if (this.cursors.down.isDown) {
this.player.setVelocityY(160);
} else {
this.player.setVelocityY(0);
}
}
}
}
class FirstScene extends BaseScene {
constructor() {
super('first');
}
create() {
super.create();
// other none duplicate code
// ...
}
update() {
super.update();
// other none duplicate code
// ...
}
}
class SecondScene extends BaseScene {
constructor() {
super('second' );
}
create() {
super.create();
// other none duplicate code
// ...
}
update() {
super.update();
// other none duplicate code
// ...
}
}
Возможно, уточните, что здесь означает «попытка вернуться к первому из второго».