Hi, I am learning collision. I am trying to create a top down game. I am using Defold 1.2.179, since my graphic card is too old to support current version.
I set my player as kinematic object and whole wall and ground’s tilemap as static ( Sci-fi Interior tiles | OpenGameArt.org).
I read Platformer Defold tutorial platformer game code. Although ti does not perfectly suits to my need, I think I can use
local function handle_obstacle_contact(self, normal, distance)
-- project the correction vector onto the contact normal
-- (the correction vector is the 0-vector for the first contact point)
local proj = vmath.dot(self.correction, normal)
-- calculate the compensation we need to make for this contact point
local comp = (distance - proj) * normal
-- add it to the correction vector
self.correction = self.correction + comp
-- apply the compensation to the player character
go.set_position(go.get_position() + comp)
-- check if the normal points enough up to consider the player standing on the ground
-- (0.7 is roughly equal to 45 degrees deviation from pure vertical direction)
if normal.y > 0.7 then
self.ground_contact = true
end
-- project the velocity onto the normal
proj = vmath.dot(self.velocity, normal)
-- if the projection is negative, it means that some of the velocity points towards the contact point
if proj < 0 then
-- remove that component in that case
self.velocity = self.velocity - proj * normal
end
end
part (without velocity etc.)
I am using simple movements code :
function handle_movement(self, action_id, action)
if action_id == up then
if action.pressed then
self.active_keys["up"] = true
self.alongVector=vmath.vector3(0,1,0)
--change state to walk/run etc.
self:set_movement((self.toggle_run=="w") and layered.MOVEMENT.WALK or layered.MOVEMENT.RUN)
elseif action.released then
self.active_keys["up"] = nil
check_move_idle(self)
end
elseif action_id == down then
if action.pressed then
self.active_keys["down"] = true
self.alongVector=vmath.vector3(0,-1,0)
--change state to walk/run etc.
self:set_movement((self.toggle_run=="w") and layered.MOVEMENT.WALK or layered.MOVEMENT.RUN)
elseif action.released then
self.active_keys["down"] = nil
check_move_idle(self)
end
elseif action_id == left then
if action.pressed then
self.active_keys["left"] = true
self.alongVector=vmath.vector3(-1,0,0)
--change state to walk/run etc.
self:set_movement((self.toggle_run=="w") and layered.MOVEMENT.WALK or layered.MOVEMENT.RUN)
elseif action.released then
self.active_keys["left"] = nil
check_move_idle(self)
end
elseif action_id == right then
if action.pressed then
self.active_keys["right"] = true
self.alongVector=vmath.vector3(1,0,0)
--change state to walk/run etc.
self:set_movement((self.toggle_run=="w") and layered.MOVEMENT.WALK or layered.MOVEMENT.RUN)
elseif action.released then
self.active_keys["right"] = nil
check_move_idle(self)
end
-- standing state changes
elseif action_id == standup then
if action.pressed then
self.active_keys["standup"] = true
elseif action.released then
self.active_keys["standup"] = nil
end
--else
--handle_menu_requests(self, action_id, action)
end
-- print("move ",self.movement_state, self.move, direction)
end
This is the first scene ( house ) ![]()
In the current state, I have position such that, I have contact with two walls, both at the bottom and at one the left at the same time, no diffusion, just touch. No problem here. But when I press down key, player tries to go down self.alongVector changed to (0,-1,0).
on_message function I got normal vector as (0,-1,0)!
and in here
when I tried to go up, collision with ceil wall gave again normal as (0,-1,0) !
-
why both ceil and botton collisions gave the same normal? because of tilemap - tilesource? How can I distinguish bottom-top collisions? or simply do I need to acc.to my movement code?
-
how can I reconfigure the movement code to in the example tutorial to prevent wall diffusions and stop player when collide with obstable? Thanks.

