Tilde

p2 collision WITHOUT physics

Recommended Posts

There's so little documentation about phaser.p2 online, so crossing over from Arcade has been tricky for me. The thing is, I don't wish for my game to have physics. My top-down, free-roaming space shooter game only needs the rotating collision boxes that p2 allows for. I'm trying to turn the physics OFF altogether while still using the standard collision checks that make Phaser so easy to use. And while the P2 Examples page is helpful and fascinating, I can't quite seem to find what I'm looking for on it.

 

So since I got this working with Arcade, let's say I have a group of shotPowerups on the field, and touching a member of the group with the player would collect the powerup and destroy it. And obviously, I don't want the ship and the powerups knocking each other around like silly. They shouldn't have any physical interaction. I'd be trying to accomplish this:

 

if (this.checkOverlap(player, shotPowerupGroup))        collectShotPowerup(player, the...shot inside shotPowerupGroup?)

I got this working with Arcade using this line:

game.physics.arcade.overlap(player, shotPowerupGroup, this.collectShotPowerup, null, this);

When the player touches a member of the shotPowerupGroup, it collects that powerup, since this method automatically pulls the appropriate member from shotPowerupGroup. Well, the ship, what with having a non-AABB hitbox, no longer has an Arcade body. So I can't use this anymore.

 

In the following thread, Rich says that if all you're looking for is collision without any sort of physics system, Phaser.Rectangle.intersects alone can check for that.

 

http://www.html5gamedevs.com/topic/1974-using-collision-detection-without-physics/

 

But that seems to only account for AABB hitboxes. And without enabling a P2 body for my ship, giving it the physics I don't want it to have, I can't modify values like player.body.angle.

 

I know about the "collision event" function in p2, as shown here,

 

https://phaser.io/examples/v2/p2-physics/contact-events

 

but I don't think it directly correlates to what I'm trying to accomplish. Or does it? I'm pretty clueless at this point. I've seen other examples say that "phaser.physics.collide" is a thing, but it's not. Neither is "phaser.physics.p2.overlap".

 

All of this also has me looking for P2 equivalents for Arcade functions I've already used, like "velocityFromAngle" and stuff like that. Unless I can just freely pull them from Arcade and copy them into my code, but I don't much trust myself for that.

Share this post


Link to post
Share on other sites

Easiest way would probably be to make everything sensors.

 

 

Or you can try and disable all contact events before they are applied, in a function called "onPresolve" in your Game state. Like so:

 

onPresolve : function (presolve) {            for (var i = 0; i < presolve.contactEquations.length; i++) {               presolve.contactEquations[i].enabled = false;                    }},

 

I don't recommend doing that unless you are not getting the information you need when everything is a sensor (iirc, some things will not be calculated for sensors...)

Share this post


Link to post
Share on other sites

I'm not familiar with sensors. Setting body.sensor = true on a sprite doesn't seem to work, and I don't know how to pass this into a collision check like I've outlined above. Sorry, but can someone please explain this to me?

Share this post


Link to post
Share on other sites

A sensor is a physics body that has no collision response, but still triggers collision events.

 

Just as an example, you can set your powerup's body to be a sensor, so you don't have to worry about it knocking anything around, but you can still make it "collide" with the player's ship so it triggers a callback that causes the ship to pick it up.

 

So you still need to make use of P2's tools, like creating collision groups and setting callbacks, it just doesn't do anything other than report on the "collision".

Share this post


Link to post
Share on other sites

The only thing with "sensor" that I can find in Phaser Chains ( http://phaserchains.boniatillo.com/ ) is Phaser.Physics.P2.FixtureList.SetSensor. But it works by key rather than by object, so I'm not sure if it handles the same thing you're talking about. There is a Sprite.body.sensor property, but it looks like it's only in Box2D, not P2.

Share this post


Link to post
Share on other sites

Ohhhh, okay! Sorry myself for misunderstanding. So if I get this, what I want to do is NOT do game.physics.startSystem(Phaser.Physics.P2JS);, and for each of my objects, use Phaser.Physics.P2.Body.addFixture(fixtureData)?

fixtureData is apparently a string, and I'm not sure how it's formatted, there's no info on it anywhere...

Share this post


Link to post
Share on other sites

You DO want to use physics.startSystem, that's what gets the ball rolling on the physics systems so they work.

 

You'll need to start P2 and use p2.enable on your sprites as normal, because they still need to have bodies. There are actually a few ways to deal with sensors, the easiest is probably to go ahead and add shapes to your body like you normally would, except store the shape (almost all of the shape-adding functions return the shape they added) and just set shape.sensor to true.

 

Or if you just want to make sure entire bodies are sensors, just call a function that iterates over the body.shapes array and sets all the sensors that way.

 

I don't know why fixtureData is a string in the documentation, it's accessed like a normal object in the code. fixtureData contains a lot of information and using it is mostly internal, you probably don't need to deal with it unless you're doing something very special.

 

Basically, everything is exactly the same except you need to take a moment to set the shape's sensor property. That's it: the shapes won't cause physical collisions anymore, but they will still trigger collision callbacks so you can detect touching them.

Share this post


Link to post
Share on other sites

That's awesome, thank you so much. I think I'll be able to figure it out thanks to your outline. I have just one more question. Maybe you've already addressed this and it's just gone over my head, but is there a p2 equivalent for the following function, as defined in the first post?

game.physics.arcade.overlap(player, shotPowerupGroup, this.collectShotPowerup, null, this);

Because it's one thing to say "if these two things overlap, call this function". It's another to say "if these two things overlap, call this function using the specific two objects out of each group as parameters".

Share this post


Link to post
Share on other sites

Eh, kind of. Every function that sets a callback also generally lets you set a callbackContext (sometimes called listenerContext), which lets you define what the this variable will be when your callback is called. You can use that to construct an object that has all the information you need during the callback.

 

Also, I just wanted to clarify something, because I think I steered you wrong: Sensors will NOT trigger collision callbacks! What they WILL do is trigger contact events which send signals, such as "onBeginContact" and "onEndContact". I believe you still need to set up your collision groups so the bodies know what they should have contacts with.

 

The end result is basically the same (you can probably find some cases where they aren't), though the actual code ends up being a little different. You'll need to set a callback that is called when, for example, "onBeginContact" is triggered. You can look at the Phaser.Signal documentation to see how to use it.

 

I think it's done this way because sensors, being non-interactive, would end up triggering collision callbacks every single frame, so instead they only trigger the signals when a contact begins and ends. You can set up whatever you need when those signals get sent.

Share this post


Link to post
Share on other sites

I've started implementing this system, and it's going surprisingly well. I have another question for anyone that happens to be around, since this will shape my game in the future.

 

When it comes to physics functionalities, I do want hard collisions against, say, walls and the world boundaries, without having to code all that myself. That's why I'm using phaser. But is it possible to have it both ways? If I'm setting the body to a sensor shape that can't be thrown around by other entities, can I still use p2's collision exclusion somehow? Right now I'm freely walking through the world boundaries.

Share this post


Link to post
Share on other sites

Absolutely. Being a sensor is a property of a single shape, not a whole body. You can create a body and add more than 1 shape to it, so the sensors don't collide with anything but the non-sensor shapes do.

 

But it sounds like you want your body to collide against certain things, but not others. This is actually built into P2's collision groups. Make sure every body you make sets its collision group, and control which groups collide with what by using the collides method. There's a special variable for colliding with the world bounds (body.collideWorldBounds).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.