Like this developer, I was following along with this post. Unfortunately, I got an error that says it doesn’t know what “export” means, and I don’t know how to fix it (though, it does load the title scene). Additionally, I’m not sure how to call other JS files from each method of the class (example later). If someone has the time to help, I’d greatly appreciate it.
game.js
import TitleScene from '/js/titleScene.js';
import GameScene from '/js/gameScene.js';
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
scene: [TitleScene, GameScene]
};
var game = new Phaser.Game(config);
titleScene.js
class TitleScene extends Phaser.Scene {
constructor() {
super({ key: 'titleScene' });
}
preload = function () {
this.load.image('background', 'assets/title/welcome.png');
};
create = function () {
var bg = this.add.sprite(0, 0, 'background');
bg.setOrigin(0, 0);
var text = this.add.text(100, 100, 'Welcome to my game!');
text.setInteractive({ useHandCursor: true });
text.on('pointerdown', () => this.clickButton());
};
clickButton() {
this.scene.switch('gameScene');
}
}
export default TitleScene;
gameScene.js
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'gameScene' });
}
// Is it possible to call other JS files from here?
// If I have "gameCreate.js", can I call that from the create() method below ?
init() { };
preload() { }
create() { }
update() { }
end() { }
}
export default GameScene;
For each script that includes export, remove the <script> for it. The imports should all go through game.js.
Also, final scene setup in the tutorial is more complicated than it needs to be. You can just use
import TitleScene from './titleScene.js';
import GameScene from './gameScene.js';
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
scene: [ TitleScene, GameScene ]
};
var game = new Phaser.Game(config);
import TitleScene from '/js/titleScene.js';
import GameScene from '/js/gameScene.js';
I get an “Uncaught SyntaxError: Cannot use import statement outside a module” message in the console.
I thought perhaps it was my paths, but those check out, and game.js is specified as being a module. Can you think of anything else that I might be doing wrong?
Very strange…I got it to work. But in order to do that, I had to make the code changes so that they were correct (type=“module”, etc), and then close down VS22, open it back up, and then hit the page. For some reason, it wasn’t registering that I had made changes…which was apparent when I had an entire code block commented out in game.js, but it was still showing up in the Sources tab in the debugger in Chrome. Weird.
So now that I have titleScene.js loaded and working, it will call gameScene.js when that’s done. However, in the gameScene.js file, the functions in there are empty.
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'gameScene' });
}
init() { };
preload() { } // How do I get this preload to load up my /js/preload.js content?
create() { }
update() { }
end() { }
}
export default GameScene;
How do I go about telling them to use content from other files. For example, previously I had game.js, which had:
So in game.js, I added the imports and set the GameScene prototypes to what I was importing…
import TitleScene from '/js/titleScene.js';
import GameScene from '/js/gameScene.js';
import preload from '/js/preload.js';
import create from '/js/create.js';
import update from '/js/update.js';
GameScene.prototype.preload = preload;
GameScene.prototype.create = create;
GameScene.prototype.update = update;
var config = {
type: Phaser.AUTO,
width: 800,
height: 600,
scene: [TitleScene, GameScene]
};
var game = new Phaser.Game(config);
Then have gameScene.js like this…
class GameScene extends Phaser.Scene {
constructor() {
super({ key: 'gameScene' });
}
// Is it possible to call other JS files from here?
// If I have "gameCreate.js", can I call that from the create() method below ?
init() { };
preload() { }
create() { }
update() { }
end() { }
}
export default GameScene;
And for example, create.js is like this:
function create() {
// Set world bounds
this.physics.world.setBounds(0, 0, 800, 252);
// Other stuff
}
export default create;
Thank you. I’m really grateful for the help, but I feel like I’m just not understanding how to go about structuring everyything.
I would do this in gameScene.js, if at all.
How else would you approach it? For example, I followed the tutorial and ended up with a structure like this:
game.js
preload.js
create.js
update.js
That was really easy, but I’m already hitting the point where it’s making it very messy, with a huge create.js file. What I’d like to do is restructure everything so that I can split that up into other files, I’m just not sure how Phaser does that.
titleScene.js
preload.js
create.js
update.js
game.js
preload.js
create.js
update.js
(and other classes in their own .js file)
If this were your game, and you just wanted a title scene, a game scene, and maybe an end scene, how would you go about doing that and setting it up? I can’t seem to find any examples of this on the Explorer page or the Examples page.
I mean that if you want to modify GameScene.prototype, it makes sense to do it in gameScene.js, where it’s being created and exported.
It’s a little unusual to split up a class into separate modules, but you can still do it. If the main scene methods get unruly people usually add helper methods:
And then load something like gameCreate.js like this:
function gameCreate() {
// Set world bounds
this.physics.world.setBounds(0, 0, 800, 252);
}
It doesn’t understand what world is. When I log this to the console, it recognizes the scene (GameScene) but this.physics comes back as undefined (which should be where Phaser.Physics.Arcade.World exists, right?).
Is there a way to persist something like the player through multiple functions then?
For example, if I declare my player and initialize my player in my create function, it’s undefined in the update function. But if we set the physics on the scene, why wouldn’t it recognize physics.add.sprite?
function gameCreate() {
var ship, asteroids, cursors, events;
// Player
player = this.physics.add.sprite(1000, 252, 'dude');
and then gameUpdate.js
function gameUpdate() {
// Camera follows player
// Breaks on 'player.x', as player is undefined?
scrollX = player.x - game.config.width / 2;
this.cameras.main.scrollX = scrollX;
}
So if I store something in the scene(this.player) then I’ll need to refer to it everywhere else as a part of the scene (referencing this.player since that’s what we’re passing to each function), right?
What about things that we’ll later check inside of another function? For example, if I declare this.cursors in the scene and log it in the console in my gameCreate.js file, it logs fine. But if I try to log it inside of a this.physics.add.overlap in my gameCreate.js then it’s undefined (presumably because of this having a different scope).
Other than reassigning it before checking it (something like var myCursors = this.cursors and then referencing myCursors inside of the function), is there another way to deal with that?
Phaser functions that take a callback argument also take a calling context argument. In overlap() or collider(), it’s the fifth argument, and you can pass this there to keep the scene context.