El juego que estoy creando no requiere ninguna física, sin embargo, puedes interactuar cuando pasas el cursor sobre el sprite o haces clic en él usando sprite.setInteractive({cursor: "pointer"}); , sprite.on('pointermove', function(activePointer) {...}); y similares Sin embargo, noté dos problemas con eso:
El sprite tiene algunas áreas que son transparentes. Las funciones interactivas aún se activarán al hacer clic en esas áreas transparentes, lo cual no es ideal.
Al reproducir una animación de sprite, el área interactiva no parece cambiar por completo (¿en absoluto?), por lo tanto, si el sprite termina en un cuadro más grande que el anterior, terminan siendo áreas pequeñas con las que no puedo interactuar.
Una opción que pensé fue crear un polígono sobre mi sprite, que cubre el área que quiero que sea interactiva. Sin embargo, antes de hacerlo, simplemente quería preguntar si hay formas más sencillas de solucionar estos problemas.
Estaba tratando de encontrar una respuesta para esto yo mismo hace un momento ...
Piensa que Make Pixel Perfect es lo que estás buscando.
this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());https://newdocs.phaser.io/docs/3.54.0/focus/Phaser.Input.InputPlugin-makePixelPerfect
Puede que esta no sea la mejor solución, pero yo resolvería este problema así. (Si no quiero usar la física, y si no afecta demasiado el rendimiento)
Verificaría en el controlador de eventos, si en la posición del mouse el píxel es transparente más o menos, esto es más exacto y menos trabajo que usar cuadros delimitadores.
Tendrías que hacer algunos cálculos menores, pero debería funcionar bien.
por cierto: si el origen no es
0, tendrías que compensar esto en los cálculos. (en este ejemplo , se implementa el desplazamiento de origen)
Aquí hay una demostración, para el evento de clic:
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>