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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.