Games [XUI2D] To Collide or Not To Collide

Discussion in 'Game Development' started by Erel, Sep 12, 2018.

  1. Erel

    Erel Administrator Staff Member Licensed User

    [​IMG]

    The purpose of this example is to demonstrate the usage of mask bits and category bits properties.

    Collision rules:

    - Collisions happen between dynamic bodies and other bodies (including other dynamic bodies).
    - The collisions actually happen between two fixtures of two bodies. Bodies can have multiple fixtures with different properties.
    - If a fixture is set to be a sensor (is sensor property) then the collision will be detected but there will not be a physical collision.

    Now for mask bits and category bits. The formal rule sounds a bit complicated so we will start with an example.
    The default mask bits is 65535 (0xFFFF).
    0xFFFF in base 2 is 1111 1111 1111 1111.
    Category bits should be a power of 2. This means that it is a number with a single high (1) bit. The default value is 1.

    If the same bit is high in both the mask bits and the category bits then we have a collision.

    In our example the second ground body mask bits value is 0 = 0000 0000 0000 0000. This means that it will never collide with other bodies. It is better to set the mask bits to 0 than using a sensor unless you are actually interested in detecting the collision.

    The third ground body mask bits value is 65529 = 0xFFFF - 4 - 2 = 1111 1111 1111 1001
    This means that it will collide with all bodies except bodies with category bits of 2 (10) or 4 (100).

    The formal rule is:
    For a collision to happen: (FixtureA.MaskBits & FixtureB.CategoryBits) <> 0 AND (FixtureA.CategoryBits & FixtureB.MaskBits) <> 0.
    & - bitwise and.

    Note that you can change the filter bits at runtime:
    Code:
    bw.Body.FirstFixture.SetFilterBits(00)
    The above code is from Mario example. When Mario is hit we want to let Mario fall out of the screen.

    There are two ways to detect collisions:
    1. Call Body.GetContactList to get the current contacts. In most cases you will want to pass True for the TouchingOnly parameter. The items in the list returned are B2Contact items.

    2. Handle the world contact events: BeginContact, PreSolve, PostSolve and EndContact. Note that PreSolve and PostSolve are not called for sensors.
    The events are a bit more complicated to handle but are more powerful as they allow you to modify the contact behavior and they also include more information about the contact. See the walking character example.
    The world is "locked" during these events. Don't add or destroy anything during these events. You can use X2.AddFutureTask to run something after the events complete.
    Nice tutorial about box2d collisions: http://www.iforce2d.net/b2dtut/collision-anatomy

    The example is included in the examples pack: https://www.b4x.com/android/forum/threads/xui2d-example-pack.96454/
     
    Last edited: Sep 12, 2018
  2. Peter Simpson

    Peter Simpson Expert Licensed User

    I had to read this 3 times, now it's time to make a cuppa tea, and then I'll read it again.

    Thank you for the info @Erel...
     
    Last edited: Sep 12, 2018
    Toky Olivier likes this.
  3. Erel

    Erel Administrator Staff Member Licensed User

    Run the project. Reading is not enough...
     
    tufanv likes this.
  4. inakigarm

    inakigarm Well-Known Member Licensed User

    Thanks for this example !; I was thinking to open a Post asking for this (I had read http://www.iforce2d.net/b2dtut/collision-filtering but didn't understand well)
     
  5. CaStar

    CaStar Member Licensed User

    Thanks for this. Is it possible to make an item passing a bar from one side but not from the other?
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    Yes. It is more complicated. You can see an example of it in the walking character example.

    [​IMG]

    The important code is in World_PreSolve sub.
     
  7. Gunther

    Gunther Active Member Licensed User

    Hello,

    Here a small (= more easy) example in a World_PreSolve sub where it is checked 1) if 'ball' is in contact and 2) if it is with 'coin'
    If so, then the contact is disabled - means they will not collide.

    'ball' and 'coin' are X2BodyWrapper.

    Your task is in the if ...then to check if the item you deal with is on the one or other side of the other item.
    According to that check set the "Contact.IsEnabled = False" or not.
    Code:
    Private Sub World_PreSolve (Contact As B2Contact, OldManifold As B2Manifold)
        
    '
        Dim bodies As X2BodiesFromContact = X2.GetBodiesFromContact(Contact"ball")
        
    If bodies = Null Then Return ' noone is in contact with 'ball'
        '
        'yes, the ball has contacts
        If bodies.OtherBody.Name = "coin" Then ' but is it 'coin' ?
            'yes, therefore ignore the collision if the ball
            Contact.IsEnabled = False
        
    End If
       
    '
    End Sub
     
    Last edited: Jan 25, 2019
  8. Erel

    Erel Administrator Staff Member Licensed User

    This case is simpler and can be solved using the mask bits demonstrated in the first post.
     
  9. Gunther

    Gunther Active Member Licensed User

    True 100%, but the focus is on:
    ;)
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice