Dev #11
@@ -49,7 +49,7 @@ function rect(left, top, width, height) {
|
||||
return { left, top, width, height, right: left + width, bottom: top + height, shape: 'rectangle' };
|
||||
}
|
||||
|
||||
test('forgeCollisionRuleTriggerActive — trigger "collision" : vrai seulement si les boîtes se chevauchent', () => {
|
||||
test('forgeCollisionRuleTriggerActive — trigger "collision" : vrai si les boîtes se chevauchent, faux si loin', () => {
|
||||
const objRect = rect(0, 0, 20, 20);
|
||||
const overlapping = rect(10, 10, 20, 20);
|
||||
const far = rect(200, 200, 20, 20);
|
||||
@@ -57,6 +57,18 @@ test('forgeCollisionRuleTriggerActive — trigger "collision" : vrai seulement s
|
||||
assert.equal(forgeCollisionRuleTriggerActive({ trigger: 'collision' }, objRect, far), false);
|
||||
});
|
||||
|
||||
test('forgeCollisionRuleTriggerActive — trigger "collision" : vrai aussi pour un simple CONTACT (bords qui se touchent sans se chevaucher)', () => {
|
||||
// Bug corrigé : cet objet est presque toujours aussi un obstacle
|
||||
// SOLIDE (forgeWouldCollide, personnage-controller.js) — le joueur ne
|
||||
// peut donc jamais dépasser un contact tangent, et un chevauchement
|
||||
// STRICT n'était donc jamais atteint : "à la collision" ne se
|
||||
// déclenchait jamais en jeu réel. objRect va de x=[20,40], playerRect
|
||||
// juste à côté en x=[0,20] : bord à bord, AUCUN chevauchement géométrique.
|
||||
const objRect = rect(20, 0, 20, 20);
|
||||
const touchingPlayer = rect(0, 0, 20, 20);
|
||||
assert.equal(forgeCollisionRuleTriggerActive({ trigger: 'collision' }, objRect, touchingPlayer), true);
|
||||
});
|
||||
|
||||
test('forgeCollisionRuleTriggerActive — trigger "perimetre" : distance entre centres <= perimetre_px', () => {
|
||||
const objRect = rect(0, 0, 10, 10); // centre (5,5)
|
||||
const near = rect(10, 0, 10, 10); // centre (15,5) -> distance 10
|
||||
|
||||
@@ -32,13 +32,35 @@ function forgeElementBoxRect(el, collision) {
|
||||
return forgeCollisionRectFromBox({ left: left, top: top, width: width, height: height }, collision);
|
||||
}
|
||||
|
||||
// "collision" : même chevauchement de boîtes que forgeWouldCollide
|
||||
// (personnage-controller.js). "perimetre" : distance entre les CENTRES
|
||||
// des deux boîtes <= rule.perimetre_px (pas entre les bords — plus simple
|
||||
// et suffisant pour une portée approximative, cohérent avec le reste du
|
||||
// moteur qui ne vise pas une physique précise).
|
||||
// Une petite marge (px) appliquée SEULEMENT à la détection du
|
||||
// déclencheur "collision" ci-dessous — jamais au blocage physique du
|
||||
// déplacement (forgeWouldCollide, personnage-controller.js, qui reste
|
||||
// strict). Bug corrigé : un objet est presque toujours aussi un
|
||||
// OBSTACLE SOLIDE (collision activée par défaut) — le joueur ne peut
|
||||
// donc jamais aller au-delà d'un contact tangent (bords qui se touchent
|
||||
// SANS se chevaucher), et un chevauchement STRICT (forgeShapesOverlap
|
||||
// nu) n'était donc jamais atteint : la règle "à la collision" ne se
|
||||
// déclenchait jamais. Cette marge élargit la boîte testée pour que ce
|
||||
// simple contact compte comme une collision.
|
||||
var FORGE_COLLISION_RULE_TOUCH_MARGIN = 3;
|
||||
|
||||
function forgeExpandRect(rect, margin) {
|
||||
return {
|
||||
left: rect.left - margin, top: rect.top - margin,
|
||||
right: rect.right + margin, bottom: rect.bottom + margin,
|
||||
width: rect.width + margin * 2, height: rect.height + margin * 2,
|
||||
shape: rect.shape,
|
||||
};
|
||||
}
|
||||
|
||||
// "collision" : chevauchement des boîtes, ÉLARGI d'une petite marge pour
|
||||
// détecter un simple contact (voir FORGE_COLLISION_RULE_TOUCH_MARGIN
|
||||
// ci-dessus). "perimetre" : distance entre les CENTRES des deux boîtes
|
||||
// <= rule.perimetre_px (pas entre les bords — plus simple et suffisant
|
||||
// pour une portée approximative, cohérent avec le reste du moteur qui ne
|
||||
// vise pas une physique précise).
|
||||
function forgeCollisionRuleTriggerActive(rule, objRect, playerRect) {
|
||||
if (rule.trigger === 'collision') return forgeShapesOverlap(objRect, playerRect);
|
||||
if (rule.trigger === 'collision') return forgeShapesOverlap(forgeExpandRect(objRect, FORGE_COLLISION_RULE_TOUCH_MARGIN), playerRect);
|
||||
var ocx = objRect.left + objRect.width / 2, ocy = objRect.top + objRect.height / 2;
|
||||
var pcx = playerRect.left + playerRect.width / 2, pcy = playerRect.top + playerRect.height / 2;
|
||||
var dist = Math.hypot(ocx - pcx, ocy - pcy);
|
||||
@@ -179,7 +201,7 @@ if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = {
|
||||
forgeCollisionRuleTriggerActive, forgeRunCollisionRuleAction, forgeCollisionRuleTick,
|
||||
forgeStartCollisionRuleControllers, forgeStopCollisionRuleControllers,
|
||||
forgeCollisionRuleStateKey, forgeElementBoxRect,
|
||||
forgeCollisionRuleStateKey, forgeElementBoxRect, forgeExpandRect,
|
||||
};
|
||||
const conditionsMod = require('./conditions.js');
|
||||
global.forgeCollisionRectFromBox = global.forgeCollisionRectFromBox || conditionsMod.forgeCollisionRectFromBox;
|
||||
|
||||
Reference in New Issue
Block a user