Periodically call while pointerdown

Hello, is it anyhow possible to periodically call a function while pointerdown?
I am currently moving the camera on pointerdown and therefore while pointer is down the world position of the pointer moves but it is not updating when calling periodically game.input.activePointer.worldX

What I got (where move is just moving the camera):

this.on("pointerdown", (event: Phaser.Input.Pointer) => {
	move(event); // call every 500ms while pointerdown
	this.on("pointermove", move);
});
this.on("pointerup", () => this.off("pointermove", move));

Hi,
Perhaps something like this…not tested

this.isMoving = false;

this.on("pointerdown", (event: Phaser.Input.Pointer) => {
	this.time.addEvent({
          delay: 500,
          callback: () => {
            if (!this.isMoving) {
              this.isMoving = true;
              move(event)
            }
          }
        });
	this.on("pointermove", move);
});



move(event) {
  // move camera code
  this.isMoving = false;
}

1 Like

Calling it periodically works but the problem is that the event is still the old and the new pointerposition in world coordinates does not updates.

Ok, add this listener to get the pointer x, y position(not sure about event.World, add a console.log to detect the good value) and use MoveX as current pointer position

this.input.on('pointermove',  (event) => {
  this.moveX = event.WorldX;
  this.moveY = event.WorldY;
});

The moving from pointerdown and pointermove works fine, but when button is pressed (pointerdown) then it only fires one event and stops (pointermove and up works).
What I want:

  1. pointerdown started => move
  2. after 500ms pointer is still not up => move
  3. goto 2.
    Maybe I have to emit manually more pointerdown events which are coded every 500ms?
    The problem is I dont know how to get the updated Phaser.Input.Pointer

perhaps this example can help you

Add https://cdn.jsdelivr.net/npm/phaser@3.22.0/dist/phaser.js to Settings JS

It seems it only use this to move the camera

this.input.on('pointermove', function (p) {
    if (!p.isDown) return;

    cam.scrollX -= (p.x - p.prevPosition.x) / cam.zoom;
    cam.scrollY -= (p.y - p.prevPosition.y) / cam.zoom;
  });
}
1 Like

It looks interesting, solves another “problem” so I don’t have to on and off pointermove and just check if pointer is down.
Unfortunately it doesn’t solve the pointerdown problem.

If the camera have the position (0, 0) and I press the pointer (on world position (50, 50)) then the camera position is set to (50, 50) but the pointer is now at (100, 100), pressing it again would work, camera (100, 100) … pointer (150, 150).
What I want to achieve now is making this with only one pointerdown event and while it is down it updates the camera with the actual pointer world positions.

Maybe just to explain a little bit more I am moving the camera from start to end with elapsedTime so therefore adding every 500ms the (50, 50) does not work and I need the actual world position from the pointer.

Ok, got it
Perhaps in the update loop:

update(time, delta) {
  this.moveX = this.input.pointer.WorldX; // or something similar
  this.moveY = this.input.pointer.WorldY;
}

When pointerdown is fired the pointer itself is not updated so therefore while it is pressed and not moved this.input.pointer will be the same.
I think it is not possible with pointer events itself to solve the problem.
Probably have to make it a little bit hacky something like that:

this.on("pointerdown", (event) => {
    const startX = camera.x;
    const startY = camera.y;
    move(event);
    const doEvery500Ms = () => {
        const elapsedX = event.worldX - startX;
        const elapsedY = event.worldY - startY;
        event.worldX += elapsedX;
        event.worldY += elapsedY;
        ...update startx and y with actual camera pos
        move(event);
    };
})

Thank you for your help!

that’s why i suggested you to use the update loop to always get the pointer world position up to date, and so you can use this.moveX and this.moveY in your ‘pointerdown’ eventListener

create() {
this.moveX = 0;
this.moveY = 0;

this.on("pointerdown", (event) => {
    const startX = camera.x;
    const startY = camera.y;
    move(event);
    const doEvery500Ms = () => {
        const elapsedX = this.moveX - startX;
        const elapsedY = this.moveY - startY;
        event.worldX += elapsedX;
        event.worldY += elapsedY;
        ...update startx and y with actual camera pos
        move(event);
    };
})
}


update(time, delta) {
  this.moveX = this.input.activePointer.worldX; // or something similar
  this.moveY = this.input.activePointer.worldY;
}

The pointer is not updated on the update loop, it looks that it works like this:
pointerdown -> update pointer
move camera -> but pointer on next update will be still the same
only after pointerup the pointer gets the new position

I don’t think

But it’s not this.input.pointer but instead this.input.activePointer
I edited my last example

Codepen - custom example
Not exactly how I wanted it to make but it should be clearly demonstrate that if you press the button then the camera position will be updated but the world is only updated after you make another pointer event.

Based on your codepen

document.getElementById('version')
  .textContent = 'Phaser v' + Phaser.VERSION;
var config = {
    type: Phaser.AUTO,
    parent: 'phaser-example',
    width: 800,
    height: 600,
    disableContextMenu: true,
    scene: {
        create: create,
        update: update
    }
};

var text

var isMoving = false;

var game = new Phaser.Game(config);

function create ()
{
  
    this.scene.add("d", new Phaser.Scene());
    text = this.add.text(10, 10, 'Move the mouse', { font: '16px Courier', fill: '#00ff00' });
  
    //this.scene.scene.input.on("pointerdown", (event) => {moveCamera(this.scene)})
}

function update ()
{
    var pointer = this.input.activePointer;
  if(pointer.isDown && !isMoving) {
    moveCamera(this.scene)
  }
    text.setText([
        'cameraX : ' + this.scene.scene.cameras.main.x,
        'cameraY : ' + this.scene.scene.cameras.main.y,
        'worldX: ' + pointer.worldX,
        'worldY: ' + pointer.worldY,
    ]);
}

function moveCamera(scene) {
  isMoving = true;
  scene.scene.time.addEvent({
    delay: 500,
    callback: () => {
      console.log(isMoving) 
      if (!scene.scene.isMoving) {
        console.log('move')
        
        scene.scene.cameras.main.scrollX += scene.scene.cameras.main.scrollX - scene.scene.input.activePointer.x;
        isMoving = false;
      }
    }
  });
}

That would be again the problem where you just add the position based on the first button click. (camera.x - worldX)

yea just check for pointerdown / up and set a flag according to that, then in the main loop … (update ?) put a conditional on the flag