Smoother gameplay / steering player without stuck at collisions

Hey there.

I am moving a character (player) on a tilemap. The tilemap has collisions.
If the player runs around/near a corner he’ll stuck.

Does anyone has an idea how to solve this or how to do it better?

Game can be tested here: (Use F9 for the physics debug)
http://foodrescue.trinium.de

Here are some code-snippets how the input and movement works:

  • the tilemap is a simple tilemap with 2 layers - a background and a front with some furnitures etc. Nearly all tiles have a collision set up in the tileset.
    Here is a screenshot of the game with physics debug: the player is stuck at the corner

fr collisions

    -- set posi
    self.pos = go.get_position()
    local newpos = self.pos + self.paul.movedirection * self.paul.movespeed * dt
  • input:
function on_input(self, action_id, action)
  if GLOBAL.GAMESTATE == GLOBAL.GAMESTATE_PLAY then

    if action.pressed then
      if action_id == hash("KEY_LSHIFT") then
        self.paul.movespeed = self.paul.walkspeed + self.paul.runspeed
      elseif action_id == hash("KEY_UP") then
        self.paul.movedirection.y = 1
        msg.post("#sprite", "play_animation", {id = hash(self.paulstate[self.paul.state]["walk"])})
      elseif action_id == hash("KEY_DOWN") then
        self.paul.movedirection.y = -1
        msg.post("#sprite", "play_animation", {id = hash(self.paulstate[self.paul.state]["walk"])})
      elseif action_id == hash("KEY_LEFT") then
        self.paul.movedirection.x = -1
        msg.post("#sprite", "play_animation", {id = hash(self.paulstate[self.paul.state]["walk"])})
      elseif action_id == hash("KEY_RIGHT") then
        self.paul.movedirection.x = 1
        msg.post("#sprite", "play_animation", {id = hash(self.paulstate[self.paul.state]["walk"])})
      end

    elseif action.released then

      if action_id == hash("KEY_LSHIFT") then
        self.paul.movespeed = self.paul.walkspeed
      elseif action_id == hash("KEY_UP") then
        self.paul.movedirection.y = 0
      elseif action_id == hash("KEY_DOWN") then
        self.paul.movedirection.y = 0
      elseif action_id == hash("KEY_LEFT") then
        self.paul.movedirection.x = 0
      elseif action_id == hash("KEY_RIGHT") then
        self.paul.movedirection.x = 0
      elseif action_id == hash("KEY_ESC") then
        msg.post("main:/gamecontrol#script", "gameover")
      elseif action_id == hash("KEY_F9") then
        msg.post("@system:", "toggle_physics_debug")
      elseif action_id == hash("KEY_F10") then
        msg.post("@system:", "toggle_profile")
      end
      if self.paul.movedirection.x == 0 and self.paul.movedirection.y == 0 then
        msg.post("#sprite", "play_animation", {id = hash(self.paulstate[self.paul.state]["idle"])})
      end
    end
  end
end
  • the collision is working like this (maybe a better way?):
if message_id == hash("collision_response") then
      --print("Paul colliding with " .. message.group .. " id " .. message.other_id)
      if message.group == hash("wall") or message.group == hash("furniture") or message.group == hash("trigger_furniture") then
        self.paul.movedirection.x = 0
        self.paul.movedirection.y = 0
      end

I already thought about raycasts, but this would just be a “early warning”.

How to make it more smooth and a better gameplaying? Getting stuck all the time is a mess :frowning:

Tilemap collision data is bugged (and reported a while ago). You can tell in your pic the corner should be straight but it is curved instead.

2017-09-18 17_16_04-Smoother gameplay _ steering player without stuck at collisions - General - Defo

3 Likes

Yes, there are issues with tilemap collisions, but from what I can tell of the code above @stephenkalisch is not resolving the collision properly.

@stephenkalisch: Since you are using kinematic physics you need to manually separate the two colliding objects. In this case the player is the one that should be separated out and away from the tilemap. This is discussed in the platformer tutorial and the runner tutorial (see handle_geometry_contact).

2 Likes

There is also a section in the physics manual that goes into resolving collisions in detail: https://www.defold.com/manuals/physics/#_resolving_kinematic_collisions

2 Likes

Thanks to all of you for your answers. I’ve saw this in the past but didnt remember.

Guess I have to take a closer look to this :roll_eyes: