Issue with Character Movement When Losing Window Focus – "Key Sticking"

Hello everyone,

I’m developing a new game and have encountered an issue with character movement. If a player holds down a movement key and then clicks the mouse outside the game window, the character continues moving even after the key is released. When I return to the game window, the character starts moving again but does not respond to key presses. It only stops after pressing the same key again.

I ran diagnostics through the console and found that GDevelop does not register that the key is no longer pressed when the window loses focus. After returning to the game, the engine still thinks the key is being held down.

If anyone has examples of a solution to this issue or JavaScript code that could help, I would greatly appreciate any assistance or advice!

Using variables is not a suitable solution. The game has top-down movement, and certain key combinations conflict with each other—for example, when pressing W and then WD.

Thank you!

I found a solution. The problem will be solved if you insert these two pieces of code.

Puts the scene on pause when the focus is lost.

// Get the TimeManager object through runtimeScene
var timeManager = runtimeScene.getTimeManager();  // It's important to ensure this is the correct time management object

// On window focus:
window.addEventListener('focus', function (event) {
    // Restore normal time speed
    timeManager.setTimeScale(1);  // Restores normal speed
    console.log('Time scale set to 1 (focus)');  // Output message for debugging
});

// On window blur:
window.addEventListener('blur', function (event) {
    // Stop the game (set time scale to 0)
    timeManager.setTimeScale(0);  // Freezes the game
    console.log('Time scale set to 0 (blur)');  // Output message for debugging
});

Resets all buttons when the game window gains focus.

// Function to clear all properties of an object
function clearObjectProperties(obj) {
  for (let prop in obj) {
    if (obj.hasOwnProperty(prop)) {
      delete obj[prop];
    }
  }
}

// Function that clears keyboard states
function clearKeyboardStates() {
  const inputManager = runtimeScene.getGame().getInputManager();

  // Clear _pressedKeys (pressed keys)
  if (inputManager._pressedKeys && typeof inputManager._pressedKeys.clear === "function") {
    inputManager._pressedKeys.clear();
  } else if (inputManager._pressedKeys) {
    clearObjectProperties(inputManager._pressedKeys);
  }

  // Clear _releasedKeys (released keys)
  if (inputManager._releasedKeys && typeof inputManager._releasedKeys.clear === "function") {
    inputManager._releasedKeys.clear();
  } else if (inputManager._releasedKeys) {
    clearObjectProperties(inputManager._releasedKeys);
  }
  
  console.log("Keyboard states cleared (blur).");
}

// Add a permanent blur event handler
window.addEventListener('blur', function (event) {
  clearKeyboardStates();
});
1 Like

Where exacttly do I put this code?

Edit:
Do I go
Event sheet > Add> Javascript code

Do I have to put it on every scene?
Do I have to do two different javascript blocks for the two different blocks of code you gave?

Is this image right?

Yes, you did everything correctly. I also added a condition for it to trigger once, but I’m not sure if it’s necessary.
And yes, the code needs to be added to all scenes.

Ok thanks a bunch. it seems like it might work
However, I actually use ‘Tab’ for my games inventory. now it seems i cant press Tab anymore. does this script make the ‘Tab’ key unusable?

i asked chatgpt to fix the second block, so I can still press tab key in game. it gave me this

// Function to clear all properties of an object, except for the tab key
function clearObjectProperties(obj) {
  for (let prop in obj) {
    if (obj.hasOwnProperty(prop) && prop !== "9") { // Skip the tab key (keyCode 9)
      delete obj[prop];
    }
  }
}

// Function that clears keyboard states
function clearKeyboardStates() {
  const inputManager = runtimeScene.getGame().getInputManager();

  // Clear _pressedKeys (pressed keys), but skip the tab key
  if (inputManager._pressedKeys && typeof inputManager._pressedKeys.clear === "function") {
    inputManager._pressedKeys.clear();
  } else if (inputManager._pressedKeys) {
    clearObjectProperties(inputManager._pressedKeys);
  }

  // Clear _releasedKeys (released keys), but skip the tab key
  if (inputManager._releasedKeys && typeof inputManager._releasedKeys.clear === "function") {
    inputManager._releasedKeys.clear();
  } else if (inputManager._releasedKeys) {
    clearObjectProperties(inputManager._releasedKeys);
  }

  console.log("Keyboard states cleared (blur).");
}

// Add a permanent blur event handler
window.addEventListener('blur', function (event) {
  clearKeyboardStates();
});

// Capture the tab key to prevent its default behavior (switching focus)
window.addEventListener('keydown', function(event) {
  if (event.key === "Tab") {
    event.preventDefault();  // Prevent the default tab behavior (focus switch)
    console.log("Tab key pressed");
  }
});

window.addEventListener('keyup', function(event) {
  if (event.key === "Tab") {
    // Handle tab release if necessary
    console.log("Tab key released");
  }
});

I can press tab in game now. I think it still fixes the problem, I will need to test.