Merging previous changes back in again.

This commit is contained in:
photonstorm 2014-01-22 14:31:18 +00:00
parent f6af6fe0a3
commit b2c49ef853
7 changed files with 229 additions and 770 deletions

View file

@ -56,10 +56,15 @@ Significant API changes:
* Tilemap.createFromObjects can now turn a bunch of Tiled objects into Sprites in one single call, and copies across all properties as well. * Tilemap.createFromObjects can now turn a bunch of Tiled objects into Sprites in one single call, and copies across all properties as well.
* Tween.onStartCallback and onCompleteCallback have been removed to avoid confusion. You should use the onStart, onLoop and onComplete events instead. * Tween.onStartCallback and onCompleteCallback have been removed to avoid confusion. You should use the onStart, onLoop and onComplete events instead.
* Button.forceOut default value has changed from true to false, so Buttons will revert to an Up state (if set) when pressed and released. * Button.forceOut default value has changed from true to false, so Buttons will revert to an Up state (if set) when pressed and released.
* Body.drag has been removed. Please use the new Body.friction value instead (which is a number value, not a Point object)
* The way the collision process callback works has changed significantly and now works as originally intended. * The way the collision process callback works has changed significantly and now works as originally intended.
* The World level quadtree is no longer created, they are now built and ripped down each time you collide a Group, this helps collision accuracy. * The World level quadtree is no longer created, they are now built and ripped down each time you collide a Group, this helps collision accuracy.
* Bodies are no longer added to a world quadtree, so have had all of their quadtree properties removed such as skipQuadtree, quadTreeIndex, etc. * Bodies are no longer added to a world quadtree, so have had all of their quadtree properties removed such as skipQuadtree, quadTreeIndex, etc.
* Body.drag has been removed. Please use the new Body.friction value instead (which is a number value, not a Point object)
* Body.embedded and Body.wasTouching have been removed as they are no longer required.
* Body.customSeparateX/Y have been removed as you should now use Body.customSeparateCallback.
* Body.maxVelocity defaults have been removed from 10,000 to 2000.
* Body.friction is new and has a default value of 0.1 - you may need to set this to zero depending on the type of game you're making.
* Body.customSeparateCallback allows you to set your own callback when two Bodies need to separate rather than using the built-in method.
New features: New features:
@ -87,12 +92,14 @@ New features:
* Groups now have an 'alive' property, which can be useful when iterating through child groups with functions like forEachAlive. * Groups now have an 'alive' property, which can be useful when iterating through child groups with functions like forEachAlive.
* Added a new Project Template "Full Screen Mobile" which you can find in the resources folder. Contains html / css / layout needed for a deployed Phaser game. * Added a new Project Template "Full Screen Mobile" which you can find in the resources folder. Contains html / css / layout needed for a deployed Phaser game.
* Body.speed - the current speed of the body. * Body.speed - the current speed of the body.
* Body.angle - the current angle the Body is facing based on its velocity. This is not the same as the Sprite angle that may own the body.
* Body.friction - This now replaces Body.drag and provides for a much smoother friction experience. * Body.friction - This now replaces Body.drag and provides for a much smoother friction experience.
* Body.minBounceVelocity - If a Body has bounce set, this threshold controls if it should rebound or not. Use it to stop 'jittering' on bounds/tiles with super-low velocities. * Body.minBounceVelocity - If a Body has bounce set, this threshold controls if it should rebound or not. Use it to stop 'jittering' on bounds/tiles with super-low velocities.
* QuadTree.populate - you can pass it a Group and it'll automatically insert all of the children ready for inspection. * QuadTree.populate - you can pass it a Group and it'll automatically insert all of the children ready for inspection.
* Input.setMoveCallback allows you to set a callback that will be fired each time the activePointer receives a DOM move event. * Input.setMoveCallback allows you to set a callback that will be fired each time the activePointer receives a DOM move event.
* Math.distancePow(x1,y1,x2,y2,power) returns the distance between two coordinates at the given power. * Math.distancePow(x1,y1,x2,y2,power) returns the distance between two coordinates at the given power.
* Physics.collideArray(obj, array) for when you want to collide an object against a number of sprites that aren't all in the same Group. * Physics.collideArray(obj, array) for when you want to collide an object against a number of sprites that aren't all in the same Group.
* Physics.overlapArray(obj, array) for when you want to overlap test an object against a number of sprites that aren't all in the same Group.
* Math.reverseAngle - reverses an angle (in radians). * Math.reverseAngle - reverses an angle (in radians).
* Math.normalizeAngle - normalises an angle, now in radians only. * Math.normalizeAngle - normalises an angle, now in radians only.
* Math.normalizeLatitude - Normalizes a latitude to the [-90,90] range. * Math.normalizeLatitude - Normalizes a latitude to the [-90,90] range.

View file

