I'm having trouble with tilemap collisions (SOLVED)

Hi, I’m new to Defold and I’m making a platform game mixed with shooter. The main character of my game for some reason, is crossing the ground, even with a collision

1 Like

Hi! This might be addressing your issue: https://defold.com/manuals/physics/#resolving-kinematic-collisions

If that doesn’t help, could you provide a minimal project or at least some snippets where you’re having the issues?

2 Likes

So, I did what the tutorial said, but still the character crosses the floor

Player collision

Floor collision

Did you assign collision groups in the .tilesource file?

Yes

When you use a tilesource you can hav multiple collision groups. In your screenshot you have assigned some tiles to the group “default”. The group setting in the collision properties (where you have set “floor”) is ignored and the groups in the tilesource are the ones that are used. Mentioned here:

Check this example:

1 Like

I made it…


And the character still doesn’t detect the collision of the floor

Double check everything, then share your project (exclude build and .git folder) here or directly with me (bjorn@defold.se).

Is there any code to make the character collide with the floor?

Yes, you need code to resolve the collision between the floor and your player. You should have a script attached to the player character with the code required to resolve the collision. That is what Alesis mentioned in his reply to you:

Here is a complete template project for a platformer game in Defold: https://github.com/defold/template-platformer

So, I copied the player’s script and modified it a little:

local air_acceleration_factor = 0.8

local max_speed = 450

local gravity = -1900

local jump_takeoff_speed = 1200

local msg_contact_point_response = hash(“contact_point_response”)

local msg_animation_done = hash(“animation_done”)

local group_obstacle = hash(“floor”)

local input_left = hash(“Left”)

local input_right = hash(“Right”)

local input_jump = hash(“jump”)

local anim_idle = hash(“idle”)

local anim_fall = hash(“fall”)

function init(self)

    msg.post(".", “acquire_input_focus”)

    msg.post(“camera”, “acquire_camera_focus”)

    self.velocity = vmath.vector3(0, 0, 0)

    self.correction = vmath.vector3()

    self.ground_contact = false

    self.anim = nil

end

local function play_animation(self, anim)

    if self.anim ~= anim then

        msg.post("#sprite", “play_animation”, {id = anim})

        self.anim = anim

    end

end

local function update_animations(self)

    sprite.set_hflip("#sprite", self.velocity.x < 0)

    if self.ground_contact then

        if self.velocity.x == 0 then

            play_animation(self, anim_idle)

        else

            play_animation(self, anim_walk)

        end

    else

        if self.velocity.y > 0 then

            play_animation(self, anim_jump)

        else

            play_animation(self, anim_fall)

        end

    end

end

function update(self, dt)

    self.velocity.y = self.velocity.y + gravity * dt

    local pos = go.get_position()

    pos = pos + self.velocity * dt

    go.set_position(pos)

    update_animations(self)

    self.correction = vmath.vector3()

    self.ground_contact = false

    self.wall_contact = false

end

local function handle_obstacle_contact(self, normal, distance)

    if distance > 0 then

        local proj = vmath.project(self.correction, normal * distance)

        if proj < 1 then

            local comp = (distance - distance  proj)  normal

            go.set_position(go.get_position() + comp)

            self.correction = self.correction + comp

        end

    end

    if math.abs(normal.x) > 0.7 then

        self.wall_contact = true

        self.velocity.x = 0

    end

    if normal.y > 0.7 then

        self.ground_contact = true

        self.velocity.y = 0

    end

    if normal.y < -0.7 then

        self.velocity.y = 0

    end

end

function on_message(self, message_id, message, sender)

    if message_id == msg_contact_point_response then

        if message.group == group_obstacle then

            handle_obstacle_contact(self, message.normal, message.distance)

        end

    end

end

local function jump(self)

    if self.ground_contact then

        self.velocity.y = jump_takeoff_speed

        play_animation(self, anim_jump)

        self.ground_contact = false

    end

end

local function abort_jump(self)

    if self.velocity.y > 0 then

        self.velocity.y = self.velocity.y * 0.5

    end

end

local function walk(self, direction)

    if self.ground_contact then

        self.velocity.x = max_speed * direction

    else

        self.velocity.x = max_speed  air_acceleration_factor  direction

    end

end

function on_input(self, action_id, action)

    if action_id == input_left then

        walk(self, -action.value)

    elseif action_id == input_right then

        walk(self, action.value)

    elseif action_id == input_jump then

        if action.pressed then

            jump(self)

        elseif action.released then

            abort_jump(self)

        end

    end

end

Ok, so you got everything working now?

No

Did you try the template project as a whole? And did you compare your project to the template project?

My offer remains to help you if you share a copy of your project.

1 Like

How?

So…

I’m created a GameObject separate and I put the tile map on that GameObject and it worked :smiley:

Could you please specify in more detail what you did? I have this same issue.