How can I detect the collisions of multiple children from different groups?
similar
Imagine something like this, but with square hitboxes the pink object is from one group, the red object from another, and the orange objects from another group
(also, this exact order/position is not necessary, but as long as each orange object is touching two bigger objects and they are near each other)
how can I get an collision like this in arcade physics? (matter.js solutions still work if its not possible in arcade, but arcade is preferred)
EDIT, all hitboxes are square
Update: I misunderstud your question
In Arcade Physics this is not really possible you could work around it setting the hitbox to circles ( checkout this example). It would not fix prefect, but could be a easy solution if it doesn't have to be perfect. If you need exact hitboxes, you need matterjs (or create your own physics-engine).
Well I think it is difficult to achevie this with arcade physics, since each impact will push the object away and this will push the other touching away, so rarely all 6 will be touching.
That said depending on you usecase, you could iterate through all gameobject and check if it matches your desired pattern. Depending on how many gameObjects it might cause performance issues.
Basically your have to programm the matching yourself
Small Demo, for three Object:
(the objects have to overlap for this demo to work)
UPDATE CODE for complex model
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: { gravity: { y: 0 } }
},
scene: { create }
};
function create() {
this.add.text(10, 10, 'Target ')
.setScale(1.5)
.setOrigin(0)
.setStyle({ fontStyle: 'bold', fontFamily: 'Arial' });
this.add.text(180, 10, 'Build yourself')
.setScale(1.5)
.setOrigin(0)
.setStyle({ fontStyle: 'bold', fontFamily: 'Arial' });
this.result = this.add.text(400, 10, 'No Match')
.setScale(1.5)
.setColor('#ff0000')
.setOrigin(0)
.setStyle({ fontStyle: 'bold', fontFamily: 'Arial' });
let graphics = this.make.graphics();
graphics.fillStyle(0xffffff);
graphics.fillRect(0, 0, 20, 20);
graphics.generateTexture('big', 20, 20);
graphics.fillStyle(0xff0000);
graphics.fillRect(0, 0, 10, 10);
graphics.generateTexture('small', 10, 10);
// DEMO
let demoTop = this.add.image(60, 60, 'big');
let demoMid = this.add.image(60, 60, 'small').setDepth(10);
let demoBottom = this.add.image(60, 60, 'big');
Phaser.Display.Align.To.RightCenter(demoMid, demoTop, -2, 0);
Phaser.Display.Align.To.RightCenter(demoBottom, demoMid, -2, 0);
this.add.image(75, 85, 'big');
this.add.image(66, 72, 'small').setDepth(10);
this.add.image(83, 72, 'small').setDepth(10);
this.add.line(150, 0, 0, 0, 0, config.height, 0xffffff).setOrigin(0);
this.big = this.physics.add.group({
key: "big",
repeat: 2,
setXY: { x: 240, y: 65, stepX: 26 },
});
this.small = this.physics.add.group({
key: "small",
repeat: 2,
setXY: { x: 290, y: 65, stepY: 32 },
});
this.big.children.iterate(function (child) {
child.setInteractive({ draggable: true });
child.on('pointerdown', () => {
this.selectedGameObject = child;
});
}, this); // <-- don't forget to pass the context
this.small.children.iterate(function (child) {
child.setInteractive({ draggable: true });
child.on('pointerdown', () => {
this.selectedGameObject = child;
});
}, this); // <-- don't forget to pass the context
this.input.on('drag', pointer => {
if (this.selectedGameObject) {
this.selectedGameObject.setPosition(pointer.x, pointer.y);
}
});
this.input.on('dragend', pointer => {
if (this.selectedGameObject) {
this.selectedGameObject.setPosition(pointer.x, pointer.y);
this.selectedGameObject = null
}
})
this.physics.add.overlap([this.small, this.big], [this.small, this.big], (p1, p2) => {
// Target is BIG - SMALL - BIG
this.result.setText('No Match').setColor('#ff0000');
if (p1.texture.key == 'big') {
if (p2.texture.key == 'small') {
this.big.children.iterate(function (p3) {
if (p3 != p1 && this.physics.overlap(p2, p3)) {
this.small.children.iterate(
function (p4) {
if (p4 != p2 && this.physics.overlap(p3, p4)) {
this.big.children.iterate(function (p5) {
if([p1,p3].indexOf(p5) == -1 && this.physics.overlap(p4, p5)){
this.small.children.iterate(
function (p6) {
if([p2,p4].indexOf(p6) == -1 &&
this.physics.overlap(p5, p6) &&
this.physics.overlap(p6, p1)
){
this.result.setText('Match').setColor('#00ff00');
}
}, this);
}
}, this);
}
}, this);
}
}, this);
}
}
});
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser/dist/phaser.min.js"></script>
If you opt for matterjs, I recommend checking out this example for matterjs, it is straight forward, but how it is done depnece on your specific usecase.