Jump to content

[P2] Do not apply gravity to a sprite


Recommended Posts



I still have my player and my weapon, each is a sprite with a P2 body.


I'd like my weapon to follow exactly my player, not "floating" a bit when my player is moving (happens when you bind weapon.body.x/y to hero.body.x/y, sprites are not totally aligned every frame so it creates a floating movement for the weapon).


Today my weapon has KINEMATIC state because when it's in DYNAMIC state it looks like the sword has gravity effects, so it's slowly moving down from my player until it gets out of the screen.


What I don't get is that my weapon go away from my player but in it's update function I bind :

this.body.x = this.hero.body.x;this.body.y = this.hero.body.y + 13;this.x = this.hero.x;this.y = this.hero.y + 13;

I tried a lot of things but still can't make it work properly. I would like my weapon to stick my player, attach it to one pixel and it doesn't move away from it !


Thx for your help guys ;)

Link to comment
Share on other sites

1. You can set gravityScale to zero on a specific body to ignore gravity.

2. Do you set your weapon's position manually to your players position ? Have you tried to use a constraint like distance or revolute to attach it to your body?

3. Does your weapon really needs to be a physical shape? In most cases your player's position is enough to determine if a player was hit by a weapon- just compare the distance to the player when using a sword if the enemy is near enough.

4. I guess your weapon is very small? You may run into other problems with tunneling later in your development. I would really think over the decision to make the weapon a physical shape.


Have fun


Regards George

Link to comment
Share on other sites

My weapon is "physical" to use P2 with collisions, so I don't bother to calculate positions, overlaps etc. Maybe I'm wrong ?


I already tried to set gravityScale to 0 ... not working.


I do set the weapon position in it's update function and it's based on the player position (piece of code I attached in my firt post).

Link to comment
Share on other sites

You should enable sensor on it.

this.body.data.shapes[0].sensor = true;

Your weapon will still fire event when its group collides with an other but it will no longer be physical. It'll act as a trigger.

And I think you should never play with its velocity (just in case you do).


Edit: Edited the code which was totally innacurate

Link to comment
Share on other sites

What kind of event does it fire ? It's no longer P2 collision event I guess or do I still need to activate P2 on it ? I can't load custom collision shapes ?


Is there any good tutorial or topic about sensors ?


EDIT : in fact I don't get what will be changed with a sensor ?

Link to comment
Share on other sites

 It will be the same: Polygon shapes etc. but with no physical collision. That means that a sensor will not block anything but just fire the events.

For example:

this.body.onBeginContact.add(callback, this); // It works with sensor=true;

I often use it.

Link to comment
Share on other sites

Having your weapon with physics will make it floating since each frame you are saying "Weapon, try to reach the player coordinates" but since the weapon has physics enabled (it has a mass, it can collide with things etc...) it will feel laggy and floating.


Enable sensor on you weapon and physics will be disabled so it should no longer feel laggy because there are no more calculation like "can I go there ? Is it solid ?".



But maybe you want to keep your weapon with physics and then comes again my first question: Why the hell ? haha

Link to comment
Share on other sites

Yep, that's it, I may be mistaken sooner (I think I said this.body.sensor=true; and that's wrong).

If you're sure that your body only have one shape (that's often the case) you can just do:

this.body.data.shapes[0].sensor = true; // Enable sensor on the first (and only) shape
Link to comment
Share on other sites

Your body should be Kinematic for it not to move.

The body still react as a normal body but goes through every thing, it doesn't physically collides.


If you have 2 shapes and only one as sensor, the one which is not a sensor will act normally.


Simple example:

I want to create a proximity grenade

I add a sprite to my game

I enable physics.P2 on it

I clear its physical body

I addCircle(5) to the sprite (a little one which fits grenade visual size)

I addCircle(25) to the sprite (a big one which will be the detection range)

I do:

this.body.data.shapes[1].sensor = true;

I do;

this.body.data.shapes[0].collisionGroup = grenadeCollisionGroup.mask;this.body.data.shapes[0].collisionMask = groundCollisionGroup.mask; //It collides with the groundthis.body.data.shapes[1].collisionGroup = detectionCollisionGroup.mask;this.body.data.shapes[1].collisionMask = playerCollisionGroup.mask; //It detects the playerthis.body.onBeginContact.add(callback, this);

And callback here is somethink like:

callback= function(obj) {    if(obj.type="Player"){        boom(); //function that make it explode    }};

I'm not very sure with the callback but you got the idea.


So it should act this way:

You have a grenade, it's physical (the small circle body make it fall and hit the ground). This grenade has a range that is a bigger circle but don't physically collides with anything, BUT it can fire event each time it "hits" something new.

If the hit object is a player, you make is explode.

Link to comment
Share on other sites

I tried but doesn't seems to work. The body is KINEMATIC but does not move with my player with this in update :

this.x = this.hero.x;this.y = this.hero.y + 13;

 So this work but I still get the floating :

this.body.x = this.hero.body.x;this.body.y = this.hero.body.y + 13;

Here is my code :

this.body.clearShapes();this.body.addRectangle(16, 48, 0, -24);this.body.data.shapes[0].sensor = true;this.body.data.shapes[0].collisionGroup = weaponGroup.mask;this.body.data.shapes[0].collisionMask = enemiesGroup.mask;this.body.onBeginContact.add(this.hit, this);
Link to comment
Share on other sites

FWIW https://github.com/schteppe/p2.js/blob/master/src/objects/Body.js#L348-L353

You can just set your p2 body's gravityScale to zero. Easy. :)

This is in p2 0.5.0 / Phaser 2.0.5

EDIT: Just tested, this *does* work.

Make sure you set it on Sprite.body.data as Phaser.Physics.P2.Body does not have a helper for it.

Link to comment
Share on other sites

I'm sorry I have no idea, I thought it wouldn't float at all this way (it shouldn't...).

Try to set the hammer.body.x and y to the hero.x and y (and not the hero.body.x and y), but I don't believe that much in this solution.

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...