Problem with Mouse Pointer Lock and Events (Solved-ish, extension should still be updated)

Normally I’d create a pause menu using the escape key for my game, I cannot do that when the mouse pointer is locked because pressing the escape key while locked triggers a default behaviour where it unlocks the cursor and completely ignores any events you’d have assigned to that key, you need to press it again.

I tried doing another thing where it checked if the mouse pointer was unlocked to display the pause screen, BUT there’s a problem with this also, it makes it so whatever key you were pressing gets stuck like it’s being held down, so if you were holding the forward key when you pressed escape, you’ll keep moving forward even when not holding it.

The escape key being the pause key is THE standard for first person games or pretty much every single computer game with keyboard controls, what am I supposed to do???

How are you locking the mouse? Can you screen shot the events?

Using the MousePointerLock extension. Heads up I’ve heard things about the default javascript mouse pointer lock behaviour being impossible to work around thanks to the standards set by browsers, but the keys getting stuck is specially horrible.
image
image

You may be best to get in touch with the author/contributors (Pandako & davy) and ask if it’s possible to update the extension to cater for this.

I ended up just editing the javascript myself. Changed the onSceneFirstLoaded function

class PointerLockHandler {
    movementX = 0;
    movementY = 0;
    retried = false;
    /**
     * @type {gdjs.RuntimeGame}
     */
    game;

    /**
     * @param {gdjs.RuntimeGame} game
     */
    constructor(game) {
        this.game = game;
        const canvas = game.getRenderer().getCanvas();
        
        //DISABLE HELD KEYS WHEN ESCAPING
        document.addEventListener("pointerlockchange", () => {
            if (!document.pointerLockElement) {
                this.onPointerLockExit();
            }
        });

        canvas.addEventListener("pointermove", event => {
            if (!!document.pointerLockElement) {
                this.movementX += event.movementX || 0;
                this.movementY += event.movementY || 0;
            }
        }, false);

        document.addEventListener("pointerlockerror", event => {
            if (!this.retried) {
                canvas.requestPointerLock();
                this.retried = true;
            }
        });
    }

    //DISABLE HELD KEYS WHEN ESCAPING
    onPointerLockExit() {
    //Reset mouse deltas
    this.resetMovement();

    const inputManager = this.game.getInputManager();
    if (!inputManager) return;

    //Clear stuck keyboard keys
    if (inputManager._pressedKeys) {
        inputManager._pressedKeys.clear();
    }
}

    requestPointerLock() {
        const canvas = this.game.getRenderer().getCanvas();
        if (canvas.requestPointerLock && !document.pointerLockElement) {
            this.retried = false;
            canvas.requestPointerLock({ unadjustedMovement: true });
        }
    }

    exitPointerLock() {
        if (document.exitPointerLock) {
            document.exitPointerLock();
        }
    }

    isPointerLocked() {
        return !!document.pointerLockElement;
    }

    resetMovement() {
        this.movementX = 0;
        this.movementY = 0;
    }
};

gdjs._MousePointerLockExtension = { handler: new PointerLockHandler(runtimeScene.getGame()) };

1 Like

Do you also need to lock the cursor again once the pause menu is closed?

Well yeah but that’s not that hard I just make it so when you click on a resume button you lock the mouse and make the pause menu disappear.

Is there a better way or something?

I’d say that’s the best way for now, until the extension is updated.

I was just checking so if other have this same issue and they come across this post then they know what needs to be done.

Thanks for sharing your solution, btw. It does help the GDevelop community.