Circle hit area is too small. Is it a rectangular hit-area within the circle?

In the following code the hit area seems to be much smaller than the rendered circle. What have I done wrong? Is the hit area a rectangle? How can I fix this?

spotLayers.forEach(spotLayer => {
    spotLayer.spotMarkers.forEach(spotMarker => {
                                           
        var spotcircle = this.add.circle(spotMarker.x * (width / maxWidth), spotMarker.y * (height / maxHeight), 60 * (width / maxWidth)); 
        graphics.fillCircleShape(spotcircle); // so I can see it
        spotMarker.gameObject = spotcircle;
                                        
        spotMarker.gameObject.setInteractive();
        spotMarker.gameObject.on('pointerdown', function (pointer) {
            console.log('pointer x ' + pointer.x + ' pointer y ' + pointer.y);                        
        }, this);
    });
});

Thanks!

.setInteractive uses a rectangle as default hit area. Use .setInteractive(shape, callback) instead, where shape is the circle shape you want and callback is Phaser.Geom.Circle.Contains

1 Like

Thanks @Stefan_Octavian,

I am really new to this and struggling with these objects - the below is wrong (‘pointerdown’ event is not wired up). Can you point me in the right direction please?

var spotcircle = new Phaser.Geom.Circle(spotMarker.x * (width / maxWidth), spotMarker.y * (height / maxHeight), 60 * (width / maxWidth));  
                                             
graphics.fillCircleShape(spotcircle);
spotMarker.gameObject = this.add.circle(spotcircle);
spotMarker.gameObject.setInteractive(spotcircle, Phaser.Geom.Circle.Contains);
spotMarker.gameObject.on('pointerdown', function (pointer) { ...}

Well, I am also a beginner but ran into the same problem and changing my setInteractive call worked in my case. I don’t see what’s the problem with the code. Maybe someone else could help. Try to provide a similar example in a codepen to reproduce your situation.

Try something like this:

var spotLayers = [];

spotLayers.forEach(spotLayer => {
  spotLayer.spotMarkers.forEach(spotMarker => {
    var spotcircle = this.add.circle(
      spotMarker.x * (width / maxWidth),
      spotMarker.y * (height / maxHeight),
      60 * (width / maxWidth),
      0xffff00, // fillColor
      0.5 // fillAlpha
    );

    spotcircle.setInteractive(
      new Phaser.Geom.Circle(
        0.5 * spotcircle.displayWidth, // center x
        0.5 * spotcircle.displayHeight, // center y
        spotcircle.radius // radius
      ),
      Phaser.Geom.Circle.Contains
    );

    console.log('hitArea', spotcircle.input.hitArea); // Geom.Circle

    // Makes a debug shape for the hit area (thin green stroke)
    // It should align with `spotcircle` texture (solid yellow)
    this.input.enableDebug(spotcircle);

    spotcircle.on(
      'pointerdown',
      function (pointer) {
        console.log('pointer x ' + pointer.x + ' pointer y ' + pointer.y);
      },
      this
    );

    spotMarker.gameObject = spotcircle;
  });
});

Thank you so much! I am still not entirely clear why my code did not work (I tried a lot of variants), but will study your solution and revisit the docs. x1000 thanks

1 Like