Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

306
Vistas
Phaser 3: Change "Hitbox"/Interactive area of sprite without physics

The game I'm creating doesn't require any physics, however you are able to interact when hovering over/clicking on the sprite by using sprite.setInteractive({cursor: "pointer"});, sprite.on('pointermove', function(activePointer) {...}); and similar. However I noticed two issues with that:

  1. The sprite has some area which are transparent. The interactive functions will still trigger when clicking on those transparent areas, which is unideal.

  2. When playing a sprite animation, the interactive area doesn't seem to entirely (at all?) change, thus if the sprite ends on a frame bigger than the previous, there end up being small areas I can't interact with.

One option I thought of was to create a polygon over my sprite, which covers the area I want to be interactive. However before I do that, I simply wanted to ask if there are simpler ways to fix these issues.

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Was trying to find an answer for this myself just now..

Think Make Pixel Perfect is what you're looking for.

this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());

https://newdocs.phaser.io/docs/3.54.0/focus/Phaser.Input.InputPlugin-makePixelPerfect

about 4 years ago · Juan Pablo Isaza Denunciar

0

This might not be the best solution, but I would solve this problem like this. (If I don't want to use physics, and if it doesn't impact the performance too much)

I would check in the event-handler, if at the mouse-position the pixel is transparent or so, this is more exact and less work, than using bounding-boxes.

You would have to do some minor calculations, but it should work well.

btw.: if the origin is not 0, you would would have to compensate in the calculations for this. (in this example, the origin offset is implemented)

Here is a demo, for the click event:

let Scene = {
    preload ()
    {
        this.load.spritesheet('brawler', 'https://labs.phaser.io/assets/animations/brawler48x48.png', { frameWidth: 48, frameHeight: 48 });
    },
    create ()
    {
        // Animation set
        this.anims.create({
            key: 'walk',
            frames: this.anims.generateFrameNumbers('brawler', { frames: [ 0, 1, 2, 3 ] }),
            frameRate: 8,
            repeat: -1
        });
        
        // create sprite
        const cody = this.add.sprite(200, 100).setOrigin(0);
        cody.play('walk');
        cody.setInteractive();
        
        // just info text
        this.mytext =  this.add.text(10, 10, 'Click the Sprite, or close to it ...', { fontFamily: 'Arial' });

        // event to watch
        cody.on('pointerdown', function (pointer) {
            // calculate x,y position of the sprite to check
            let x = (pointer.x - cody.x) / (cody.displayWidth / cody.width)
            let y = (pointer.y - cody.y) / (cody.displayHeight / cody.height);
            
            // just checking if the properties are set
            if(cody.anims && cody.anims.currentFrame){
                let currentFrame = cody.anims.currentFrame;
                let pixelColor = this.textures.getPixel(x, y, currentFrame.textureKey, currentFrame.textureFrame);

                // alpha > 0 a visible pixel of the sprite, is clicked 
                if(pixelColor.a > 0) {
                    this.mytext.text = 'Hit';
                } else {
                    this.mytext.text = 'No Hit';
                }
                
                // just reset the textmessage
                setTimeout(_ => this.mytext.text = 'Click the Sprite, or close to it ...' , 1000);
            }
        }, this);
    }
};

const config = {
    type: Phaser.AUTO,
    width: 400,
    height: 200,
    scene: Scene
};

const game = new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser@3.55.2/dist/phaser.js"></script>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda