I have this error when I touch a wall to change scene:
Cannot read properties of undefined (reading 'start')
I tried several techniques but none worked, yet I have no other errors and my code is quite simple and I don't understand why it doesn't work... Here is my code:
class SceneMilieu extends Phaser.Scene {
constructor() {
super({key: 'sceneMilieu'});
}
//Chargement des images
preload() {
// this.load.image("Backgrond", "javascript/assets/Background.png");
this.load.image("player", "javascript/assets/player.png");
this.load.image("run1", "javascript/assets/run1.png");
this.load.image("run2", "javascript/assets/run2.png");
this.load.image("playerLeftRun1", "javascript/assets/playerLeftRun1.png");
this.load.image("playerLeftRun2", "javascript/assets/playerLeftRun2.png");
this.load.image("wall", "javascript/assets/wall.png");
}
create() {
cursor = this.input.keyboard.createCursorKeys(); //touches des fleches
var w = config.width;
var h = config.height;
//Les animations
this.anims.create({
key : "playerWalkUp",
frames : [
{key : "run1"},
{key : "run2"}],
frameRate : 7,
repeat : 0
})
this.anims.create({
key : "playerWalkLeft",
frames : [
{key : "playerLeftRun1"},
{key : "playerLeftRun2"}],
frameRate : 7,
repeat : 0
})
// L'apparition + le controle et les collisions ce fais ci dessous
// var backgroundImage = this.add.sprite(0, 0, "Background");
// backgroundImage.setPosition(w/2, h/2);
player = this.physics.add.sprite(100, 300, "player"); //joueur
player.setScale(1);
player.body.setSize(30, 35);
player.setCollideWorldBounds(true); //collision avec la bordure
doorLeft = this.physics.add.staticSprite(200, 400, "wall"); //Porte de tp
var platforms = this.physics.add.staticGroup();
var wall = this.add.sprite(400, 500, "wall"); //mur
this.physics.add.collider(platforms, player); //collision
platforms.add(wall);
function collision() {
this.scene.start("sceneGauche");
}
this.physics.add.collider(player, doorLeft, collision);
}
update() {
// Tous les mouvement sont controler par ce code
if (cursor.left.isDown){
player.setVelocityX(-200); //vitesse de deplacements
player.anims.play("playerWalkLeft", true); //animations du personnage
player.setFlip(false, false); //oriantation de l'image
} else if (cursor.right.isDown){
player.setVelocityX(200);
player.anims.play("playerWalkLeft", true);
player.setFlip(true, false);
} else if (cursor.up.isDown){
player.setVelocityY(-200);
player.anims.play("playerWalkUp", true);
player.setFlip(false, false);
} else if (cursor.down.isDown){
player.setVelocityY(200);
player.anims.play("playerWalkUp", true);
player.setFlip(false, true);
} else {
player.setVelocity(0);
player.setTexture("player");
}
if ((cursor.left.isDown && cursor.up.isDown) || (cursor.left.isDown && cursor.right.isDown) || (cursor.left.isDown && cursor.down.isDown) || (cursor.right.isDown && cursor.up.isDown) || (cursor.right.isDown && cursor.down.isDown)){
player.setVelocity(0);
player.setTexture("player");
}
//--------
}}
class SceneGauche extends Phaser.Scene {
constructor() {
super({key: "SceneGauche"});
scene: {
preload: this.preload;
create: this.create;
update: this.update;
}
}
preload() {
this.load.image("player", "javascript/assets/player.png");
this.load.image("run1", "javascript/assets/run1.png");
this.load.image("run2", "javascript/assets/run2.png");
this.load.image("playerLeftRun1", "javascript/assets/playerLeftRun1.png");
this.load.image("playerLeftRun2", "javascript/assets/playerLeftRun2.png");
this.load.image("wall", "javascript/assets/wall.png");
}
create() {
cursor = this.input.keyboard.createCursorKeys();
var w = config.width;
var h = config.height;
this.anims.create({
key : "playerWalkUp",
frames : [
{key : "run1"},
{key : "run2"}],
frameRate : 7,
repeat : 0
})
this.anims.create({
key : "playerWalkLeft",
frames : [
{key : "playerLeftRun1"},
{key : "playerLeftRun2"}],
frameRate : 7,
repeat : 0
})
player = this.physics.add.sprite(100, 300, "player");
player.setScale(1);
player.body.setSize(30, 35);
const border = player.setCollideWorldBounds(true);
var platforms = this.physics.add.staticGroup();
var wall = this.add.sprite(400, 500, "wall");
platforms.add(wall);
this.physics.add.collider(platforms, player);
player.onCollide = new Phaser.signal();
border.onCollide.add(changeMapGauche, this);
}
update() {
if (cursor.left.isDown){
player.setVelocityX(-200);
player.anims.play("playerWalkLeft", true);
player.setFlip(false, false);
} else if (cursor.right.isDown){
player.setVelocityX(200);
player.anims.play("playerWalkLeft", true);
player.setFlip(true, false);
} else if (cursor.up.isDown){
player.setVelocityY(-200);
player.anims.play("playerWalkUp", true);
player.setFlip(false, false);
} else if (cursor.down.isDown){
player.setVelocityY(200);
player.anims.play("playerWalkUp", true);
player.setFlip(false, true);
} else {
player.setVelocity(0);
player.setTexture("player");
}
if ((cursor.left.isDown && cursor.up.isDown) || (cursor.left.isDown && cursor.right.isDown) || (cursor.left.isDown && cursor.down.isDown) || (cursor.right.isDown && cursor.up.isDown) || (cursor.right.isDown && cursor.down.isDown)){
player.setVelocity(0);
player.setTexture("player");
}
}
}
var config = {
type: Phaser.AUTO,
width: window.innerWidth - 20,
height: window.innerHeight - 100,
backgroundColor: "#EDEED0",
physics: {
default : "arcade",
arcade : {
debug : true,
}
},
scene: [SceneMilieu, SceneGauche]
};
let game = new Phaser.Game(config);
var cursor;
var player;
var doorLeft;
<!-- begin snippet: js hide: false console: true babel: false -->
<!DOCTYPE html>
<html lang="fr-FR">
<head>
<meta charset="utf-8" />
<meta name="description" content="Page web du projet de NSI. Ce site regrouppe quelque jeux en ligne programmer par nous même en javascript" />
<meta name="author" content="Thorvald Helbling, Alexis STOCK, Lionel FUCHS" />
<title>Thoralial</title>
<link rel="stylesheet" type="text/css" href="style.css" />
<script src="//cdn.jsdelivr.net/npm/[email protected]/dist/phaser.js"></script>
</head>
<header>
<img id="LogoThoralial" src="info/image/LogoThoralial.png" alt="Logo du site" />
<div>
<h1>Bienvenue !</h1>
<p>C'est votre tableau de bord.</p>
</div>
</header>
<body>
<script id="js" type="text/javascript" src="javascript/main.js"></script>
<script></script>
</body>
<footer>
<div id="personne">
<p>
Ce projet a étais réalisé par : <a href="***"> Thorvald HELBLING</a>, <a href="***"> Lionel FUCHS </a> et <a href="***"> Alexis STOCK </a>
</p>
</div>
</footer>
</html>
I would like to understand where my error comes from and common fixed it. I use Phaser3 The error comes from the site console. (Local)
The problem is this line of code:
this.physics.add.collider(player, doorLeft, collision);
You only need to pass the scene
as context to the collider
function. Here is a link to the documentation, especially for the collider
function and parameters. https://newdocs.phaser.io/docs/3.52.0/focus/Phaser.Physics.Arcade.Factory-collider
With other words, you just have to pass the scene
context (as parameter 5) and a should process function (parameter 4, in this case undefined
, since there is no function)
Just replace the current line, with this line (or add the two parameters), and it should work
this.physics.add.collider(player, doorLeft, collision, undefined, this);
Or you can use the javascript function bind
:
this.physics.add.collider(player, doorLeft, collision.bind(this));
Might not be as obvious, but it is shorter and works fine (Link to bind
documentaion). This would be my prefered mehtod, if I don't use the parameter 4, since the code likes much cleaner and shorter this way.
Update: Alternativly if you want to use Closures you could change only the function definition, to a arrow function expression, then you would not have to pass any extra parameter, do the collider
function:
let collision = () => {
this.scene.start("sceneGauche");
}
I'm in usually no fan of defining functions inside of function/methods (especially with the
function
keyword), but with the arrow function expression, it's looks even abit cleaner.