我是 Phaser 3 的新手,我一直在尝试创建一个实例,其中玩家精灵与将玩家带到另一张地图的游戏对象发生碰撞。现在,我正试图让玩家将场景从 1 号房屋更改为 2 号房屋,但是当我将玩家精灵移到游戏对象上时,什么也没有发生。没有错误告诉我没有定义或任何东西。就好像改变场景的触发器从来不存在一样
这是 Player.js 文件
export default class Player {
constructor(scene, x, y) {
this.scene = scene;
const anims = scene.anims;
anims.create({
key: 'turn1',
frames: [ { key: 'dude', frame: 32 } ],
frameRate: 20
});
anims.create({
key: 'rdown',
frames: anims.generateFrameNumbers('dude', { start: 0, end: 7 }),
frameRate: 16,
repeat: -1
});
anims.create({
key: 'rright',
frames: anims.generateFrameNumbers('dude', { frames: [ 8, 9, 10, 11, 12, 13, 14, 15 ] }),
frameRate: 16,
repeat: -1
});
anims.create({
key: 'rup',
frames: anims.generateFrameNumbers('dude', { frames: [ 16, 17, 18, 19, 20, 21, 21, 23 ] }),
frameRate: 16,
repeat: -1
});
anims.create({
key: 'rleft',
frames: anims.generateFrameNumbers('dude', { frames: [ 24, 25, 26, 27, 28, 29, 30, 31 ] }),
frameRate: 16,
repeat: -1
});
this.sprite = scene.physics.add.sprite(x, y, "dude", 0).setSize(16, 16).setOffset(0, 8);
this.sprite.anims.play("rdown");
this.gamepad = scene.input.gamepad.once('down', function (pad, button, index) {
this.gamepad = pad;
}, this);
}
update() {
const gamepad = this.gamepad;
const sprite = this.sprite;
const speed = 90;
const prevVelocity = sprite.body.velocity.clone();
sprite.body.setVelocity(0);
if (gamepad.right && gamepad.up) {
sprite.body.setVelocityX(speed);
sprite.body.setVelocityY(-speed);
} else if (gamepad.right && gamepad.down) {
sprite.body.setVelocityX(speed);
sprite.body.setVelocityY(speed);
} else if (gamepad.left && gamepad.up) {
sprite.body.setVelocityX(-speed);
sprite.body.setVelocityY(-speed);
} else if (gamepad.left && gamepad.down) {
sprite.body.setVelocityX(-speed);
sprite.body.setVelocityY(speed);
} else if (gamepad.left) {
sprite.body.setVelocityX(-speed);
} else if (gamepad.right) {
sprite.body.setVelocityX(speed);
} else if (gamepad.up) {
sprite.body.setVelocityY(-speed);
} else if (gamepad.down) {
sprite.body.setVelocityY(speed);
}
sprite.body.velocity.normalize().scale(speed);
if (gamepad.left) {
sprite.anims.play("rleft", true);
} else if (gamepad.left && gamepad.down) {
sprite.anims.play("rleft", true);
} else if (gamepad.left && gamepad.up) {
sprite.anims.play("rleft", true);
} else if (gamepad.right && gamepad.down) {
sprite.anims.play("rright", true);
} else if (gamepad.right && gamepad.up) {
sprite.anims.play("rright", true);
} else if (gamepad.up) {
sprite.anims.play("rup", true);
} else if (gamepad.right) {
sprite.anims.play("rright", true);
} else if (gamepad.down) {
sprite.anims.play("rdown", true);
} else {
sprite.stopOnFrame(sprite.anims.currentAnim.getFrameAt(0))
}
}
}
这是 TestLevel.js 文件
import Player from "./Player.js";
import TestRoom2 from "./TestRoom2.js";
export default class TestRoom extends Phaser.Scene {
map;
player;
constructor() {
super()
}
text;
preload() {
this.load.image('tiles', 'assets/tilemaps/tiles/house1.png');
this.load.spritesheet('dude', 'assets/images/link.png', { frameWidth: 16, frameHeight: 24 });
this.load.tilemapTiledJSON('map', 'assets/tilemaps/maps/TestRoom.json');
this.load.image('exit', 'assets/tilemaps/tiles/exit.png');
}
create()
{
this.map = this.make.tilemap({ key: 'map' });
this.map.landscape = this.map.addTilesetImage('house', 'tiles');
this.map.createLayer("ground", [this.map.landscape], 0, 0);
this.player = new Player(this, 128, 112);
this.map.createLayer("above", [this.map.landscape], 0, 0);
this.cameras.main.setSize(256,224);
this.cameras.main.setBounds(0, 0, this.map.widthInPixels, this.map.heightInPixels);
this.cameras.main.startFollow(this.player.sprite);
this.cameras.main.setDeadzone(4,4);
this.exited = this.physics.add.sprite(112, 220, 'exit').setOrigin(0,0);
this.exitBox= this.physics.add.group({
key: 'exit'});
this.physics.add.collider(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')});
}
update() {
this.player.update();
this.physics.collide(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')});
}
}
另一张地图是一样的,但是用TestRoom代替了TestRoom2。
这是具有游戏配置的主场景
import TestRoom from "./TestRoom.js";
import TestRoom2 from "./TestRoom2.js";
var config = {
type: Phaser.AUTO,
width: 256,
height: 224,
backgroundColor: '#000000',
pixelArt: true,
input: {
gamepad: true
},
physics: {
default: 'arcade',
arcade: {
gravity: { y: 0 },
debug: true
}
},
scene: TestRoom, TestRoom2
};
var game = new Phaser.Game(config);
一切正常。唯一没有的是启动场景变化。
我该怎么做才能解决这个问题?
首先
config
不是100%正确,所有的场景都必须在一个数组中(或者稍后手动添加)。这里你缺少方括号[]
var config = {
type: Phaser.AUTO,
width: 256,
height: 224,
...
scene: [TestRoom, TestRoom2] // <-- missing brackets
};
可以去掉下面一行,从
update
函数中,collider
函数中的create
就够了:
this.physics.collide(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')});
在
create
函数中,更改以下行以传递回调函数的上下文:
this.physics.add.collider(this.player, this.exitBox, function(player, exitBox) { this.scene.start('TestRoom2')}, null, this);
或者使用箭头函数:
this.physics.add.collider(this.player, this.exitBox, (player, exitBox) => { this.scene.start('TestRoom2')});
我认为这应该涵盖我能找到的所有错误。
btw.: 检查浏览器控制台是否有错误,这有助于发现问题。
更新:
我认为创建函数中的行应该是
exited
而不是exitBox
,因为空组永远不会与玩家发生碰撞:
this.physics.add.collider(this.player, this.exited, (player, exited) => { this.scene.start('TestRoom2')});
您可以查看this answer的示例以查看播放器/场景切换的简短工作示例。