phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.
571 lines (519 loc) • 24.2 kB
JavaScript
var ProcessY = require('../../../src/physics/arcade/ProcessY');
// Helper: create a minimal mock body with configurable properties
function makeBody (options)
{
options = options || {};
var body = {
velocity: { y: options.velocityY !== undefined ? options.velocityY : 0 },
pushable: options.pushable !== undefined ? options.pushable : true,
_dy: options._dy !== undefined ? options._dy : 0,
bottom: options.bottom !== undefined ? options.bottom : 100,
y: options.y !== undefined ? options.y : 0,
bounce: { y: options.bounceY !== undefined ? options.bounceY : 0 },
blocked: {
up: options.blockedUp !== undefined ? options.blockedUp : false,
down: options.blockedDown !== undefined ? options.blockedDown : false
},
mass: options.mass !== undefined ? options.mass : 1,
moves: options.moves !== undefined ? options.moves : false,
directControl: options.directControl !== undefined ? options.directControl : false,
x: options.x !== undefined ? options.x : 0,
autoFrame: { x: options.autoFrameX !== undefined ? options.autoFrameX : 0 },
prev: { x: options.prevX !== undefined ? options.prevX : 0 },
friction: { x: options.frictionX !== undefined ? options.frictionX : 1 },
_dx: options._dx !== undefined ? options._dx : 0,
processY: vi.fn()
};
return body;
}
// body1OnTop when |body1.bottom - body2.y| <= |body2.bottom - body1.y|
// body1 on top: body1.bottom=100, body2.y=100, body2.bottom=200, body1.y=0 → |0| <= |200| ✓
// body2 on top: body1.bottom=200, body2.y=100, body2.bottom=150, body1.y=150 → |100| <= |0| ✗
function makeBody1OnTop ()
{
return {
b1: makeBody({ bottom: 100, y: 0 }),
b2: makeBody({ bottom: 200, y: 100 })
};
}
function makeBody2OnTop ()
{
return {
b1: makeBody({ bottom: 200, y: 150 }),
b2: makeBody({ bottom: 150, y: 100 })
};
}
describe('Phaser.Physics.Arcade.ProcessY.Set', function ()
{
it('should return 0 when neither body is blocked', function ()
{
var b = makeBody1OnTop();
var result = ProcessY.Set(b.b1, b.b2, 10);
expect(result).toBe(0);
});
it('should return the absolute value of a negative overlap', function ()
{
var b = makeBody1OnTop();
// With a negative overlap and no blocking conditions, should still return 0
var result = ProcessY.Set(b.b1, b.b2, -10);
expect(result).toBe(0);
});
it('should return 0 with zero overlap', function ()
{
var b = makeBody1OnTop();
var result = ProcessY.Set(b.b1, b.b2, 0);
expect(result).toBe(0);
});
it('should detect body1 on top when bottom of body1 is close to top of body2', function ()
{
// body1.bottom=100, body2.y=100 → distance=0; body2.bottom=200, body1.y=0 → distance=200
// body1OnTop = true
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1 });
var b2 = makeBody({ bottom: 200, y: 100, blockedDown: true });
var result = ProcessY.Set(b1, b2, 5);
// body1 moving down, body1 on top, body2 blocked down → returns 1
expect(result).toBe(1);
expect(b1.processY).toHaveBeenCalledWith(-5, expect.any(Number), false, true);
});
it('should compute body1FullImpact as v2 - v1 * bounce.y', function ()
{
// v1=100, v2=50, bounce.y=0.5 → fullImpact = 50 - 100*0.5 = 0
// Trigger BlockCheck result=1 to observe the impact value passed to processY
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1, velocityY: 100, bounceY: 0.5 });
var b2 = makeBody({ bottom: 200, y: 100, velocityY: 50, blockedDown: true });
ProcessY.Set(b1, b2, 8);
var call = b1.processY.mock.calls[0];
expect(call[1]).toBeCloseTo(0);
});
it('should compute body2FullImpact as v1 - v2 * bounce.y', function ()
{
// v1=100, v2=50, body2.bounce.y=0.5 → body2FullImpact = 100 - 50*0.5 = 75
// Trigger body2 processY via BlockCheck result=2: body2 moving down, body2 on top, body1 blocked down
var b = makeBody2OnTop();
b.b1.blockedDown = true; // won't read via blocked.down directly, need the object
var b1 = makeBody({ bottom: 200, y: 150, velocityY: 100, blockedDown: true });
var b2 = makeBody({ bottom: 150, y: 100, velocityY: 50, bounceY: 0.5, _dy: 1 });
ProcessY.Set(b1, b2, 10);
var call = b2.processY.mock.calls[0];
expect(call[1]).toBeCloseTo(75);
});
});
describe('Phaser.Physics.Arcade.ProcessY.BlockCheck', function ()
{
it('should return 0 when no blocked conditions are met', function ()
{
var b1 = makeBody({ _dy: 0 });
var b2 = makeBody({ _dy: 0 });
ProcessY.Set(b1, b2, 10);
expect(ProcessY.BlockCheck()).toBe(0);
});
it('should return 1 and call body1.processY when body1 moving down, body1 on top, body2 blocked down', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1 });
var b2 = makeBody({ bottom: 200, y: 100, blockedDown: true });
ProcessY.Set(b1, b2, 12);
b1.processY.mockClear();
var result = ProcessY.BlockCheck();
expect(result).toBe(1);
expect(b1.processY).toHaveBeenCalledWith(-12, expect.any(Number), false, true);
});
it('should return 1 and call body1.processY when body1 moving up, body2 on top, body2 blocked up', function ()
{
// body2 on top means body1OnTop=false → body2OnTop=true
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1 });
var b2 = makeBody({ bottom: 150, y: 100, blockedUp: true });
ProcessY.Set(b1, b2, 7);
b1.processY.mockClear();
var result = ProcessY.BlockCheck();
expect(result).toBe(1);
expect(b1.processY).toHaveBeenCalledWith(7, expect.any(Number), true);
});
it('should return 2 and call body2.processY when body2 moving down, body2 on top, body1 blocked down', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, blockedDown: true });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 1 });
ProcessY.Set(b1, b2, 9);
b2.processY.mockClear();
var result = ProcessY.BlockCheck();
expect(result).toBe(2);
expect(b2.processY).toHaveBeenCalledWith(-9, expect.any(Number), false, true);
});
it('should return 2 and call body2.processY when body2 moving up, body1 on top, body1 blocked up', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, blockedUp: true });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1 });
ProcessY.Set(b1, b2, 6);
b2.processY.mockClear();
var result = ProcessY.BlockCheck();
expect(result).toBe(2);
expect(b2.processY).toHaveBeenCalledWith(6, expect.any(Number), true);
});
it('should not return 1 for body1 moving down when body1 is NOT on top', function ()
{
// body2 is on top; body1 moving down should not trigger the first block check
var b1 = makeBody({ bottom: 200, y: 150, _dy: 1 });
var b2 = makeBody({ bottom: 150, y: 100, blockedDown: true });
var result = ProcessY.Set(b1, b2, 5);
expect(result).toBe(0);
});
});
describe('Phaser.Physics.Arcade.ProcessY.Check', function ()
{
it('should return false when no movement conditions match', function ()
{
// _dy=0 for both, no directional movement
var b1 = makeBody({ bottom: 100, y: 0, _dy: 0, pushable: true });
var b2 = makeBody({ bottom: 200, y: 100, _dy: 0, pushable: true });
ProcessY.Set(b1, b2, 10);
var result = ProcessY.Check();
expect(result).toBe(false);
});
it('should return true when body1 moving up and body2 on top (side 0)', function ()
{
// body2 on top, body1 moving up
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 0, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 10);
var result = ProcessY.Check();
expect(result).toBe(true);
});
it('should return true when body2 moving up and body1 on top (side 1)', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 0, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 10);
var result = ProcessY.Check();
expect(result).toBe(true);
});
it('should return true when body1 moving down and body1 on top (side 2)', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: 0, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 10);
var result = ProcessY.Check();
expect(result).toBe(true);
});
it('should return true when body2 moving down and body2 on top (side 3)', function ()
{
// body2 on top, body2 moving down
var b1 = makeBody({ bottom: 200, y: 150, _dy: 0, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 1, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 10);
var result = ProcessY.Check();
expect(result).toBe(true);
});
it('should call Run(0) which calls processY on body1 and body2 when both pushable', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: true, mass: 1, velocityY: -100 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 0, pushable: true, mass: 1, velocityY: 0 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Check();
expect(b1.processY).toHaveBeenCalled();
expect(b2.processY).toHaveBeenCalled();
});
});
describe('Phaser.Physics.Arcade.ProcessY.Run', function ()
{
it('should always return true', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: 0, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 10);
expect(ProcessY.Run(0)).toBe(true);
expect(ProcessY.Run(1)).toBe(true);
expect(ProcessY.Run(2)).toBe(true);
expect(ProcessY.Run(3)).toBe(true);
});
it('should split overlap equally when both bodies are pushable (side 0)', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 0, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(0);
// overlap becomes 20*0.5=10; side 0 → body1 gets +overlap, body2 gets -overlap
expect(b1.processY.mock.calls[0][0]).toBeCloseTo(10);
expect(b2.processY.mock.calls[0][0]).toBeCloseTo(-10);
});
it('should split overlap equally when both bodies are pushable (side 1)', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 0, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(1);
// side 1 → body1 gets -overlap, body2 gets +overlap
expect(b1.processY.mock.calls[0][0]).toBeCloseTo(-10);
expect(b2.processY.mock.calls[0][0]).toBeCloseTo(10);
});
it('should apply full overlap to body1 only when body1 pushable and body2 not (side 0)', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 0, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 16);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(0);
expect(b1.processY).toHaveBeenCalledWith(16, expect.any(Number), true);
expect(b2.processY).not.toHaveBeenCalled();
});
it('should apply full overlap to body1 only when body1 pushable and body2 not (side 1)', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 0, pushable: true, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 16);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(1);
expect(b1.processY).toHaveBeenCalledWith(-16, expect.any(Number), false, true);
expect(b2.processY).not.toHaveBeenCalled();
});
it('should apply full overlap to body2 only when body2 pushable and body1 not (side 0)', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 0, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 14);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(0);
expect(b2.processY).toHaveBeenCalledWith(-14, expect.any(Number), false, true);
expect(b1.processY).not.toHaveBeenCalled();
});
it('should apply full overlap to body2 only when body2 pushable and body1 not (side 1)', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 0, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1, pushable: true, mass: 1 });
ProcessY.Set(b1, b2, 14);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(1);
expect(b2.processY).toHaveBeenCalledWith(14, expect.any(Number), true);
expect(b1.processY).not.toHaveBeenCalled();
});
it('should handle neither pushable, side 0, body2 stationary', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 0, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(0);
expect(b1.processY).toHaveBeenCalledWith(20, 0, true);
expect(b2.processY).toHaveBeenCalledWith(0, null, false, true);
});
it('should handle neither pushable, side 0, body2 moving down', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 1, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(0);
expect(b1.processY).toHaveBeenCalledWith(10, 0, true);
expect(b2.processY).toHaveBeenCalledWith(-10, 0, false, true);
});
it('should handle neither pushable, side 0, body2 moving up (same direction)', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: false, mass: 1, velocityY: -50 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: -1, pushable: false, mass: 1, velocityY: -30 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(0);
expect(b1.processY).toHaveBeenCalledWith(10, -30, true);
expect(b2.processY).toHaveBeenCalledWith(-10, null, false, true);
});
it('should handle neither pushable, side 1, body1 stationary', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 0, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(1);
expect(b1.processY).toHaveBeenCalledWith(0, null, false, true);
expect(b2.processY).toHaveBeenCalledWith(20, 0, true);
});
it('should handle neither pushable, side 1, body1 moving down', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(1);
expect(b1.processY).toHaveBeenCalledWith(-10, 0, false, true);
expect(b2.processY).toHaveBeenCalledWith(10, 0, true);
});
it('should handle neither pushable, side 2, body2 stationary', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: 0, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(2);
expect(b1.processY).toHaveBeenCalledWith(-20, 0, false, true);
expect(b2.processY).toHaveBeenCalledWith(0, null, true);
});
it('should handle neither pushable, side 2, body2 moving up', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, _dy: 1, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 200, y: 100, _dy: -1, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(2);
expect(b1.processY).toHaveBeenCalledWith(-10, 0, false, true);
expect(b2.processY).toHaveBeenCalledWith(10, 0, true);
});
it('should handle neither pushable, side 3, body1 stationary', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: 0, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 1, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(3);
expect(b1.processY).toHaveBeenCalledWith(0, null, true);
expect(b2.processY).toHaveBeenCalledWith(-20, 0, false, true);
});
it('should handle neither pushable, side 3, body1 moving up', function ()
{
var b1 = makeBody({ bottom: 200, y: 150, _dy: -1, pushable: false, mass: 1 });
var b2 = makeBody({ bottom: 150, y: 100, _dy: 1, pushable: false, mass: 1 });
ProcessY.Set(b1, b2, 20);
b1.processY.mockClear();
b2.processY.mockClear();
ProcessY.Run(3);
expect(b1.processY).toHaveBeenCalledWith(10, 0, true);
expect(b2.processY).toHaveBeenCalledWith(-10, 0, false, true);
});
});
describe('Phaser.Physics.Arcade.ProcessY.RunImmovableBody1', function ()
{
it('should zero out body2 velocity when blockedState is 1', function ()
{
var b1 = makeBody({ bottom: 100, y: 0 });
var b2 = makeBody({ bottom: 200, y: 100, velocityY: 200 });
ProcessY.Set(b1, b2, 10);
ProcessY.RunImmovableBody1(1);
expect(b2.velocity.y).toBe(0);
expect(b2.processY).not.toHaveBeenCalled();
});
it('should call body2.processY with positive overlap when body1 is on top and blockedState is 0', function ()
{
var b1 = makeBody({ bottom: 100, y: 0 });
var b2 = makeBody({ bottom: 200, y: 100 });
ProcessY.Set(b1, b2, 15);
b2.processY.mockClear();
ProcessY.RunImmovableBody1(0);
expect(b2.processY).toHaveBeenCalledWith(15, expect.any(Number), true);
});
it('should call body2.processY with negative overlap when body2 is on top and blockedState is 0', function ()
{
var b1 = makeBody({ bottom: 200, y: 150 });
var b2 = makeBody({ bottom: 150, y: 100 });
ProcessY.Set(b1, b2, 15);
b2.processY.mockClear();
ProcessY.RunImmovableBody1(0);
expect(b2.processY).toHaveBeenCalledWith(-15, expect.any(Number), false, true);
});
it('should apply body1 horizontal distance to body2.x when body1.moves is true (prev control)', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, moves: true, directControl: false, x: 50, prevX: 40, frictionX: 1 });
var b2 = makeBody({ bottom: 200, y: 100, x: 100, prevX: 100 });
ProcessY.Set(b1, b2, 10);
b2.processY.mockClear();
ProcessY.RunImmovableBody1(1);
// body1Distance = 50 - 40 = 10; body2.x += 10 * 1 = 110
expect(b2.x).toBe(110);
expect(b2._dx).toBe(110 - 100);
});
it('should apply body1 horizontal distance using autoFrame when directControl is true', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, moves: true, directControl: true, x: 50, autoFrameX: 45, frictionX: 2 });
var b2 = makeBody({ bottom: 200, y: 100, x: 100, prevX: 100 });
ProcessY.Set(b1, b2, 10);
b2.processY.mockClear();
ProcessY.RunImmovableBody1(1);
// body1Distance = 50 - 45 = 5; body2.x += 5 * 2 = 110
expect(b2.x).toBe(110);
expect(b2._dx).toBe(10);
});
it('should not modify body2.x when body1.moves is false', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, moves: false });
var b2 = makeBody({ bottom: 200, y: 100, x: 100, prevX: 100 });
ProcessY.Set(b1, b2, 10);
b2.processY.mockClear();
ProcessY.RunImmovableBody1(1);
expect(b2.x).toBe(100);
});
});
describe('Phaser.Physics.Arcade.ProcessY.RunImmovableBody2', function ()
{
it('should zero out body1 velocity when blockedState is 2', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, velocityY: 300 });
var b2 = makeBody({ bottom: 200, y: 100 });
ProcessY.Set(b1, b2, 10);
ProcessY.RunImmovableBody2(2);
expect(b1.velocity.y).toBe(0);
expect(b1.processY).not.toHaveBeenCalled();
});
it('should call body1.processY with positive overlap when body2 is on top and blockedState is 0', function ()
{
// body2OnTop → body1OnTop=false
var b1 = makeBody({ bottom: 200, y: 150 });
var b2 = makeBody({ bottom: 150, y: 100 });
ProcessY.Set(b1, b2, 18);
b1.processY.mockClear();
ProcessY.RunImmovableBody2(0);
expect(b1.processY).toHaveBeenCalledWith(18, expect.any(Number), true);
});
it('should call body1.processY with negative overlap when body1 is on top and blockedState is 0', function ()
{
var b1 = makeBody({ bottom: 100, y: 0 });
var b2 = makeBody({ bottom: 200, y: 100 });
ProcessY.Set(b1, b2, 18);
b1.processY.mockClear();
ProcessY.RunImmovableBody2(0);
expect(b1.processY).toHaveBeenCalledWith(-18, expect.any(Number), false, true);
});
it('should apply body2 horizontal distance to body1.x when body2.moves is true (prev control)', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, x: 200, prevX: 200 });
var b2 = makeBody({ bottom: 200, y: 100, moves: true, directControl: false, x: 60, prevX: 50, frictionX: 1 });
ProcessY.Set(b1, b2, 10);
b1.processY.mockClear();
ProcessY.RunImmovableBody2(2);
// body2Distance = 60 - 50 = 10; body1.x += 10 * 1 = 210
expect(b1.x).toBe(210);
expect(b1._dx).toBe(210 - 200);
});
it('should apply body2 horizontal distance using autoFrame when directControl is true', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, x: 200, prevX: 200 });
var b2 = makeBody({ bottom: 200, y: 100, moves: true, directControl: true, x: 60, autoFrameX: 55, frictionX: 3 });
ProcessY.Set(b1, b2, 10);
b1.processY.mockClear();
ProcessY.RunImmovableBody2(2);
// body2Distance = 60 - 55 = 5; body1.x += 5 * 3 = 215
expect(b1.x).toBe(215);
expect(b1._dx).toBe(15);
});
it('should not modify body1.x when body2.moves is false', function ()
{
var b1 = makeBody({ bottom: 100, y: 0, x: 200, prevX: 200 });
var b2 = makeBody({ bottom: 200, y: 100, moves: false });
ProcessY.Set(b1, b2, 10);
b1.processY.mockClear();
ProcessY.RunImmovableBody2(2);
expect(b1.x).toBe(200);
});
});