If you take 2 objects and let’s say the first object will have a dynamic collision and the second will have a static collision. If you accelerate a dynamic object to a certain speed and higher, then the dynamic object will pass through the static object.
how i can fix it?
What you’re describing is the problem of continuous collision detection. In order to fix objects tunneling through other objects due to high velocities, we usually take the lazy (AKA more productive) way out and implement a max_speed
value, then clamp an object’s velocity below max_speed
so that tunneling never occurs.
Defold does not provide an out-of-the-box solution to this problem.
Thanks, I just thought of one idea. We find out the direction of movement of the object and create a ray to the point that will be in the next frame, and if something is in the path of the ray, then this means that at this point we have to bounce off the object. Tomorrow I’ll try to implement it, but I don’t quite understand how to implement collision with an object, let’s say if our restitution is 1, then nothing prevents us from simply changing the direction of movement, but what if we have a different value. I don’t really want to write collision physics
If you don’t want to cap the max velocity, rays are the way to go. You don’t need to resolve the collision yourself. Move the body to the ray intersect point and let Box2D handle it.
You may need to read linear_velocity and angular_velocity before and set it after you move it. You may also want to disable the collision object of the dynamic body before you move it and enable it afterwards.
Thanks!
it works, but not always. I set high speed values just for demonstration, in the game this speed will not be
Also on the gif you can see what is not visible on the monitor. The moment when the ball bounces off the snake is not visible on the monitor, for me it was displayed as the ball goes through the snake
with raycast:
without raycast:
code:
local prevX, prevY
local myX, myY
local nextX, nextY;
function update(self, dt)
myX = go.get_world_position().x
myY = go.get_world_position().y
if(prevX ~= nil)then
local nX = (myX - prevX)
local nY = (myY - prevY)
nextX = nX*1.5+myX
nextY = nY*1.5+myY
local nextFrPos = vmath.vector3(nX+myX,nY+myY,0)
local result = physics.raycast(go.get_position(), vmath.vector3(nextX,nextY,0), {hash("default")})
msg.post("@render:", "draw_line", { start_point = go.get_position(), end_point = vmath.vector3(nextX,nextY,0), color = vmath.vector4(1,0,0,1) })
if(result)then
if(math.abs(nextFrPos.x - result.position.x)<math.abs(nextX) and math.abs(nextFrPos.y - result.position.y)<math.abs(nextY))then
go.set_position(result.position)
end
end
end
prevX = myX
prevY = myY
end
guys, I will be grateful for any improvement of the code)