# Implementing an object gravity?

## Recommended Posts

Hi,
Is it possible to implement a gravity-like pulling force towards an object?
I mean that if I have object X which applies this force, other objects near him will be pulled stronger the closer they are to it?

thanks!

##### Share on other sites

It seems like what you are describing might be found here: http://phaser.io/docs/2.4.6/Phaser.Physics.P2.Body.html#gravity

However, note that this property of a P2 body is not implemented. Sounds like there might be future support, though.

You could do it yourself by seeing how P2 physics implements actual gravity, and then just apply that logic to local objects. If you do that cleanly, you could probably just contribute your implementation to the P2 Phaser source code!

##### Share on other sites

JIC: Arcade physics has this on the Arcade body as "gravity" and it has an x and a y.

##### Share on other sites

2 hours ago, drhayes said:

JIC: Arcade physics has this on the Arcade body as "gravity" and it has an x and a y.

I think this helps changing the gravity that affects the object.

I want the object to pull other objects towards it.

##### Share on other sites

Hello,

yes it's possible. It's not even that difficult consult google about newtonian gravity there is an equation which calculates the force between two objects (it's a simple equation in it's basic form). Apply that and you are there.

Here is a simple jsfiddle example which I just put together - I hope I understood what you are looking for correctly.

An here is the code:

``````console.log('start');
var ctx = document.querySelector('canvas').getContext('2d');
var lastTime = null;
var timeStep;

var obj1 = {};
var obj2 = {};

obj1.x = 20;
obj1.y = 270;
obj1.width = 20;
obj1.height = 20;
obj1.velocity = {
x: 50,
y: 0
};

obj2.x = 250;
obj2.y = 170;
obj2.width = 150;
obj2.height = 150;
obj2.mass = 100;

function attract(obj1, obj2)
{
var dx = obj2.x - obj1.x;
var dy = obj2.y - obj1.y;

if ((dx < 0 ? -dx : dx) > radii)
{
return;
}
if ((dy < 0 ? -dy : dy) > radii)
{
return;
}
var distance = dx * dx + dy * dy;
{
var ratio = (obj2.mass / distance)
obj1.velocity.x += ratio * dx;
obj1.velocity.y += ratio * dy;
}
}

function move(obj, dt)
{
obj.x += obj.velocity.x * dt;
obj.y += obj.velocity.y * dt;
}

function draw(obj)
{
ctx.beginPath();
ctx.arc(obj.x, obj.y, obj.radius, 0, 2 * Math.PI, false);
ctx.fill();
{
ctx.beginPath();
ctx.arc(obj.x, obj.y, obj.forceRadius, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#ff0000';
ctx.stroke();
}
}

function loop(time)
{
if (lastTime !== null) {
timeStep = time / 1000 - lastTime;
}
lastTime = time / 1000;

if (timeStep)
{
move(obj1, timeStep);
attract(obj1, obj2);
ctx.clearRect(0, 0, 500, 500);
ctx.fillStyle = '#B18247';
draw(obj2);
ctx.fillStyle = '#503779';
draw(obj1);
}

window.requestAnimationFrame(loop);
}

window.requestAnimationFrame(loop);``````

I don't know why but code tag or whatever it's called doesn't kinda work for me, I can see it in the preview displayed correctly but not when it's posted, so I gope you can get something from this :-). It's not a phaser example on purpose the implementation in phaser should be straightforward.

EDIT: And now it looks perceftly ok in code, I don't know what happened though :).

EDIT2: Oh, when I post or edit the post I can't see code formatting at all unless I go to outside the topic and then come back, weird but at least it works :-).

##### Share on other sites

For clarity I'm making another post so you can get through the code easier.

Here is slightly adjusted example with both objects attracting each other.

``````console.log('start');
var ctx = document.querySelector('canvas').getContext('2d');
var lastTime = null;
var timeStep;

var obj1 = {};
var obj2 = {};

obj1.x = 20;
obj1.y = 270;
obj1.velocity = {
x: 50,
y: 0
};
obj1.mass = 100;

obj2.x = 250;
obj2.y = 170;
obj2.velocity = {
x: 0,
y: 0
};
obj2.mass = 100;

function attract(obj1, obj2)
{
var dx = obj2.x - obj1.x;
var dy = obj2.y - obj1.y;

if ((dx < 0 ? -dx : dx) > radii)
{
return;
}
if ((dy < 0 ? -dy : dy) > radii)
{
return;
}
var distance = dx * dx + dy * dy;
{
var ratio = (obj2.mass / distance)
obj1.velocity.x += ratio * dx;
obj1.velocity.y += ratio * dy;
}
}

function move(obj, dt)
{
obj.x += obj.velocity.x * dt;
obj.y += obj.velocity.y * dt;
}

function draw(obj)
{
ctx.beginPath();
ctx.arc(obj.x, obj.y, obj.radius, 0, 2 * Math.PI, false);
ctx.fill();
{
ctx.beginPath();
ctx.arc(obj.x, obj.y, obj.forceRadius, 0, 2 * Math.PI, false);
ctx.lineWidth = 3;
ctx.strokeStyle = '#ff0000';
ctx.stroke();
}
}

function loop(time)
{
if (lastTime !== null) {
timeStep = time / 1000 - lastTime;
}
lastTime = time / 1000;

if (timeStep)
{
move(obj1, timeStep);
move(obj2, timeStep);
attract(obj1, obj2);
attract(obj2, obj1);
ctx.clearRect(0, 0, 500, 500);
ctx.fillStyle = '#B18247';
draw(obj2);
ctx.fillStyle = '#503779';
draw(obj1);
}

window.requestAnimationFrame(loop);
}

window.requestAnimationFrame(loop);``````

EDIT: You can play with mass and force radis of both objects however you want to get different results.

Is this what you are looking for?