Phaser 3

Pixel perfect hittest with phaser 3 without physics

Performing pixel-perfect hit testing without using the built-in physics engine in Phaser 3 requires comparing the pixel data of two sprites. Below, I’ll outline a basic approach to achieve pixel-perfect hit testing between two sprites in Phaser 3 without using the physics engine:

import Phaser from 'phaser';

const config = {
  type: Phaser.AUTO,
  width: 800,
  height: 600,
  scene: {
    preload: preload,
    create: create,
    update: update,
  },
};

const game = new Phaser.Game(config);

let sprite1;
let sprite2;

function preload() {
  this.load.image('sprite1', 'path_to_sprite1.png');
  this.load.image('sprite2', 'path_to_sprite2.png');
}

function create() {
  sprite1 = this.add.sprite(200, 300, 'sprite1');
  sprite2 = this.add.sprite(600, 300, 'sprite2');
}

function update() {
  if (checkPixelPerfectCollision(sprite1, sprite2)) {
    // Handle collision
    sprite1.setTint(0xff0000);
    sprite2.setTint(0xff0000);
  } else {
    sprite1.clearTint();
    sprite2.clearTint();
  }
}

function checkPixelPerfectCollision(spriteA, spriteB) {
  const boundsA = spriteA.getBounds();
  const boundsB = spriteB.getBounds();

  const intersection = Phaser.Geom.Intersects.RectangleToRectangle(boundsA, boundsB);

  if (!intersection) {
    return false;
  }

  const x1 = Math.floor(intersection.x - boundsA.x);
  const y1 = Math.floor(intersection.y - boundsA.y);
  const x2 = Math.floor(intersection.x - boundsB.x);
  const y2 = Math.floor(intersection.y - boundsB.y);

  const textureA = spriteA.texture.getSourceImage();
  const textureB = spriteB.texture.getSourceImage();

  const dataA = textureA.getContext('2d').getImageData(x1, y1, intersection.width, intersection.height).data;
  const dataB = textureB.getContext('2d').getImageData(x2, y2, intersection.width, intersection.height).data;

  for (let i = 0; i < dataA.length; i += 4) {
    if (dataA[i + 3] > 0 && dataB[i + 3] > 0) {
      return true;
    }
  }

  return false;
}

You can use below code for quick test of PixelPerfectHitTesting

export function pixelPerfectHitTest(object1, image) {
    var p = getTipPoint(object1);
    if (p.x > image.x && p.y > image.y && p.x < image.x + image.width && p.y < image.y + image.height) {
        var m = image.texture.manager;
        var alpha = m.getPixelAlpha(p.x - image.x, p.y - image.y, image.texture.key);
        if (alpha > 200) {
            return true;
        } else {
            return false;
        }
    }
}

Another example below

var config = {
    type: Phaser.AUTO,
    width: 800,
    height: 600,
    scene: {
        preload: preload,
        create: create
    }
};

var game = new Phaser.Game(config);

function preload() {
    // Load images here
}

function create() {
    // Create game objects
    var player = this.add.rectangle(100, 100, 50, 50, 0xff0000);
    var obstacle = this.add.rectangle(300, 300, 80, 80, 0x00ff00);
    
    // Enable input events for the player
    player.setInteractive();

    // Add a pointerdown event to the player
    player.on('pointerdown', function() {
        if (Phaser.Geom.Intersects.RectangleToRectangle(player.getBounds(), obstacle.getBounds())) {
            console.log('Collision detected!');
        }
    });
}

In this example, we create two rectangles: player and obstacle. The player rectangle is interactive and has a pointerdown event attached to it. When the player rectangle is clicked or tapped, the collision between the player and the obstacle is checked using the Phaser.Geom.Intersects.RectangleToRectangle function. If a collision is detected, a message is logged to the console.

Keep in mind that this is a basic example and can be expanded to handle more complex collision scenarios with different shapes and objects. Phaser provides various geometry and collision functions that you can use to check for collisions between different types of game objects. Make sure to consult the Phaser 3 documentation for more information on available methods and properties.

Leave a Reply

Your email address will not be published. Required fields are marked *.

*
*
You may use these <abbr title="HyperText Markup Language">HTML</abbr> tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>