0
\$\begingroup\$

I am working on my first 2D game with Phaser 3. I have set up VS Code with a node.js https server and run it to deploy the game on localhost.

While the game gets compiled successfully and deployed, I get a runtime error when executing the collider and overlap function:

Uncaught TypeError: Cannot read property 'isParent' of undefined
     at World.collideObjects (phaser.js?d4ef:102761)
     ...

For the time being I have a title screen with "welcome to my game" text and it is clickable. Once you click that you are navigating to the play scene. When navigating to the play scene, I am getting that error displayed as you can see here:

Error

I suspect that this is caused by my use of the this keyword and the scope of it. But I have no idea how to fix that. I spent 2-3 hours debugging and playing with 'this.' here and there but I am still clueless as to how I can fix this and what I did wrong.

The comment //Error on "is parent undefined" is added to mark the lines where I get the error.

import Phaser from 'phaser';

class PlayScene extends Phaser.Scene {

constructor() {
    super('PlayScene');
}

create() {
    var player;
    var stars;
    var bombs;
    var bomb;
    var platforms;
    var cursors;
    var score = 0;
    var gameOver = false;
    var gameOverText;
    var scoreText;
    var leftKey;
    var rightKey;
    var upKey;
    var repeatStarCount;
    this.add.image(400, 300, 'sky');

    platforms = this.physics.add.staticGroup();
    platforms.create(390, 568, 'ground1');
  
    platforms.create(750, 200, 'ground2');
    platforms.create(0, 150, 'ground4');
    platforms.create(690, 420, 'ground4');
    platforms.create(100, 320, 'ground4');

    player = this.physics.add.sprite(100, 450, 'dude');
    player.setBounce(0.2);
    player.setCollideWorldBounds(true);
    player.setScale(0.15);
    player.setSize(300, 400, false);
    player.body.offset.y = 0;
    player.body.offset.x = 0;

    //  Input Events
    this.cursors = this.input.keyboard.createCursorKeys();
    this.leftKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT);
    this.rightKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT);
    this.upKey = this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP);

    //  player animations
    this.anims.create({
        key: 'LeftRun',
        frames: this.anims.generateFrameNumbers('dude', {
            start: 14,
            end: 17
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'LeftJump',
        frames: [{
            key: 'dude',
            frame: 13
        }],
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'LeftIdle',
        frames: this.anims.generateFrameNumbers('dude', {
            start: 9,
            end: 10
        }),
        frameRate: 10,
        repeat: -1
    });
    this.anims.create({
        key: 'LeftDizzy',
        frames: this.anims.generateFrameNumbers('dude', {
            start: 10,
            end: 11
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'RightRun',
        frames: this.anims.generateFrameNumbers('dude', {
            start: 5,
            end: 8
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'RightJump',
        frames: [{
            key: 'dude',
            frame: 4
        }],
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'RightIdle',
        frames: this.anims.generateFrameNumbers('dude', {
            start: 0,
            end: 1
        }),
        frameRate: 10,
        repeat: -1
    });

    this.anims.create({
        key: 'RighttDizzy',
        frames: this.anims.generateFrameNumbers('dude', {
            start: 2,
            end: 3
        }),
        frameRate: 10,
        repeat: -1
    });

    //  Some stars to collect, 12 in total, evenly spaced 70 pixels apart along the x axis
    repeatStarCount = 10;
    this.stars = this.physics.add.group({
        key: 'star',
        repeat: repeatStarCount,
        setXY: {
            x: 8,
            y: 0,
            stepX: 50
        },
        setScale: {
            x: 0.05,
            y: 0.05
        }
    });

    this.stars.children.iterate(function(child) {

        child.setBounceY(Phaser.Math.FloatBetween(0.4, 0.8));

    });

    this.bombs = this.physics.add.group();

    var style = {
        font: "30px Arial",
        fill: "#ffff00",
        stroke: "#535353",
        align: "center",
        strokeThickness: 15,
    };

    var style1 = {
        font: "40px Arial",
        fill: "#ffff00",
        stroke: "#535353",
        align: "center",
        strokeThickness: 15,
    };

    scoreText = this.add.text(0, 0, "Score: 0", style);
    gameOverText = this.add.text(300, 250, "Game Over", style1);
    gameOverText.visible = false;

    //  Collide the player and the stars with the platforms
    this.physics.add.collider(player, platforms);
    this.physics.add.collider(stars, platforms);
    this.physics.add.collider(bombs, platforms);
  
    //Error on "is parent undefined"
    this.physics.add.overlap(player, stars, () => {

        star.disableBody(true, true);

        //  Add and update the score
        score += 10;
        scoreText.setText('Score: ' + score);

        if (stars.countActive(true) === 0) {
            repeatStarCount = +3;
            //  A new batch of stars to collect
            stars.children.iterate(function(child) {

                child.enableBody(true, child.x, 0, true, true);

            });

            var x = (player.x < 400) ? Phaser.Math.Between(400, 800) : Phaser.Math.Between(0, 400);

            var bomb = bombs.create(x, 16, 'bomb');
            bomb.setBounce(1);
            bomb.setCollideWorldBounds(true);
            bomb.setVelocity(Phaser.Math.Between(-200, 200), 20);
            bomb.allowGravity = false;

        }

    }, null, this);

   //Error on "is parent undefined"
    this.physics.add.collider(player, bombs, () => {
        this.physics.pause();
        if (player.anims.currentAnim.key === 'RightRun' || player.anims.currentAnim.key === 'RightIdle' || player.anims.currentAnim.key === 'RightJump') {
            player.anims.play('RighttDizzy');
        }

        if (player.anims.currentAnim.key === 'LeftRun' || player.anims.currentAnim.key === 'LeftIdle' || player.anims.currentAnim.key === 'LeftJump') {
            player.anims.play('LeftDizzy');
        }
        gameOver = true;
        let timer = this.time.delayedCall(500, () => {
            player.anims.stop();
            gameOverText.visible = true;
        }, [], this);
    }, null, this);
}

update() {
    if (this.gameOver) {
        return;
    }

    if (this.cursors.left.isDown) {

        player.setVelocityX(-160);
        player.anims.play('LeftRun', true);

    } else if (this.cursors.right.isDown) {

        player.setVelocityX(160);
        player.anims.play('RightRun', true);

    } else if (Phaser.Input.Keyboard.JustUp(this.leftKey)) {

        player.setVelocityX(0);
        player.anims.play('LeftIdle', true);

    } else if (Phaser.Input.Keyboard.JustUp(this.rightKey)) {

        player.setVelocityX(0);
        player.anims.play('RightIdle', true);

    } else if (Phaser.Input.Keyboard.JustUp(this.upKey) && player.anims.currentAnim != null) {

        if (player.anims.currentAnim.key === 'LeftJump') {
            player.anims.play('LeftIdle', true);
        }

        if (player.anims.currentAnim.key === 'RightJump') {
            player.anims.play('RightIdle', true);

        }

    } else if (this.cursors.up.isDown && player.anims.currentAnim != null) {

        if (player.anims.currentAnim.key === 'RightIdle') {
            player.anims.play('RightJump', true);
            if (player.body.touching.down) {
                player.setVelocityY(-350);
            }
        }

        if (player.anims.currentAnim.key === 'LeftIdle') {
            player.anims.play('LeftJump', true);
            if (player.body.touching.down) {
                player.setVelocityY(-350);
            }
        }
    }
}}export default PlayScene;
\$\endgroup\$
1
\$\begingroup\$

I solved this problem. The issue is actually related to variable declaration. So I moved all the variable declarations in to the constructor and that fixed the problem. I don't know whether that is a common practice or not anyway.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .