Jump to content

Gamepad justPressed not working


padpadpad
 Share

Recommended Posts

Hey there !

 

I've been playing around with gamepad related stuff in phaser and I've noticed a couple of issues.

 

First of all, the Phaser.Gamepad.pad1 ... pad4 are noted as type boolean in phaser/src/input/Gamepad.js when they should be of type Phaser.SinglePad, and Phaser.Gamepad.padsConnected should be of type number instead of boolean. This was corrected yesterday in the typescript definition file, but it's still unchanged in the jsdoc comments in "Gamepad.js"

 

Next, the justPressed() function doesn't work with Gamepads (or at least not as intended). As of right now, justPressed() always returns true as long as the button is pressed, regardless of duration.

 

All justPressed() functions end up calling Phaser.GamepadButton.justPressed(duration) : 

    /**    * Returns the "just pressed" state of this button. Just pressed is considered true if the button was pressed down within the duration given (default 250ms).    *     * @method Phaser.GamepadButton#justPressed    * @param {number} [duration=250] - The duration below which the button is considered as being just pressed.    * @return {boolean} True if the button is just pressed otherwise false.    */    justPressed: function (duration) {        if (typeof duration === "undefined") { duration = 250; }        return (this.isDown && this.duration < duration);    },

This code is correct. The reason why the function always returns true if the button is pressed is that this.duration is always 0.

 

Now, let's look at Phaser.GamepadButton.processButtonDown() : 

    processButtonDown: function (value) {        if (this.isDown)        {            this.duration = this.game.time.now - this.timeDown;            this.repeats++;        }        else        {            this.isDown = true;            this.isUp = false;            this.timeDown = this.game.time.now;            this.duration = 0;            this.repeats = 0;            this.value = value;            this.onDown.dispatch(this, value);        }    },

This, again, seems correct. On its first call (when the button has just been pressed), we go in the else block where this.duration is set to 0this.isDown is set to true and this.value is set to 1 (pressed). Then, on the next calls, this.isDown is true so the if block just updates this.duration and increments this.repeats

With the help of a debugger, it's easy to see that processButtonDown() is just called once when the button is pressed, which means that this.duration is never updated and stays at 0.

 

Phaser.GamepadButton.processButtonDown() is called by the Phaser.SinglePad class. Specifically, it's called by Phaser.SinglePad.processButtonDown() which is itself called by Phaser.SinglePad.pollStatus()

pollStatus: function () {        if (!this.connected || this.game.input.disabled || this.game.input.gamepad.disabled || (this._rawPad.timestamp && (this._rawPad.timestamp === this._prevTimestamp)))        {            return;        }        for (var i = 0; i < this._buttonsLen; i++)        {            var rawButtonVal = isNaN(this._rawPad.buttons[i]) ? this._rawPad.buttons[i].value : this._rawPad.buttons[i];            if (rawButtonVal !== this._buttons[i].value)            {                if (rawButtonVal === 1)                {                    this.processButtonDown(i, rawButtonVal);                }...

Here are our culprits :

 

Let's say the user presses a button on his game pad. pollStatus() is called. this._rawPad.timestamp is the timestamp of the button press, which is gonna be different than this._prevTimestamp. We enter the for loop. rawButtonVal for our button is 1 (pressed) this._buttons.value is 0 (as it was released before), so we enter the two if statements and processButtonDown() is called.

 

The user keeps pressing on the button. On the next pollStatus() call, there are two possibilities : 

 

If the user hasn't changed the gamepad state (i.e. not pushed / released a button and not touched the sticks / triggers), this._rawPad.timestamp is unchanged and will be equal to this._prevTimestamp. This means that we will enter the first if statement and pollStatus() will return without calling processButtonDown()

 

If the user has changed the gamepad state, we enter the for loop. For our button, rawButtonVal will be 1 (pressed), this._buttons.value will be 1 (remember that it was changed in the first processButtonDown() call), so we won't enter the first if statement of the for loop and processButtonDown() will never be called.

Link to comment
Share on other sites

  • 1 month later...
  • 2 months later...

Hello! 

 

I'm on v2.1.2 , and I don't seem to have much luck with this still. Whilst querying for pointer.justPressed(200) in the onInputUp of a sprite (querying the Phaser.Pointer passed into it by default) it always returns false. Any idea whether this is sitll not working for sprites (funnily enough, I set the same listeners and example up on a state, and that seemed to work fine), or whether I''m doing something wrong?

 

Here's a sample of it: 

 

 
    export class PieSlice extends Phaser.Sprite {
 
        constructor(game: Phaser.Game, x, y, key: string, levelId: number) {
            super(game, x, y, key);
        
            this.events.onInputDown.add(this.onInputDown);
            this.events.onInputUp.add(this.onInputUp);
        }
        
        onInputUp(slice: PieSlice, pointer: Phaser.Pointer, event: MouseEvent) {
            console.log(pointer.justPressed(2000));
        }
 
        onInputDown() {
            //console.log('down down down, into the ground');
        }
 
    }
 
 
PS- oops, many things on my mind and I didn't realise this thread was for gamepad rather than touch/mouse, so, if it doesn't apply at all, sorry for posting in the wrong place! 
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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