@ -3,8 +3,8 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p
function preload() { function preload() {
game.load.tilemap('level3', 'assets/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON); game.load.tilemap('level3', 'assets/tilemaps/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON);
game.load.image('tiles', 'assets/maps/cybernoid.png', 16, 16); game.load.image('tiles', 'assets/tilemaps/tiles/cybernoid.png', 16, 16);
game.load.image('phaser', 'assets/sprites/phaser-ship.png'); game.load.image('phaser', 'assets/sprites/phaser-ship.png');
game.load.image('chunk', 'assets/sprites/chunk.png'); game.load.image('chunk', 'assets/sprites/chunk.png');
@ -29,13 +29,12 @@ function create() {
// Basically this sets EVERY SINGLE tile to fully collide on all faces // Basically this sets EVERY SINGLE tile to fully collide on all faces
map.setCollisionByExclusion([7, 32, 35, 36, 47]); map.setCollisionByExclusion([7, 32, 35, 36, 47]);
// layer.debug = true; layer.debug = true;
layer.resizeWorld(); layer.resizeWorld();
sprite = game.add.sprite(450, 80, 'phaser'); sprite = game.add.sprite(450, 80, 'phaser');
sprite.anchor.setTo(0.5, 0.5); sprite.anchor.setTo(0.5, 0.5);
sprite.angle = 5;
game.camera.follow(sprite); game.camera.follow(sprite);
// game.camera.deadzone = new Phaser.Rectangle(160, 160, layer.renderWidth-320, layer.renderHeight-320); // game.camera.deadzone = new Phaser.Rectangle(160, 160, layer.renderWidth-320, layer.renderHeight-320);
@ -47,7 +46,7 @@ function create() {
emitter.makeParticles('chunk'); emitter.makeParticles('chunk');
emitter.minRotation = 0; emitter.minRotation = 0;
emitter.maxRotation = 0; emitter.maxRotation = 0;
emitter.gravity = 5; emitter.gravity = 150;
emitter.bounce.setTo(0.5, 0.5); emitter.bounce.setTo(0.5, 0.5);
game.input.onDown.add(particleBurst, this); game.input.onDown.add(particleBurst, this);

View file

@ -28,7 +28,7 @@ function create() {
var bg = game.add.sprite(0, 0, bmd); var bg = game.add.sprite(0, 0, bmd);
bg.body.moves = false; bg.body.moves = false;
test7(); test4();
} }
@ -36,7 +36,7 @@ function test7() {
game.physics.gravity.y = 200; game.physics.gravity.y = 200;
sprite = game.add.sprite(300, 300, 'gameboy', 0); sprite = game.add.sprite(0, 300, 'gameboy', 0);
sprite.name = 'red'; sprite.name = 'red';
sprite.body.collideWorldBounds = true; sprite.body.collideWorldBounds = true;
sprite.body.bounce.setTo(0.8, 0.8); sprite.body.bounce.setTo(0.8, 0.8);
@ -119,7 +119,7 @@ function stop5() {
function test4() { function test4() {
game.physics.gravity.y = 50; game.physics.gravity.y = 150;
sprite = game.add.sprite(300, 0, 'gameboy', 0); sprite = game.add.sprite(300, 0, 'gameboy', 0);
sprite.name = 'red'; sprite.name = 'red';
@ -242,15 +242,15 @@ function update() {
// game.physics.collide(group, group); // game.physics.collide(group, group);
// if (sprite3) if (sprite3)
// { {
// game.physics.collideArray(sprite, [sprite2, sprite3]); game.physics.collideArray(sprite, [sprite2, sprite3]);
// game.physics.collide(sprite2, sprite3); game.physics.collide(sprite2, sprite3);
// } }
// else else
// { {
// game.physics.collide(sprite, sprite2); game.physics.collide(sprite, sprite2);
// } }
if (sprite) if (sprite)

View file

@ -23,10 +23,11 @@ function create() {
bg.body.moves = false; bg.body.moves = false;
game.physics.gravity.y = 250; game.physics.gravity.y = 250;
// game.physics.gravity.x = 250;
sprites = game.add.group(); sprites = game.add.group();
for (var i = 0; i < 40; i++) for (var i = 0; i < 20; i++)
{ {
var s = sprites.create(game.rnd.integerInRange(100, 700), game.rnd.integerInRange(32, 200), 'ball'); var s = sprites.create(game.rnd.integerInRange(100, 700), game.rnd.integerInRange(32, 200), 'ball');
s.body.velocity.x = game.rnd.integerInRange(-400, 400); s.body.velocity.x = game.rnd.integerInRange(-400, 400);

View file

@ -3,8 +3,8 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p
function preload() { function preload() {
game.load.tilemap('level3', 'assets/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON); game.load.tilemap('level3', 'assets/tilemaps/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON);
game.load.image('tiles', 'assets/maps/cybernoid.png', 16, 16); game.load.image('tiles', 'assets/tilemaps/tiles/cybernoid.png', 16, 16);
game.load.image('phaser', 'assets/sprites/phaser-ship.png'); game.load.image('phaser', 'assets/sprites/phaser-ship.png');
game.load.image('chunk', 'assets/sprites/chunk.png'); game.load.image('chunk', 'assets/sprites/chunk.png');
@ -29,7 +29,7 @@ function create() {
// Basically this sets EVERY SINGLE tile to fully collide on all faces // Basically this sets EVERY SINGLE tile to fully collide on all faces
map.setCollisionByExclusion([7, 32, 35, 36, 47]); map.setCollisionByExclusion([7, 32, 35, 36, 47]);
// layer.debug = true; layer.debug = true;
layer.resizeWorld(); layer.resizeWorld();
@ -47,7 +47,7 @@ function create() {
emitter.makeParticles('chunk'); emitter.makeParticles('chunk');
emitter.minRotation = 0; emitter.minRotation = 0;
emitter.maxRotation = 0; emitter.maxRotation = 0;
emitter.gravity = 5; emitter.gravity = 150;
emitter.bounce.setTo(0.5, 0.5); emitter.bounce.setTo(0.5, 0.5);
game.input.onDown.add(particleBurst, this); game.input.onDown.add(particleBurst, this);

View file

@ -32,12 +32,7 @@ Phaser.Physics.Arcade = function (game) {
/** /**
* @property {Phaser.Rectangle} bounds - The bounds inside of which the physics world exists. Defaults to match the world bounds. * @property {Phaser.Rectangle} bounds - The bounds inside of which the physics world exists. Defaults to match the world bounds.
*/ */
this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height); // this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height);
/**
* @property {number} OVERLAP_BIAS - A value added to the delta values during collision checks.
*/
this.OVERLAP_BIAS = 4;
/** /**
* @property {Phaser.QuadTree} quadTree - The world QuadTree. * @property {Phaser.QuadTree} quadTree - The world QuadTree.
@ -60,55 +55,55 @@ Phaser.Physics.Arcade = function (game) {
* @property {Phaser.Rectangle} _bounds1 - Internal cache var. * @property {Phaser.Rectangle} _bounds1 - Internal cache var.
* @private * @private
*/ */
this._bounds1 = new Phaser.Rectangle(); // this._bounds1 = new Phaser.Rectangle();
/** /**
* @property {Phaser.Rectangle} _bounds2 - Internal cache var. * @property {Phaser.Rectangle} _bounds2 - Internal cache var.
* @private * @private
*/ */
this._bounds2 = new Phaser.Rectangle(); // this._bounds2 = new Phaser.Rectangle();
/** /**
* @property {number} _overlap - Internal cache var. * @property {number} _overlap - Internal cache var.
* @private * @private
*/ */
this._overlap = 0; // this._overlap = 0;
/** /**
* @property {number} _maxOverlap - Internal cache var. * @property {number} _maxOverlap - Internal cache var.
* @private * @private
*/ */
this._maxOverlap = 0; // this._maxOverlap = 0;
/** /**
* @property {number} _velocity1 - Internal cache var. * @property {number} _velocity1 - Internal cache var.
* @private * @private
*/ */
this._velocity1 = 0; // this._velocity1 = 0;
/** /**
* @property {number} _velocity2 - Internal cache var. * @property {number} _velocity2 - Internal cache var.
* @private * @private
*/ */
this._velocity2 = 0; // this._velocity2 = 0;
/** /**
* @property {number} _newVelocity1 - Internal cache var. * @property {number} _newVelocity1 - Internal cache var.
* @private * @private
*/ */
this._newVelocity1 = 0; // this._newVelocity1 = 0;
/** /**
* @property {number} _newVelocity2 - Internal cache var. * @property {number} _newVelocity2 - Internal cache var.
* @private * @private
*/ */
this._newVelocity2 = 0; // this._newVelocity2 = 0;
/** /**
* @property {number} _average - Internal cache var. * @property {number} _average - Internal cache var.
* @private * @private
*/ */
this._average = 0; // this._average = 0;
/** /**
* @property {Array} _mapData - Internal cache var. * @property {Array} _mapData - Internal cache var.
@ -263,45 +258,39 @@ Phaser.Physics.Arcade.prototype = {
this._result = false; this._result = false;
this._total = 0; this._total = 0;
// Only test valid objects this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true);
if (object1 && object2 && object1.exists && object2.exists)
return (this._total > 0);
},
/**
* Checks for overlaps between a game object and a array of game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer checks.
* Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.
* An optional processCallback can be provided. If given this function will be called when two sprites are found to be overlapping,
* giving you the chance to perform additional checks. If the function returns true then the overlap takes place. If it returns false it is skipped.
* The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for overlapCallback to be called.
*
* @method Phaser.Physics.Arcade#overlapArray
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
* @param {<Phaser.Sprite>array|<Phaser.Group>array|<Phaser.Particles.Emitter>array|<Phaser.Tilemap>array} objectArray - An array of objects to check. Can contain instances of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.
* @param {function} [overlapCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
* @param {object} [callbackContext] - The context in which to run the callbacks.
* @returns {boolean} True if a collision occured otherwise false.
*/
overlapArray: function (object1, objectArray, overlapCallback, processCallback, callbackContext) {
overlapCallback = overlapCallback || null;
processCallback = processCallback || null;
callbackContext = callbackContext || overlapCallback;
this._result = false;
this._total = 0;
for (var i = 0, len = objectArray.length; i < len; i++)
{ {
// SPRITES this.collideHandler(object1, objectArray[i], overlapCallback, processCallback, callbackContext, true);
if (object1.type == Phaser.SPRITE || object1.type == Phaser.TILESPRITE)
{
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
{
this.collideSpriteVsSprite(object1, object2, overlapCallback, processCallback, callbackContext, true);
}
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
{
this.collideSpriteVsGroup(object1, object2, overlapCallback, processCallback, callbackContext, true);
}
}
// GROUPS
else if (object1.type == Phaser.GROUP)
{
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
{
this.collideSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext, true);
}
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
{
this.collideGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext, true);
}
}
// EMITTER
else if (object1.type == Phaser.EMITTER)
{
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
{
this.collideSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext, true);
}
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
{
this.collideGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext, true);
}
}
} }
return (this._total > 0); return (this._total > 0);
@ -333,7 +322,7 @@ Phaser.Physics.Arcade.prototype = {
this._result = false; this._result = false;
this._total = 0; this._total = 0;
this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext); this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false);
return (this._total > 0); return (this._total > 0);
@ -365,7 +354,7 @@ Phaser.Physics.Arcade.prototype = {
for (var i = 0, len = objectArray.length; i < len; i++) for (var i = 0, len = objectArray.length; i < len; i++)
{ {
this.collideHandler(object1, objectArray[i], collideCallback, processCallback, callbackContext); this.collideHandler(object1, objectArray[i], collideCallback, processCallback, callbackContext, false);
} }
return (this._total > 0); return (this._total > 0);
@ -379,16 +368,17 @@ Phaser.Physics.Arcade.prototype = {
* @private * @private
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap. * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
* @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. Can also be an array of objects to check. * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. Can also be an array of objects to check.
* @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them. * @param {function} collideCallback - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.
* @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them. * @param {function} processCallback - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
* @param {object} [callbackContext] - The context in which to run the callbacks. * @param {object} callbackContext - The context in which to run the callbacks.
* @param {boolean} overlapOnly - Just run an overlap or a full collision.
*/ */
collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext) { collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) {
// Only collide valid objects // Only collide valid objects
if (typeof object2 === 'undefined' && object1.type === Phaser.GROUP) if (typeof object2 === 'undefined' && object1.type === Phaser.GROUP)
{ {
this.collideGroupVsSelf(object1, collideCallback, processCallback, callbackContext, false); this.collideGroupVsSelf(object1, collideCallback, processCallback, callbackContext, overlapOnly);
return; return;
} }
@ -399,11 +389,11 @@ Phaser.Physics.Arcade.prototype = {
{ {
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE) if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
{ {
this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, false); this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} }
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
{ {
this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, false); this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} }
else if (object2.type == Phaser.TILEMAPLAYER) else if (object2.type == Phaser.TILEMAPLAYER)
{ {
@ -415,11 +405,11 @@ Phaser.Physics.Arcade.prototype = {
{ {
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE) if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
{ {
this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, false); this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
} }
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
{ {
this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, false); this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} }
else if (object2.type == Phaser.TILEMAPLAYER) else if (object2.type == Phaser.TILEMAPLAYER)
{ {
@ -443,11 +433,11 @@ Phaser.Physics.Arcade.prototype = {
{ {
if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE) if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
{ {
this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, false); this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
} }
else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
{ {
this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, false); this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
} }
else if (object2.type == Phaser.TILEMAPLAYER) else if (object2.type == Phaser.TILEMAPLAYER)
{ {
@ -688,11 +678,7 @@ Phaser.Physics.Arcade.prototype = {
{ {
if (body1.overlap(body2)) if (body1.overlap(body2))
{ {
// console.log('-----------------------------------------------------------------------------'); return body1.separate(body2);
// console.log(body1.sprite.name, 'overlaps', body2.sprite.name, 'x', body1.overlapX, 'y', body1.overlapY);
body1.separate(body2);
return true;
} }
} }

File diff suppressed because it is too large Load diff