Polygon hit area seems to be off

I have created a minimal example to reproduce:

var config = {
    type: Phaser.AUTO,
    width: 400,
    height: 200,
    scene: {
        preload: preload,
        create: create,
        update: update
    }
};

var game = new Phaser.Game(config);
var textBox;

function preload() {
}

function create() {
    textBox = this.add.text(200, 0, "text", {fill: "white"});

    drawBox(this, [ 0,0, 99,0, 99,99, 0,99 ], 0xFF0000, 'red');
    drawBox(this, [ 100,0, 199,0, 199,99, 100,99 ], 0x00FF00, 'green');
}

function drawBox(scene, points, color, msg) {
    var polygon = scene.add.polygon(0, 0, points, color).setOrigin(0, 0);
    polygon.setInteractive();
    polygon.addListener(Phaser.Input.Events.GAMEOBJECT_POINTER_DOWN, function() {
        textBox.setText(msg);
    });
}


function update() {
}

18

When the green rectangle is hit, nothing happens; when the red rectangle is hit, the text turns green. Is this behaviour expected? If so, why? Or did I found a bug?

And on a side note: why is there a gap between the red and the green rectangle?

Tested with Phaser 3.16.2

1 Like

I think this is probably what you want:

function create() {
    textBox = this.add.text(200, 0, "text", {fill: "white"});

    drawBox(this,   0, 0, [ 0,0, 99,0, 99,99, 0,99 ], 0xFF0000, 'red');
    drawBox(this, 100, 0, [ 0,0, 99,0, 99,99, 0,99 ], 0x00FF00, 'green');
}

function drawBox(scene, x, y, points, color, msg) {
    var polygon = scene.add.polygon(x, y, points, color).setOrigin(0, 0);
    polygon.setInteractive();
    console.log('position', polygon.x, polygon.y);
    console.log('hitArea', polygon.input.hitArea);
    polygon.addListener(Phaser.Input.Events.GAMEOBJECT_POINTER_DOWN, function() {
        textBox.setText(msg);
    });
}

The hit area is rectangular unless you pass a different Geom to setInteractive().

The gap is the difference between the right (99) and left (100) edges, I think.

Nope, unfortunately this is not what I want. I already feared somebody might simply want to fix my minimal example. In my actual game the polygons are a lot more complicated: they are generated from geo spatial data and look like, well, how country borders look like: garbled lines. The points are oriented to 0,0. I fear it would be very complicated, if at all possible, to shift them and choose a different position.

The answer also does not address the question, whether this is expected behaviour or a bug.

That is interesting. I expected the hit area to be defined by the polygon.

In a discrete environment (pixel in this case) there is nothing between 99 and 100. I would therefore expect there to be no gap.

I did just port my code from Phaser CE to Phaser 3. In Phaser CE the polygon hit area worked exactly as expected. This is my minimal example ported to Phaser CE (2.10.5) with the expected behaviour:

var config = {
    renderer: Phaser.AUTO,
    width: 400,
    height: 200,
    state: {
        preload: preload,
        create: create,
        update: update
    }
};

var game = new Phaser.Game(config);
var textBox;

function preload() {
}

function create() {
    textBox = game.add.text(200, 0, "text", {fill: "white"});

    drawBox([ 0,0, 99,0, 99,99, 0,99 ], 0xFF0000, 'red');
    drawBox([ 100,0, 199,0, 199,99, 100,99 ], 0x00FF00, 'green');
}

function drawBox(points, color, msg) {
    var polygon = game.add.graphics(0, 0);
    polygon.beginFill(color);
    polygon.drawPolygon(points);
    polygon.endFill();
    polygon.inputEnabled = true;
    polygon.events.onInputDown.add(function() {
        textBox.setText(msg);
    });
}

function update() {
}

In Phaser CE the hit area was defined by the polygon. Why has that changed in Phaser 3?

1 Like

When you pass no hitArea to setInteractive() it makes a rectangular hit area based on the game object’s intrinsic width and height , if possible. That’s expected.

The width and height of a Polygon game object are the width and height of the rectangle enclosing it. That’s expected.

In that example the green polygon has position (0, 0) and hit area

{ x: 0, y: 0, width: 99, height: 99 }

which maps to the same position on the game canvas.

1 Like

Thank you for your explanation. Got it working now. Found the solution in the sample you posted:

polygon.setInteractive(new Phaser.Geom.Polygon(points), Phaser.Geom.Polygon.Contains);