Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

9 years ago by substandardgaussian

Has any variant of Box2D been modified to work with Impact's directional collision tiles? I have heard that sloped collision tiles now work, and that support should be available for pass-through tiles, but I believe Joncom misread the original post.

As of right now, Joncom's great Box2D Sugar extension does not seem to support directional collision tiles. I'm interested in extending the plugin to support that, though I'd probably fold that into extending the power of Weltmeister for my own project, so it may not be generally useful without the extended WM. Has any work been done thus far on getting directional collision to work in this context?

9 years ago by Joncom

Haha yeah, I did misread the original post. You're right that the plugin does not currently support this. It should be possible though...

http://www.iforce2d.net/b2dtut/one-way-walls

9 years ago by substandardgaussian

Thanks for the link Joncom, I was about to do it with one of the less "correct" methods listed on that page.

After a few hiccups, I've got the solution. I'm certainly willing to share the code, but I have only one question: for some reason, in vanilla Box2D, directional tiles work when disabling the contact in BeginContact (so long as you've commented out automatically re-enabling the contact during Update as in the link), but in your version, trying that appears to do nothing. The only way to make it work is to do it in PreSolve, which, to my understanding, is inefficient because PreSolve is called during every step, while BeginContact only happens once. Since we're not automatically re-enabling contacts anymore, this code belongs in BeginContact, since the call in PreSolve will only accomplish anything one time.

Do you know why the solution in the link doesn't work for your version of Box2D JS in particular? I can't find any place where the contact is re-enabled, yet its status is "true" right as EndContact begins. With vanilla Box2D, everything works just fine.

9 years ago by Joncom

Quote from substandardgaussian
I can't find any place where the contact is re-enabled, yet its status is "true" right as EndContact begins.
I presume you are overloading the entity .beginContact function?

beginContact: function(other, contact) {
    this.parent(other, contact);
    contact.SetEnabled(false);
}

9 years ago by substandardgaussian

Yes, I am. In fact, when that didn't work, I replaced the callback in BeginContact with a single line: "contact.SetEnabled(false)".

That should have resulted in all collisions effectively vanishing and all gravity-affected entities falling through the floor, but it doesn't. It only does that when I move that line to PreSolve.

While we're on the subject, I actually think there's a problem with the asynchronous nature of the callback mechanism. I'm seeing beginContact being called before the init method of the object it is being called on is actually finished: this leads to collisions that shouldn't happen, because the filter data hasn't been set by init() yet. This data is only set in the init method of my core PhysEnt object, which subclasses your Entity class.

Essentially, I have an NPC shooting (spawning) an energy ball in my PC's direction, which then calls beginContact because that ball is touching the entity it spawned from, despite the fact that the ball's init method sets the category bits to ID it as an "enemy" entity, and the mask bits would be set to "PC + Friendly".

Dumping the filter data to the console on beginContact produces:

Object { categoryBits: 1, maskBits: 65535, groupIndex: 0 }

Those are almost certainly the default values.

Later, when that shot eventually hits a wall and beginContact is called again, I see:

Object { categoryBits: 2, maskBits: 5, groupIndex:0 }

which are the values it should have had in the first place (0x0002 = ENEMY, 0x0004 + 0x0001 = FRIENDLY + PC).

I'm not sure that these two issues are related. I don't have a background in environments that use callbacks, so I'm in the dark about the best way to tackle this. A possible solution would be to make a fixture def that includes the filter data right away, and attach that fixture to the body right from the start, instead of generating a body/fixture first and modifying the filter data on the fly. That would require modifying the code in your library to take the filter data as input, so I'd like to suggest that as an update.

9 years ago by Joncom

I'm seeing beginContact being called before the init method of the object it is being called on is actually finished
I put a console.log at the end of my entity init function and at the start of its beginContact function, but can't seem to reproduce this. Are you able to upload a ZIP file containing an example which demonstrates how BeginContact is being invoked before your entity init function finishes?

9 years ago by substandardgaussian

[Link removed because it contained licensed ImpactJS files.]

That's a hastily modified version of the "Resident Raver" sample game from Jesse Freeman's "HTML5 Games with ImpactJS". The vast majority of it doesn't work properly, but of note, the "EntityBullet" object that is @ player.js:198 has its maskBits set to 0x0000, which it sets in init, so it should never collide with anything through Box2D's system, period.

However, the very first thing that happens is the bullet collides with the player entity (and kills you). The bullet logs to console whenever its beginContact is called: you'll note the cat and mask bits are wrong (and the fact that it is called at all).

If you want, you can swap the maskBits (player.js:207-209) and uncomment the expression that makes the bullet avoid damaging the player (player.js:238) to see how it functions when it hits the zombie. You'll note that it reports the appropriate category and mask bits when it hits the zombie later.

Essentially, there's a race condition. ig.world can perform a step in between getting the body from Entity.createBody and when I alter the filter data in init. That actually happening might be system-specific. I can just tell you that it happens to me on the exact code that I'm sharing with you.

EDIT: Just realized I uploaded something bugged (in-line comment failed to capture a hanging "&&"), here's an updated rar:

[Link removed because it contained licensed ImpactJS files.]

9 years ago by Joncom

Quote from substandardgaussian
Essentially, there's a race condition. ig.world can perform a step in between getting the body from Entity.createBody and when I alter the filter data in init. That actually happening might be system-specific. I can just tell you that it happens to me on the exact code that I'm sharing with you.
This line may be the culprit. The body is created and then a timestep of 0 seconds occurs to establish contacts so that the entity is fully aware of his environment.

Yeah, it would probably make sense for the setting of the mask-bits to come before that timestep...

Edit: I updated the plugin. All entities now contain an initBody function which is called after the body is created, but before the 0 second timestep. You should be able to avoid this issue like this:

initBody: function() {
    this.parent();
    /* set mask-bits and/or category-bits here */
}

9 years ago by substandardgaussian

Ah, yes, I missed that there's a step inside the init function. That would do it right there. Thanks for listening!
Page 1 of 1
« first « previous next › last »