Calling Scenes From Separate Files

I am new to this forum, so if I make a breach of any customs you guys have in posting, please tell me. I decided to learn Phaser3 a couple of days ago and wrote most of a pong game that I pushed on Github here. Then, I happened to read up on Scenes in Phaser, and I decided to re-write my program into a few different scenes: a start scene with a menu, a game scene, and a death scene that evaluates who won and lost. However, I have been encountering mild difficulties in calling various scenes from main.js, and if anyone can see what is wrong with my code, it would be great if you could point out my error(s)! Thank you very much!

So far, I just want to call the death scene from the main scene to see if it works, but it only shows a white screen and doesn’t even load the black canvas for the program (it worked fine before I chopped it into scenes :stuck_out_tongue: ). Also, the file organization in my program is situated thus:

assets

  • ball.png
  • ground.png
  • horizontal_border.png
  • paddle.png

src

  • classes
  • scenes
    • EndScreen.js
    • game.js
  • styles
    • main.css
  • main.js

.gitignore
index.html
phaser.js
readme.md

The Code in my relevant files (I am just trying to load the death screen (src/scenes/EndScreen.js) from src/main.js for now, I can figure the rest out later):

index.html (works fine actually, I don’t think there is an error here):

<!DOCTYPE html>
<html>
   <head>
   <title>
      Learning_example
   </title>
   <script src="//cdn.jsdelivr.net/npm/phaser@3.51.0/dist/phaser.min.js"></script>
   <script src="phaser.js"></script>
   </head>
<body>
   <script src="src/main.js"></script>
</html>

main.js:

import EndScreen from './scenes/EndScreen'

var config = {
	type: Phaser.AUTO,
	pixelArt: false,
	roundPixels: false,
	width: 1000,
	height: 700,
	backgroundColor: 0x000000,
	
	physics: {
		default: 'arcade',
		arcade: {
			gravity: { y: 0, x: 0 },
			debug: true
		}h
	},
	
	scenes: [ EndScreen ]
};

var game = new Phaser.Game(config);

DeathScreen.js:

class EndScreen extends Phaser.Scene {
	
	constructor() {
		super({ key: 'EndScreen' });
	}
	
	preload() {
		// this.load.image('shape', '../assets/ball.png');
	}
	
	create() {
		// this.add.image(100, 100, 'shape');
		this.add.text(40, 40, 'ReadMe!!!', { 	fontSize: '64px', fill: '#bbf' });
	}
	
	update() {
	}
}

game.js (not using this right now, but might as well post the code):

import config from '../main'

var player;
var ai;
var ball;

var playerScore = 0;
var aiScore = 0;

var playerScoreText;
var aiScoreText;

var playerWon = false;
var aiWon = false;

var cursors;

var paddle = {
	width: 20,
	height: 100,
	sprite: 'paddle',
}

var playerConfig = {
	startingX: 20,
	startingY: (config.height / 2) - (paddle.height / 2),
	velocityX: 0,
	velocityY: 0,
}

var aiConfig = {
	startingX: config.width - (50),
	startingY: (config.height / 2) - (paddle.height / 2),
	velocityX: 0,
	velocityY: 0,
}

var ballConfig = {
	velocityX: 400,
	velocityY: 400,
	
	startingX: (config.width / 2) - (30 / 2),
	startingY: (config.height / 2) - (30 / 2),
}

var SceneOne = new Phaser.Class(
{
	extends: Phaser.Scene(),
	
	initialize: function()
	{
		Phaser.Scene.call(this, {"key": "SceneOne"});
	},
	
	preload: function()
	{
		this.load.image('ball', './assets/ball.png');
		this.load.image('paddle', './assets/paddle.png');
		this.load.image('horiz_border', './assets/horizontal_border.png');
	},
	
	create: function()
	{
		player = this.physics.add.sprite(playerConfig.startingX, playerConfig.	startingY, 'paddle').setOrigin(0, 0).setImmovable();
		ai = this.physics.add.sprite(aiConfig.startingX, aiConfig.startingY, 	'paddle').setOrigin(0, 0).setImmovable();
		ball = this.physics.add.sprite(ballConfig.startingX, ballConfig.startingY, 'ball').setOrigin(0, 0);
		
		player.setCollideWorldBounds(true);
		ai.setCollideWorldBounds(true);
		ball.setCollideWorldBounds(true);
		
		this.physics.add.collider(player, ball);
		
		this.physics.add.collider(ai, ball);
		
		initialiseBall();
		
		playerScoreText = this.add.text(config.width/3, config.height / 3, '0', { 	fontSize: '64px', fill: '#fff' });
		aiScoreText = this.add.text(config.width*2/3, config.height*2 / 3, '0', { 	fontSize: '64px', fill: '#fff' });
		
		cursors = this.input.keyboard.createCursorKeys();
	},

	update: function()
	{
		updatePlayer();
		updateAI();
		checkForScore();
	},
	
	initialiseBall: function() 
	{
		ball.x = config.width / 2;
		ball.y = Phaser.Math.Between(25, config.height - (20 + 5));
		
		ball.setBounce(1);
		
		var goingUp = Phaser.Math.Between(0, 1);
		var goingRight = Phaser.Math.Between(0, 1);
		
		if(goingUp === 1)
		{
			ball.setVelocityY(ballConfig.velocityY);
		}
		else
		{
			ball.setVelocityY(- ballConfig.velocityY);
		}
		if(goingRight ===1)
		{
			ball.setVelocityX(ballConfig.velocityX);
		}
		else
		{
			ball.setVelocityX(- ballConfig.velocityX);
		}
	},
	
	updatePlayer: function()
	{
		if(cursors.up.isDown)
		{
			player.setVelocityY(-300);
		}
		else if(cursors.down.isDown)
		{
			player.setVelocityY(300);
		}
		else
		{
			player.setVelocityY(0);
		}
	},
	
	updateAI: function()
	{
		let difference = 1.5 * Math.sqrt(Math.abs(ball.y - ai.y) + 40);
		let speed;
		
		if (difference > 400)
		{
			speed = 400;
		}
		else if (difference < 100 && difference > 10)
		{
			speed = 50;
		}
		else 
		{
			speed = difference + 20;
		}
		if(ball.y > ai.y)
		{
			ai.setVelocityY(26*difference);
		}
		else if(ball.y < ai.y)
		{
			ai.setVelocityY(-26*difference);
		}
		else
		{
			ai.setVelocityY(0);
		}
	},

	checkForScore: function()
	{
		if(ball.x < 1)
		{
			aiScore++;
			aiScoreText.setText(aiScore);
			
			initialiseBall();
		}
		if(ball.x > (config.width - 41))
		{
			playerScore++;
			playerScoreText.setText(playerScore);
			
			initialiseBall();
		}
	},
	
	checkForWin: function()
	{
		if(aiScore >= 3)
		{
			aiWon = true;
		}
		else if(playerScore >= 3)
		{
			playerWon = true;
		}
	},
});

Check the browser console for errors. But I think you need type=module on the main script.

Alright, I identified the main issue, but I still can’t figure out what to do to keep code in separate files. The issue is importing scene classes from other files. When I define a class in ‘./scenes/main.js’ file where the program begins, it works fine, but when I import a class from another file (’./scenes/titleScreen.js’), the javascript console freaks out, claiming that " import call expects exactly one argument". The confusing element in this, however, is that I have been using what Visual Studio Code appears to accept as valid code, and everything I have found on the internet (so far), verifies both my syntax and usage of import and export. In addition, I get other import warnings when I change up the import call.

main.js

import TitleScene from "./scenes/titleScreen";


var titleScene = new TitleScene();

var config = {
	type: Phaser.AUTO,
	pixelArt: false,
	roundPixels: false,
	width: 1000,
	height: 700,
	backgroundColor: 0x000000,
	
	physics: {
		default: 'arcade',
		arcade: {
			gravity: { y: 0, x: 0 },
			debug: true
		}
	},
	
	scenes: [ titleScene ]
};

var game = new Phaser.Game(config);

game.scene.add('titleScene', titleScene);

game.scene.start('titleScene');

console.log('hello');

titleScreen.js

class TitleScene extends Phaser.Scene {

	constructor() {
		super({key:'titleScene'});
	}

	preload() {
		// this.load.image('background', 'images/background.jpg');
	}

	create() {
		var text = this.add.text(100,100, 'Welcome to my game');
	}
}

export default TitleScene;

Thank you in advance!! :slight_smile:

Edit: I made my js files into module scripts in my main.html, and fixed a couple import misspellings, so it works now!