UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

518 lines (383 loc) 19.3 kB
var GetOverlapY = require('../../../src/physics/arcade/GetOverlapY'); var CONST = require('../../../src/physics/arcade/const'); describe('Phaser.Physics.Arcade.GetOverlapY', function () { function makeBody (options) { var opts = options || {}; var dy = opts._dy !== undefined ? opts._dy : 0; return { _dy: dy, y: opts.y !== undefined ? opts.y : 0, bottom: opts.bottom !== undefined ? opts.bottom : 0, overlapY: 0, embedded: false, physicsType: opts.physicsType !== undefined ? opts.physicsType : CONST.DYNAMIC_BODY, // Allow explicit deltaAbsY override; otherwise derive from _dy deltaAbsY: (function (d) { return function () { return d; }; })(opts.deltaAbsY !== undefined ? opts.deltaAbsY : Math.abs(dy)), checkCollision: { up: opts.checkCollision && opts.checkCollision.up !== undefined ? opts.checkCollision.up : true, down: opts.checkCollision && opts.checkCollision.down !== undefined ? opts.checkCollision.down : true }, touching: { none: true, up: false, down: false }, blocked: { none: true, up: false, down: false } }; } // --- Both bodies stationary --- describe('when both bodies have _dy === 0', function () { it('should set embedded true on both bodies', function () { var body1 = makeBody({ _dy: 0 }); var body2 = makeBody({ _dy: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.embedded).toBe(true); expect(body2.embedded).toBe(true); }); it('should return zero overlap when both bodies are stationary', function () { var body1 = makeBody({ _dy: 0 }); var body2 = makeBody({ _dy: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should set overlapY to zero on both bodies when stationary', function () { var body1 = makeBody({ _dy: 0 }); var body2 = makeBody({ _dy: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.overlapY).toBe(0); expect(body2.overlapY).toBe(0); }); it('should not modify touching or blocked flags when both stationary', function () { var body1 = makeBody({ _dy: 0 }); var body2 = makeBody({ _dy: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.touching.none).toBe(true); expect(body2.touching.none).toBe(true); expect(body1.blocked.none).toBe(true); expect(body2.blocked.none).toBe(true); }); }); // --- body1 moving down (body1._dy > body2._dy) --- describe('when body1._dy > body2._dy (body1 moving down)', function () { it('should return correct overlap when body1 bottom overlaps body2 top', function () { // overlap=10, maxOverlap = 20+0+0 = 20, 10 < 20 → valid var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(10); }); it('should set overlapY on both bodies to the computed overlap', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.overlapY).toBe(10); expect(body2.overlapY).toBe(10); }); it('should set touching.down on body1 and touching.up on body2', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.touching.down).toBe(true); expect(body1.touching.none).toBe(false); expect(body2.touching.up).toBe(true); expect(body2.touching.none).toBe(false); }); it('should not set touching.up on body1 or touching.down on body2', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.touching.up).toBe(false); expect(body2.touching.down).toBe(false); }); it('should return zero when overlap exceeds maxOverlap and overlapOnly is false', function () { // overlap=50, maxOverlap = 5+0+0 = 5 → 50 > 5 → 0 var body1 = makeBody({ _dy: 5, bottom: 150, deltaAbsY: 5 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should not zero out overlap when overlap exceeds maxOverlap but overlapOnly is true', function () { var body1 = makeBody({ _dy: 5, bottom: 150, deltaAbsY: 5 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var result = GetOverlapY(body1, body2, true, 0); expect(result).toBe(50); }); it('should return zero when body1 checkCollision.down is false', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, checkCollision: { down: false, up: true } }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should return zero when body2 checkCollision.up is false', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0, checkCollision: { up: false, down: true } }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should not set touching flags when collision check is disabled', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, checkCollision: { down: false, up: true } }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.touching.down).toBe(false); expect(body1.touching.none).toBe(true); expect(body2.touching.up).toBe(false); expect(body2.touching.none).toBe(true); }); it('should set body1.blocked.down when body2 is a static body and overlapOnly is false', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0, physicsType: CONST.STATIC_BODY }); GetOverlapY(body1, body2, false, 0); expect(body1.blocked.down).toBe(true); expect(body1.blocked.none).toBe(false); }); it('should not set body1.blocked.down when body2 is static but overlapOnly is true', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0, physicsType: CONST.STATIC_BODY }); GetOverlapY(body1, body2, true, 0); expect(body1.blocked.down).toBe(false); expect(body1.blocked.none).toBe(true); }); it('should set body2.blocked.up when body1 is a static body and overlapOnly is false', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, physicsType: CONST.STATIC_BODY }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body2.blocked.up).toBe(true); expect(body2.blocked.none).toBe(false); }); it('should not set body2.blocked.up when body1 is static but overlapOnly is true', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, physicsType: CONST.STATIC_BODY }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, true, 0); expect(body2.blocked.up).toBe(false); expect(body2.blocked.none).toBe(true); }); it('should not set blocked flags when neither body is static', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.blocked.down).toBe(false); expect(body2.blocked.up).toBe(false); }); it('should account for bias in maxOverlap calculation', function () { // overlap=10, deltaAbsY1=2, deltaAbsY2=2, bias=20 → maxOverlap=24 → 10 < 24 → valid var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 2 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 2 }); var result = GetOverlapY(body1, body2, false, 20); expect(result).toBe(10); }); it('should still zero the overlap when bias is not large enough', function () { // overlap=10, maxOverlap=2+2+3=7 → 10 > 7 → 0 var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 2 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 2 }); var result = GetOverlapY(body1, body2, false, 3); expect(result).toBe(0); }); }); // --- body1 moving up (body1._dy < body2._dy) --- describe('when body1._dy < body2._dy (body1 moving up)', function () { it('should return correct (negative) overlap when body1 top overlaps body2 bottom', function () { // overlap = body1.y - body2.bottom = 100 - 110 = -10, -overlap=10, maxOverlap=0+20=20 → valid var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(-10); }); it('should set overlapY on both bodies to the negative overlap value', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); GetOverlapY(body1, body2, false, 0); expect(body1.overlapY).toBe(-10); expect(body2.overlapY).toBe(-10); }); it('should set touching.up on body1 and touching.down on body2', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); GetOverlapY(body1, body2, false, 0); expect(body1.touching.up).toBe(true); expect(body1.touching.none).toBe(false); expect(body2.touching.down).toBe(true); expect(body2.touching.none).toBe(false); }); it('should not set touching.down on body1 or touching.up on body2', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); GetOverlapY(body1, body2, false, 0); expect(body1.touching.down).toBe(false); expect(body2.touching.up).toBe(false); }); it('should return zero when -overlap exceeds maxOverlap and overlapOnly is false', function () { // overlap = 100 - 150 = -50, -overlap=50, maxOverlap=0+5=5 → 50 > 5 → 0 var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 150, deltaAbsY: 5 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should not zero out overlap when -overlap exceeds maxOverlap but overlapOnly is true', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 150, deltaAbsY: 5 }); var result = GetOverlapY(body1, body2, true, 0); expect(result).toBe(-50); }); it('should return zero when body1 checkCollision.up is false', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0, checkCollision: { up: false, down: true } }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should return zero when body2 checkCollision.down is false', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, checkCollision: { down: false, up: true } }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should set body1.blocked.up when body2 is a static body and overlapOnly is false', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, physicsType: CONST.STATIC_BODY }); GetOverlapY(body1, body2, false, 0); expect(body1.blocked.up).toBe(true); expect(body1.blocked.none).toBe(false); }); it('should not set body1.blocked.up when body2 is static but overlapOnly is true', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, physicsType: CONST.STATIC_BODY }); GetOverlapY(body1, body2, true, 0); expect(body1.blocked.up).toBe(false); }); it('should set body2.blocked.down when body1 is a static body and overlapOnly is false', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0, physicsType: CONST.STATIC_BODY }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); GetOverlapY(body1, body2, false, 0); expect(body2.blocked.down).toBe(true); expect(body2.blocked.none).toBe(false); }); it('should not set body2.blocked.down when body1 is static but overlapOnly is true', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0, physicsType: CONST.STATIC_BODY }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); GetOverlapY(body1, body2, true, 0); expect(body2.blocked.down).toBe(false); }); }); // --- overlapY always set --- describe('overlapY assignment', function () { it('should always set overlapY on both bodies to the same value', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.overlapY).toBe(body2.overlapY); }); it('should set overlapY to zero when overlap is zeroed out by maxOverlap', function () { var body1 = makeBody({ _dy: 5, bottom: 200, deltaAbsY: 5 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.overlapY).toBe(0); expect(body2.overlapY).toBe(0); }); it('should set overlapY to zero when zeroed out by disabled checkCollision', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20, checkCollision: { down: false, up: true } }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); GetOverlapY(body1, body2, false, 0); expect(body1.overlapY).toBe(0); expect(body2.overlapY).toBe(0); }); }); // --- bias parameter --- describe('bias parameter', function () { it('should allow an overlap that would be zeroed without bias', function () { // overlap=10, deltaAbsY1=2, deltaAbsY2=2 → without bias maxOverlap=4 → zeroed // with bias=10 → maxOverlap=14 → 10 < 14 → valid var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 2 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 2 }); var result = GetOverlapY(body1, body2, false, 10); expect(result).toBe(10); }); it('should zero the overlap when bias is not large enough to cover it', function () { // overlap=10, maxOverlap=2+2+5=9 → 10 > 9 → 0 var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 2 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 2 }); var result = GetOverlapY(body1, body2, false, 5); expect(result).toBe(0); }); }); // --- return value --- describe('return value', function () { it('should return a number', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(typeof result).toBe('number'); }); it('should return the overlap with floating point values', function () { var body1 = makeBody({ _dy: 5, bottom: 110.5, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBeCloseTo(10.5); }); it('should return zero when both bodies are stationary', function () { var body1 = makeBody({ _dy: 0 }); var body2 = makeBody({ _dy: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBe(0); }); it('should return a positive overlap when body1 moves down into body2', function () { var body1 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var body2 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBeGreaterThan(0); }); it('should return a negative overlap when body1 moves up into body2', function () { var body1 = makeBody({ _dy: 0, y: 100, deltaAbsY: 0 }); var body2 = makeBody({ _dy: 5, bottom: 110, deltaAbsY: 20 }); var result = GetOverlapY(body1, body2, false, 0); expect(result).toBeLessThan(0); }); }); });