Collision detection

Hi everyone,

About the collision detection and position corretion. I have always to do the vectors math for that? There is not a automatic collision detection like other engines?

The collision system uses Box2D and there are many different kinds of collisions objects you can use. The documentation will describe these in more details:

  • Static objects - does not react to collisions themselves but other objects will. Use for level geometry (platforms, walls etc)
  • Dynamic objects - collides with other objects and solves all collisions automatically. Control them by applying forces.
  • Kinematic objects - collides with other objects but you will have to resolve collisions yourself
  • Triggers - simple collisions that can be used to determine when an object reaches a specific spot

So, as you can see, dynamic objects will behave realistically and handle all collisions automatically. When it comes to kinematic objects then yes, you need to handle collisions yourself. I think one of the sample projects (the platformer) does this. I encourage you or someone else to put this code into either a community shared Defold library project or as a Github project so that people can improve upon and use such a kinematic collision resolver module in their own projects.

2 Likes

I’m having a little trouble understanding dynamic vs kinematic:

I have a top-down game so I have created static collisions for the walls with the group “wall” and mask “player”. Technically, the player object is fenced in by the collision objects. The player object as of right now as the Kinematic collision to it with the group “player” and the mask “wall” so I have the relationship set up right.

However, I added a script to my player character (right from the tutorial level) and it doesn’t do anything

   function on_message(self, message_id, message, sender)
        if message_id == hash("contact_point_response") then
            if message.group == hash("wall") then
                handle_geometry_contact(self, message.normal, message.distance)
            end
        end
    end

I then get this error which is what I don’t understand. In the tutorial level, that section of the script I posted above was the only script that corresponded to collision. Tutorial level had gravity take effect but in this case I don’t want that I’d like full control of my player but have boundaries.

ERROR:SCRIPT: main/script/player.script:47: attempt to call global ‘handle_geometry_contact’ (a nil value)
stack traceback:
main/script/player.script:47: in function <main/script/player.script:43>

When I switch to dynamic, my character just falls down until he hits the bottom collision and I cant assume control. Any thoughts? I can drop my full code if you’d like me to. Thanks

Do you have the handle_geometry_contact function declared in your project? This is a function that was part of the runner game in the hero.script and explained in the tutorial.

If your collision object is kinematic it is up to you as a developer to decide what should happen when the collision is detected. Do you want the object to bounce? Do you want the object to die? Should it stop? Should push the colliding object? Read more in the physics manual in the section Resolving Kinematic Collisions.

A super basic way that is correct most of the time is to do this:

if message_id == hash("contact_point_response") and message.group == hash("wall") then
    go.set_position(go.get_position() + message.normal * message.distance)
end

It will not work well when colliding with multiple objects in a single frame. That’s where the handle_geometry_contact and the correction vector is better.

Dynamic collision objects are completely at the mercy of the physics engine. You can not manually set the position. The only way you can control it is through applied forces.

Well for the walls in this case, I’d like it to stop the user from going further. For when the object dies, I was thinking of adding a trigger collision that would trigger the death? Feels like that’s the best way to go right?

I added this and this is what I got. The goat cannot go any more towards the left or bottom (the left is what I want, the bottom not so much) and can go a little above the fence above.

and here is my collision map

keep in mind the “object” in this case is the tilemap and everything you see on the map above (not counting the humans) is part of the tilemap and not a real “object” maybe that is affecting it?
tilemap

It’s hard to help you debug without the code. It could be that it should be a minus sign instead of a plus:

go.set_position(go.get_position() - message.normal * message.distance)

Feel free to share the project with me (bjorn.ritzl@king.com) and I can take a look.

thx guys helped a ton