Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

removeInteractive() error when called in pointerover event's handler #6387

Closed
TomorrowToday opened this issue Feb 12, 2023 · 3 comments
Closed

Comments

@TomorrowToday
Copy link

Version

  • Phaser Version: 3.60.0-beta.18
  • Operating system: MacOS 13.x
  • Browser: Chrome 109

Description

Calling removeInteractive on a game object after a pointover event results in the following error. calling disableInteractive before calling remove, sometimes helps. It might take as many as 10 to 20 events to get the error.

Uncaught TypeError: Cannot read properties of undefined (reading 'cursor')
    at InputManager.resetCursor (3.60.0-beta.18.js:96605:31)
    at InputPlugin.disable (3.60.0-beta.18.js:98115:25)
    at InputPlugin.clear (3.60.0-beta.18.js:98031:14)
    at InputPlugin.preUpdate (3.60.0-beta.18.js:97769:22)
    at EventEmitter.emit (3.60.0-beta.18.js:220:33)
    at Systems.step (3.60.0-beta.18.js:186633:16)
    at SceneManager.update (3.60.0-beta.18.js:183875:21)
    at Game.step (3.60.0-beta.18.js:16986:20)
    at TimeStep.step (3.60.0-beta.18.js:17991:14)
    at step (3.60.0-beta.18.js:30961:19)

Example Test Code

class Bat extends Phaser.GameObjects.Container
{
    constructor (scene, x, y)
    {
        super(scene, x, y);

        const body = scene.add.image(0, 0, 'assets', 'Body02_01');
        const wing1 = scene.add.image(-50, 10, 'assets', 'Wing02_01').setOrigin(1, 0.5);
        const wing2 = scene.add.image(50, 10, 'assets', 'Wing02_02').setOrigin(0, 0.5);

        this.add([ wing2, body, wing1 ]);

        this.body = body;
        this.wing1 = wing1;
        this.wing2 = wing2;

        scene.add.existing(this);

        body.setInteractive(new Phaser.Geom.Circle(170, 170, 100), Phaser.Geom.Circle.Contains);

        body.once('pointerover', () => this.kill());

        this.fly();
    }

    fly ()
    {
        const y = this.y - (Phaser.Math.Between(150, 280));

        this.scene.tweens.add({
            targets: this,
            y,
            ease: 'sine.inout',
            yoyo: true,
            repeat: -1,
            duration: Phaser.Math.Between(900, 1200)
        });

        this.scene.tweens.add({
            targets: this.wing1,
            angle: { start: -20, to: 20 },
            ease: 'sine.inout',
            yoyo: true,
            repeat: -1,
            duration: 200
        });

        this.scene.tweens.add({
            targets: this.wing2,
            angle: { start: 20, to: -20 },
            ease: 'sine.inout',
            yoyo: true,
            repeat: -1,
            duration: 200
        });
    }

    kill ()
    {
        this.body.removeInteractive()
        this.scene.tweens.killTweensOf([ this, this.wing1, this.wing2 ]);

        this.wing1.setAngle(20);
        this.wing2.setAngle(-20);

        this.body.setFrame('Body02_02');

        this.scene.tweens.chain({
            targets: this,
            tweens: [
                {
                    y: '-=100',
                    angle: 270,
                    scale: 0.3,
                    duration: 500
                },
                {
                    angle: 180,
                    y: 800,
                    ease: 'power1',
                    duration: 500
                }
            ],
            onComplete: () => {

                const x = Phaser.Math.Between(100, 700);
                const y = Phaser.Math.Between(300, 500);
                const scale = Phaser.Math.FloatBetween(0.4, 1);

                new Bat(this.scene, x, y).setScale(scale);

                this.destroy();

            }
        });
    }
}

class Example extends Phaser.Scene
{
    constructor ()
    {
        super();
    }

    preload ()
    {
        this.load.image('bg', 'assets/skies/spooky.png');
        this.load.atlas('assets', 'assets/atlas/tweenparts.png', 'assets/atlas/tweenparts.json');
    }

    create ()
    {
        this.add.image(400, 300, 'bg');

        new Bat(this, 600, 300).setScale(0.4);
        new Bat(this, 180, 400).setScale(0.7);
        new Bat(this, 440, 500);
    }
}

const config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    backgroundColor: '#2d2d2d',
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

Additional Information

@TomorrowToday
Copy link
Author

Need anything additional from me to reproduce?

@TomorrowToday
Copy link
Author

Still having this issue with 3.60.0 and Chrome 112. Here is a less complex example. It might take a couple dozen times to get the error, but usually i'll see it after 3 or 4:

class Example extends Phaser.Scene
{
    preload ()
    {
        this.load.image('eye', 'assets/pics/lance-overdose-loader-eye.png');
    }

    create ()
    {
        const sprite = this.add.sprite(400, 300, 'eye').setInteractive();

        sprite.on('pointerover', function (event)
        {
            sprite.removeInteractive();
            setTimeout(()=>{
                sprite.setInteractive()
                this.setTint(0xffffff)
            }, 300)
            this.setTint(0xff0000);
        });
    }
}

const config = {
    type: Phaser.WEBGL,
    parent: 'phaser-example',
    scene: Example
};

const game = new Phaser.Game(config);

@rgk rgk closed this as completed in d35e69c Feb 5, 2024
@rgk
Copy link
Contributor

rgk commented Feb 5, 2024

Adding {useHandCursor: true} to the setInteractive config with the above example helps visualize the issue.

Thank you for submitting this issue. We have fixed this and the fix has been pushed to the master branch. It will be part of the next release. If you get time to build and test it for yourself we would appreciate that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants