Jump to content

Help with Phaser stealing keypress focus.


kgst
 Share

Recommended Posts

so I have the following code:

    wasd = {                up: game.input.keyboard.addKey(Phaser.Keyboard.W),                down: game.input.keyboard.addKey(Phaser.Keyboard.S),                left: game.input.keyboard.addKey(Phaser.Keyboard.A),                right: game.input.keyboard.addKey(Phaser.Keyboard.D),            };

Works great, the problem is when I try to type on an HTML input form outside of the game but on the same page, it won't let me type some of these letters into the box.

 

Often it's not all 4 letters, but almost always one or two stop working completely. This only starts once the game is actually run, and it's definitely that section of code that is the issue (changing them all to Keyboard.X will cause the X key to stop registering). All other letters work fine.

 

Anyway, just looking for some help, google has yielded nothing so far.

 

Link to comment
Share on other sites

"game.input.enabled = false" will absolutely stop Phaser from calling "preventDefault" on the Keyboard events, which is what stops them from propagating up to the browser. Phaser will still listen for the events, but won't act upon them.

 

You can see it here in the code:

 

https://github.com/photonstorm/phaser/blob/master/src/input/Keyboard.js#L345

Link to comment
Share on other sites

"game.input.enabled = false" will absolutely stop Phaser from calling "preventDefault" on the Keyboard events, which is what stops them from propagating up to the browser. Phaser will still listen for the events, but won't act upon them.

 

You can see it here in the code:

 

https://github.com/photonstorm/phaser/blob/master/src/input/Keyboard.js#L345

Thanks for your post, I did some more testing and I am able to stop Phaser from doing anything with WASD when "game.input.enabled = false", but it still won't let me type with those keys in another box.

 

After doing more experimentation it looks like just doing:
    wasd = {                up: game.input.keyboard.addKey(Phaser.Keyboard.W),                down: game.input.keyboard.addKey(Phaser.Keyboard.S),                left: game.input.keyboard.addKey(Phaser.Keyboard.A),                right: game.input.keyboard.addKey(Phaser.Keyboard.D),            };

alone causes this bug, even if I never use wasd in any way in my code.

changing the keys to different ones causes the same problem. 

Perhaps it's because I have another non-phaser event listener?

window.addEventListener("keypress", dealWithKeyboard, false);var isChatOpen = false;function dealWithKeyboard(e){            if(e.keyCode ==  13 && !isChatOpen){                // Disable keyboard                game.input.enabled = false;                isChatOpen = true;                var input = document.createElement("input");                input.type = "text";                input.id = "chatBox";                wrapper.appendChild(input);                input.focus();            }}

All of this works fine, except for that I can't press some of the WASD buttons.

Again, strongly appreciate any help!

Link to comment
Share on other sites

It's doing exactly what it's designed to. It's not a bug. Using addKey will automatically flag the key as being 'captured' and prevent it from going anywhere else in the browser. If it didn't then using cursor keys would scroll the page, space would jump whole pages down, etc.

 

You can use Keyboard.removeKeyCapture(keycode) to tell Phaser not to capture for a specific keycode. Do this after calling addKey.

 

But as I suggested before it would make much more sense to disable input entirely when the game doesn't have focus, and re-enable it when it does. Game.onBlur and Game.onFocus will do this.

Link to comment
Share on other sites

 

But as I suggested before it would make much more sense to disable input entirely when the game doesn't have focus, and re-enable it when it does. Game.onBlur and Game.onFocus will do this.

And like I said, even after doing:

"game.input.enabled = false"; 

 

which you say disables input entirely.

 

It still doesn't let me use the WASD keys, when the game is not in focus, and an external textbox is in focus. I can type as much as I want, and the game itself is not registering the WASD keys, but I still cannot use them to type on the unrelated, external textbox. I don't think this was intended.

I will try Keyboard.removeKeyCapture(keycode) and see if that works better.

 

There seems to be some confusion, so let me clarify the situation.

1. I can type with all letters into an external text box.

2. Game takes the WASD keys for movement.

3. Movement with the WASD keys works fine.

4. I use game.input.enabled = false.

5. The game stops moving the character with the WASD keys (this is perfect, as it should work. great!)

6. I can no longer type with all letters into the external text box.

 

game.input is stopped, but for some reason it will still not allow me to type into the external, not focused text box using the WASD keys. Even though my character is not moving, indicating that game.input.enabled = false is working.

 

Obviously there is some issue here.

Link to comment
Share on other sites

All of the below 3 options works fine for me. All I did was throw a <textarea> above the game <div>.

var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update });function preload() {    game.load.image('phaser', 'assets/sprites/phaser-dude.png');    game.load.image('logo', 'assets/sprites/phaser_tiny.png');    game.load.image('pineapple', 'assets/sprites/pineapple.png');}var key1;var key2;var key3;function create() {    game.stage.backgroundColor = '#736357';    game.add.text(0, 0, 'Press one, two or three !', {} );    //  Here we create 3 hotkeys, keys 1-3 and bind them all to their own functions    key1 = game.input.keyboard.addKey(Phaser.Keyboard.ONE);    key1.onDown.add(addPhaserDude, this);    key2 = game.input.keyboard.addKey(Phaser.Keyboard.TWO);    key2.onDown.add(addPhaserLogo, this);    key3 = game.input.keyboard.addKey(Phaser.Keyboard.THREE);    key3.onDown.add(addPineapple, this);    //  Option 1 - in the update loop you can disable all input if the pointer isn't over the game    //  (see update function)    //  Option 2 - Alternatively, Remove captures so they flood up to the browser too    game.input.keyboard.removeKeyCapture(Phaser.Keyboard.ONE);    game.input.keyboard.removeKeyCapture(Phaser.Keyboard.TWO);    game.input.keyboard.removeKeyCapture(Phaser.Keyboard.THREE);    //  Option 3 - If the game is an iframe, or chat is in another window, use Game.onBlur and Game.onFocus instead    // game.onBlur.add(...);    // game.onFocus.add(...);}function update() {    if (game.input.activePointer.withinGame)    {        game.input.enabled = true;        game.stage.backgroundColor = '#736357';    }    else    {        game.input.enabled = false;        game.stage.backgroundColor = '#731111';    }}function addPhaserDude () {    game.add.sprite(game.world.randomX, game.world.randomY, 'phaser');}function addPhaserLogo () {    game.add.sprite(game.world.randomX, game.world.randomY, 'logo');}function addPineapple () {    game.add.sprite(game.world.randomX, game.world.randomY, 'pineapple');}
Link to comment
Share on other sites

  • 2 years later...

I found this behavior rather odd. Why is Phaser messing with input events on elements outside the game canvas?

What I do is run a callback on each key press, check if an input or textarea is focused with jQuery:

    attackKey = game.input.keyboard.addKey(65);
 
    attackKey.onDown.add(function() {
        processKeyboardEvent(function() {
           // do something
        });
    });

function processKeyboardEvent(keyboardFunc) {

    var isTyping = $("input,textarea").is(":focus");

    if (isTyping) {
    game.input.enabled = false;
console.log('do not process event and turn off game input, because we are typing in an input or text box'); 
        return;
    }

    keyboardFunc();

}

 

Then turn input back on when the game canvas is clicked:

$('#game').on('click',function() { game.input.enabled = true }); 
 

Or you could use Game.onFocus like Richard suggested. 

EDIT: scratch this idea, it doesn't work because the first time you hit a key in the input element, event.preventDefault is called, so it won't type just the first key. Use game on blur/focus instead. 

 

Link to comment
Share on other sites

Okay tried this:

        game.onBlur.add(function() {

            game.input.enabled = false;

        });

        game.onFocus.add(function() {

            game.input.enabled = true;

        });

And phaser is still preventing input elements from being typed in with keys that are captured. Tried on both input elements and textarea elements. Tried on both windows and mach, using Phaser v. 2.6.2. 

I can confirm that the input is in fact turned off when typing the key (console.log(game.input.enabled)). so it looks like kgst was right - disabling the input manager isn't going to turn off the event delegation Phaser is preventing from HTML elements

Link to comment
Share on other sites

Problem solved. I think this thread was just old info. game.input.enabled won't control keyboard event delegation but game.input.keyboard will. This works:

   game.onBlur.add(function() {

                game.input.keyboard.enabled = false;

            });

            game.onFocus.add(function() {

                game.input.keyboard.enabled = true;

            });

 

Link to comment
Share on other sites

Never mind. That only works sometimes. I have no clue what is going on here. 

Sometimes I will type:

game.input.keyboard.enabled = false;

into the console and it works. Other times, I will need to type both:

game.input.keyboard.enabled = false;

game.input.enabled = false;

And it works. Other times, I type both and it doesn't work. 

 

I really have no clue. 

Link to comment
Share on other sites

okay I figured it out ... hopefully. onBlur and onFocus is triggering when it's not supposed to. Because the input element is overlayed on top of the canvas (z-indexed), it is being triggered whenever something is typed in and the input manager is turned back on. So in theory, turning off input should work just fine, just be careful you don't have your input element overlayed on top of the canvas (like it is with most UI). If that's the case you might need to figure out a different way to tell if the game is in focus/blur because game.onBlur is not reliable. 

Link to comment
Share on other sites

Using jquery mouseenter and mouseleave events seems to do the trick. It will turn input off if the mouse enters an element, even if that element is in front of the game canvas with z-indexing:


        $("#game").mouseenter(function() {
            game.input.enabled = true;
        });

        $("#game").mouseleave(function() {
            game.input.enabled = false;

        });

#game being the id of your game canvas HTML element. 

Hopefully this will help someone out who runs into the same problem. 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...