在 Phaser 3 TypeError 中调用 this.scene.restart(): this.body is undefined
Posted
技术标签:
【中文标题】在 Phaser 3 TypeError 中调用 this.scene.restart(): this.body is undefined【英文标题】:Calling this.scene.restart() in Phaser 3 TypeError: this.body is undefined 【发布时间】:2019-09-07 17:30:20 【问题描述】:我正在尝试在 Phaser 3 中重新启动游戏场景,当调用 this.scene.restart 时,我在 phaser.js 脚本的 setVelocityX 处收到错误消息“this.body is undefined”(未缩小的第 169442 行)脚本,如果有帮助)
我正在使用最新版本的 Phaser,v3.19.0。 当玩家精灵与敌人碰撞时调用 hitEnemy 函数,这会暂停物理并将 gameOver 设置为 true。在 update() 函数中,我正在检查 gameOver 是否为真,以及是否按下了“R”键,在这种情况下会调用 scene.restart() 以下是我的部分代码:
var config =
scene: 'scene1',
type: Phaser.AUTO,
scene: 'scene1',
width: 1080,
height: 890,
pixelArt: true,
physics:
default: 'arcade',
arcade:
gravity:
y: 500
,
debug: true
,
scene:
preload: preload,
create: create,
update: updateDirect
;
function preload()
var progressBar = this.add.graphics();
var progressBox = this.add.graphics();
progressBox.fillStyle(0x222222, 0.8);
progressBox.fillRect(380, 270, 320, 50);
var width = this.cameras.main.width;
var height = this.cameras.main.height;
var loadingText = this.make.text(
x: width / 2,
y: height / 2 - 50,
text: 'Loading...',
style:
font: '20px monospace',
fill: '#ffffff'
);
loadingText.setOrigin(0.5, 0.5);
var percentText = this.make.text(
x: width / 2,
y: height / 2 - 5,
text: '0%',
style:
font: '18px monospace',
fill: '#ffffff'
);
percentText.setOrigin(0.5, 0.5);
var assetText = this.make.text(
x: width / 2,
y: height / 2 + 50,
text: '',
style:
font: '18px monospace',
fill: '#ffffff'
);
assetText.setOrigin(0.5, 0.5);
this.load.image('bgtile', 'bgtile.jpg');
this.load.image('background', 'assets/lava/background2.png');
this.load.image('platformdefault', 'assets/lava/lavaplatform.png');
this.load.image('platform400', 'assets/lava/platform4002.png');
this.load.image('platform500', 'assets/lava/platform500.png');
this.load.image('platform300', 'assets/lava/platform300.png');
this.load.image('platform200', 'assets/lava/platform200.png');
this.load.image('platform100', 'assets/lava/platform100.png');
this.load.image('stopper', 'assets/lava/stopper.png');
this.load.image('sign', 'assets/lava/sign2.png');
this.load.image('enemy', 'assets/lava/enemy2.png');
this.load.spritesheet('dude', 'assets/sprites/dude.png',
frameWidth: 32,
frameHeight: 48
);
this.load.spritesheet('lavafloor', 'assets/lava/lavasprite.png',
frameWidth: 320,
frameHeight: 100
);
//scary flash ooo
flash = this.load.image('flash', 'assets/images/blue-flash.png');
this.load.image('floor', 'assets/lava/floor.png');
//audio
this.load.audio('fantastic', 'assets/audio/fantastic.mp3');
this.load.audio('wait', 'assets/audio/wait.mp3');
this.load.audio('ward', 'assets/audio/ward.mp3');
this.load.audio('whisper1', 'assets/audio/whisper1.mp3');
this.load.audio('whisper2', 'assets/audio/whisper2.mp3');
this.load.audio('whisper3', 'assets/audio/whisper3.mp3');
this.load.audio('whisper4', 'assets/audio/whisper4.mp3');
this.load.audio('hey', 'assets/audio/hey.mp3');
// this.load.video('spider', 'assets/video/spider.mp4');
// this.load.video('skull', 'assets/video/skull.mp4');
this.load.on('progress', function (value)
progressBar.clear();
progressBar.fillStyle(0xffffff, 1);
progressBar.fillRect(390, 280, 300 * value, 30);
percentText.setText(parseInt(value * 100) + '%');
);
this.load.on('fileprogress', function (file)
// console.log(file.src);
assetText.setText('Loading asset: ' + file.key);
);
this.load.on('complete', function ()
progressBar.destroy();
progressBox.destroy();
loadingText.destroy();
percentText.destroy();
assetText.destroy();
);
function create()
bgtile = this.add.image(400, 300, 'background');
this.cameras.main.setBounds(0, 0, 10392, 100);
this.physics.world.setBounds(0, 0, 10392, 710);
cameraHeight = this.cameras.height;
cameraWidth = this.cameras.width;
platforms = this.physics.add.staticGroup();
stoppers = this.physics.add.staticGroup();
var floor = platforms.create(400, 775, 'floor');
sign = this.add.image(400, 560, 'sign').setScale(0.06);
platform1 = createPlatform400(400, 600);
platform2 = createPlatform100(1100, 200);
platform3 = createPlatform300(700,500);
platform4 = createPlatform200(900, 350);
platform5 = createPlatform200(1325, 317);
platform6 = createPlatform100(1605, 358);
fantastic = this.sound.add('fantastic', loop: false, volume: 0.2 );
wait = this.sound.add('wait', loop: true, volume: 0.3 );
ward = this.sound.add('ward', loop: true, volume: 0.2 );
whisper1 = this.sound.add('whisper1', loop: false, volume: 0.1 );
whisper2 = this.sound.add('whisper2', loop: false, volume: 0.2 );
whisper3 = this.sound.add('whisper3', loop: false, volume: 0.2 );
whisper4 = this.sound.add('whisper4', loop: false, volume: 0.2 );
hey = this.sound.add('hey', loop: true, volume: 0.2)
whisper2.play();
whisper2.on('complete', function()
fantastic.play();
);
fantastic.on('complete', function()
hey.play();
);
var frameNames = this.anims.generateFrameNames('lavafloor',
start: 1, end: 4
);
this.anims.create( key: 'lavaAnim', frames: frameNames, frameRate: 4, repeat: -1 );
//player anims
this.anims.create(
key: 'left',
frames: this.anims.generateFrameNumbers('dude',
start: 0,
end: 3
),
//frames refer to spritesheet frames, between 0 and 3 it will be left facing
frameRate: 10, //10 fps
repeat: -1 //stop animation
);
this.anims.create(
key: 'turn',
frames: [
key: 'dude',
frame: 4
],
frameRate: 20
);
this.anims.create(
key: 'right',
frames: this.anims.generateFrameNumbers('dude',
start: 5,
end: 8
),
frameRate: 10,
repeat: -1
);
physics = this.physics; //get the reference to physics to create lava and enemies or platforms
dude = this.physics.add.sprite(0, 100, 'dude').setScale(1.5);
createLava(1274, 760);//add 320 to x for continuous lava
createLava(2000, 760);
enemies = this.physics.add.group();
spawnEnemy(platform3);
wasd = this.input.keyboard.addKeys(
up: Phaser.Input.Keyboard.KeyCodes.W,
down: Phaser.Input.Keyboard.KeyCodes.S,
left: Phaser.Input.Keyboard.KeyCodes.A,
right: Phaser.Input.Keyboard.KeyCodes.D,
space: Phaser.Input.Keyboard.KeyCodes.SPACE,
restart: Phaser.Input.Keyboard.KeyCodes.R,
pause: Phaser.Input.Keyboard.KeyCodes.P,
action: Phaser.Input.Keyboard.KeyCodes.F
);
dude.body.setGravityY(800);
dude.setCollideWorldBounds(true); //prevent running outside game window
this.cameras.main.startFollow(dude, true, 0.08, 0.08);
this.cameras.main.setZoom(1);
this.physics.add.collider(dude, platforms);
this.physics.add.collider(enemies, stoppers, hitStopper, null, this);
this.physics.add.overlap(dude, sign, showText, null, this);
this.physics.add.collider(enemies, platforms);
this.physics.add.collider(dude, enemies, hitEnemy, null, this);
onScreenText = this.add.text(16, 16, '',
fontSize: '32px',
fill: '#fff'
);
playerPosText = this.add.text(dude.x+300, 16, '',
fontSize: '32px',
fill: '#fff'
);
playerPosText.setScrollFactor(0);
function hitEnemy(dude, enemies)
this.physics.pause();
dude.setTint(0xff0000);
dude.anims.play('turn');
gameOver = true;
function updateDirect()
playerPosText.setText('X: ' + parseInt(dude.x) + ' ' + 'Y: ' + parseInt(dude.y));
if ((dude.x >= 380 && dude.x <= 430) && dude.y == 544)
showText("test");
else
showText('');
if(gameOver)
showText("You died\nPress R to restart");
if(wasd.restart.isDown)
this.scene.restart();
gameOver = false;
我在一个主要基于教程示例的项目中使用了它,它运行良好,我在这里使用相同的代码。总的来说,我对 Phaser 和游戏开发非常陌生,因此将不胜感激。 谢谢
【问题讨论】:
能否将create()
和preload()
方法添加到您提供的代码中?
在提供的代码中添加了创建和预加载功能。我已经尝试多次调用scene.restart(),现在我得到了一个不同的错误,“this.frame.source is null”。我通过彻底销毁游戏、移除画布并创建新游戏来解决这个问题,但这并不理想
【参考方案1】:
你可以这样做:
create()
duce.isReady = false
// Your code here...
dude.isReady = true
update()
if(dude.isReady)
dude.body.setVelocityX(...)
// Rest of your code concerning dude
【讨论】:
以上是关于在 Phaser 3 TypeError 中调用 this.scene.restart(): this.body is undefined的主要内容,如果未能解决你的问题,请参考以下文章