This is a slight tweak and more favorable version of the code using elements (Node
, NodeList
) in hypeDocument.queryIntersections
rather than a selector string. This allows to pass in arbitrary lists rather than only a selector. Selectors can still be used but now reside in your game logic.
/**
* Query intersections between elements using Matter.js
*
* @param {Node} sourceElm The source element used in each check
* @param {Nodelist} targetElms The target elements to query against
* @return {Nodelist} Returns a list of targetElms that intersect with sourceElm
*/
hypeDocument.queryIntersections = function(sourceElm, targetElms) {
var sourceBody = hypeDocument.getElementProperty(sourceElm, 'physics-body');
if (sourceBody) {
var targetBodies = [];
targetElms.forEach(function(elm){
var elmBody = hypeDocument.getElementProperty(elm, 'physics-body');
if (elmBody) {
targetBodies.push(elmBody);
} else {
console.log('target '+elm.id+' must have static Physics enabled');
}
});
var collisions = Matter.Query.collides(sourceBody, targetBodies);
if (collisions.length) {
return collisions.map(function(collision){
var isB = sourceElm.id == collision.bodyB.elementId;
return document.getElementById((isB? collision.bodyA : collision.bodyB).elementId);
});
}
} else {
console.log('sourceElm must have static Physics enabled');
}
return [];
}
Corresponding file:
drag_intersection_matter_elements.hype.zip (28,6 KB)
About using physics and intersection detection at once
So, there is an elephant in the room. What about using this approach when one is already using the physics engine for something else and the static elements needed for intersection detection are interacting with the game in unwanted ways. There is a simple solution called a collisionFilter
in Matter.js and it can be used to remove the elements from the physics simulation Hype is running while still having them active for intersection detection and other forms of queries (like point, ray etc.).
The following function removes all elements from the regular scope of the Hype physics interaction:
hypeDocument.disablePhysicsCollisions = function(targetElms) {
targetElms.forEach(function(elm){
var elmBody = hypeDocument.getElementProperty(elm, 'physics-body');
if (elmBody) elmBody.collisionFilter = { 'group': -1}
});
}
If you need a version of the code that allows to re-enable them you would need to store a temporary copy of the original collisionFilter
:
hypeDocument.disablePhysicsCollisions = function(targetElms) {
targetElms.forEach(function(elm){
var elmBody = hypeDocument.getElementProperty(elm, 'physics-body');
if (elmBody) {
if (!elmBody._collisionFilter) elmBody._collisionFilter = Object.assign({}, elmBody.collisionFilter);
elmBody.collisionFilter = { 'group': -1}
}
});
}
hypeDocument.enablePhysicsCollisions = function(targetElms) {
targetElms.forEach(function(elm){
var elmBody = hypeDocument.getElementProperty(elm, 'physics-body');
if (elmBody && elmBody._collisionFilter) {
elmBody.collisionFilter = elmBody._collisionFilter;
delete elmBody._collisionFilter;
}
});
}
One interesting by product of intersection detection is that it works solely in the Matter-Engine. Hence, if you disable the visibility (display:none
) it still works for intersection detection. If in your game logic the visibility status is to be considered just filter the elements returned from the intersection check.
This article was posted to Medium: