VirtualJoystick: release programmatically

On mobile, I’m pausing the game when the app becomes inactive, e.g when the user swipes from the edge, triggering the task switcher. The problem is, I can’t “release” the joystick programmatically. This means the character resumes walking after unpausing, even though the joystick is not pressed.

The easiest way to release the joystick seems to be to send a pointerup event to its canvas, but it requires a valid pointerId property. I wrote this disgusting hack as proof-of-concept:

class MyController {
  constructor() {
    this.leftPad = new VirtualJoystick(...)
  }

  pause() {
    // Release the joystick. This requires sending a 'touchup' event, _with a valid pointerId_.
    // There should be a method on `VirtualJoystick` to allow this.
    let touches = (<any>this.leftPad)._touches as StringDictionary<{ x: number; y: number; prevX: number; prevY: number } | PointerEvent>
    touches.forEach((key, value) => {
      console.log(key, value)
      VirtualJoystick.Canvas!.dispatchEvent(new PointerEvent('pointerup', <any>{pointerId: key}))
    })
  }
}

I wanted to get some feedback before spending time making a PR.

Hello @alekop
Could you explain in more detail if it’s possible to handle or attach a listener to the pressed property, and by controlling it, how pressed behaves? Does it remain true even if you swipe the task manager and release screen?

When I got into touch-screen controls, I tried to improve this class a bit, though I haven’t dared to modify the framework itself or submit any pull requests yet. I don’t have enough experience for pull requests either. I created my own TouchStick class, inheriting from the main VirtualJoystick, and I’m using that.

You can try to add in constructor call this.setupListeners()

  private setupListeners(): void {
    this.scene.registerBeforeRender(() => {
      if (this.leftPad) this.handleLeftPad(this.leftPad)
    })
  }

and create

 private handleLeftPad(pad: VirtualJoystick) {
    const { pressed } = pad

    if (pressed) {
      this.playerMovement(pad)
    }
  }