rexrainbow / phaser3-rex-notes

Notes of phaser3 engine
MIT License
1.18k stars 259 forks source link

Gestures: target specific game objects #418

Open lagouyn opened 3 months ago

lagouyn commented 3 months ago

Regarding gestures (particulars for mobile device support), I’d like to be able to specify a particular game object to receive certain kinds of gesture events, and to have other game objects ignore those gesture events.

For example, in my game I have a map that can have game objects on it. I would like to be able to have gestures work only when the gesture is on the map … I want the other game objects to ignore those gestures (I do want these other kinds of game objects to respond to “regular” events, like pointer down/up, drag, etc).

So, for example, I’d like to be able to scroll/zoom the camera only when the gesture is directly on the map itself.

I’ve read through your docs and tried some of your examples, but I haven’t figured out a way to target specific game objects for certain gesture events.

Could you advise?

rexrainbow commented 3 months ago

I assume that you are using pinch to detect camera zoom/scrolling. 1st parameter of creating pinch instance can be a game object.

var pan = scene.rexGestures.add.pinch(gameObject, {
    // enable: true,
    // bounds: undefined,

    // threshold: 0,
});

Or, you can add extra testing condition under 'pinch' event, it is the main logic of doing camera zoom from pinch-input.

lagouyn commented 3 months ago

Two questions:

1)

You mention testing a condition inside the pinch event handler … I don’t see the event handler getting passed the game object that was the target of the pinch. Is there a way to check which game object was pinched?

2)

Below I have pasted some code in which the red circle (which is behind the blue circle) is set configured to receive pinch events. What I notice is that when I pinch over the intersection of the blue and red circles, the pinch passes through the blue circle and red’s pinch event handler gets called. Is there a way to prevent that behavior? I only want the red circle to get a pinch event if the pinch was directly on it.

Thank you.

'use strict'

class Demo extends Phaser.Scene { constructor() { super({ key: 'examples' }) }

preload() {
    const url = 'https://raw.githubusercontent.com/rexrainbow/phaser3-rex-notes/master/dist/rexpinchplugin.min.js';
    this.load.plugin('rexpinchplugin', url, true);
}

create() {

    const redCircle = this.add.circle(
        150, 150, // x, y
        300, // r
        0xff0000,
        0.5 // alpha
    );

    const blueCircle = this.add.circle(
        300, 300, // x, y
        300, // r
        0x0000ff,
        0.5 // alpha
    );

    var dragScale = this.plugins.get('rexpinchplugin').add(redCircle);

    var camera = this.cameras.main;

    dragScale
        .on('drag1', function (dragScale) {
            var drag1Vector = dragScale.drag1Vector;
            camera.scrollX -= drag1Vector.x / camera.zoom;
            camera.scrollY -= drag1Vector.y / camera.zoom;
        })
        .on('pinch', function (dragScale) {
            var scaleFactor = dragScale.scaleFactor;
            camera.zoom *= scaleFactor;
        }, this)
}

}

var config = { type: Phaser.AUTO, parent: 'phaser-example', width: 800, height: 600, scene: Demo, };

var game = new Phaser.Game(config);

rexrainbow commented 3 months ago
  1. No game object will be picked by input manager, user has to check if pointer (pinch.pointers[0], or pinch.pointers[1]) is inside a game object or not manually.

  2. Only redCircle has registered touch detecting, blueCircle has not. Thus blueCircle will be ignored by input manager, no built-in solution to prevent this case, unless blueCircle has called blueCircle.setInteractive().

rexrainbow commented 3 months ago

I add 2 new methods pinch.isPointer0InGameObject(gameObject), pinch.isPointer1InGameObject(gameObject) at latest commit. Use them under 'pinch', or 'drag1' event, to detect if pointer is inside another gameObject's rectangle bounds or not, to solve case1 and case2 of previous post.