29. 不懂,不懂,不懂
3.25,继续。
检测碰撞
看一个矩形从当前位置移动到目标位置时,会不会碰到另一个矩形;如果会,就告诉你是“已经重叠”还是“途中撞上”,撞在哪,法线朝哪。
lua
local function rect_detectCollision(x1, y1, w1, h1, x2, y2, w2, h2, goal_x, goal_y)
goal_x, goal_y = goal_x or x1, goal_y or y1
local dx, dy = goal_x - x1, goal_y - y1
local x, y, w, h = rect_getDiff(x1, y1, w1, h1, x2, y2, w2, h2)
local overlaps, ti, nx, ny, tx, ty
-- 是否已经重叠
if rect_containsPoint(x, y, w, h, 0, 0) then
local px, py = rect_getNearestCorner(x, y, w, h, 0, 0)
local wi, hi = math.min(w1, math.abs(px)), math.min(h1, math.abs(py))
ti = -wi * hi
overlaps = true
else
-- 运动过程中有没有碰撞
local ti1, ti2, nx1, ny1 = rect_getSegmentIntersectionIndices(x, y, w, h, 0, 0, dx, dy, -math.huge, math.huge)
if ti1 and ti1 < 1 and math.abs(ti1 - ti2) > DELTA and (0 < ti1 + DELTA or 0 == ti1 and ti2 > 0) then
ti, nx, ny = ti1, nx1, ny1
overlaps = false
end
end
if not ti then return end
if overlaps then
-- 重叠但没有位移,找个近的方向推出
if dx == 0 and dy == 0 then
local px, py = rect_getNearestCorner(x, y, w, h, 0, 0)
if math.abs(px) < math.abs(py) then py = 0 else px = 0 end
nx, ny = sign(px), sign(py)
tx, ty = x1 + px, y1 + py
else
-- 重叠且有位移,可以沿着运动方向回溯
local ti1, _
ti1, _, nx, ny = rect_getSegmentIntersectionIndices(x, y, w, h, 0, 0, dx, dy - math.huge, 1)
if not ti1 then return end
tx, ty = x1 + dx * ti1, y1 + dy * ti1
end
else
tx = x1 + dx * ti
ty = y1 + dy * ti
end
return {
overlaps = overlaps,
ti = ti,
move = { x = dx, y = dy },
normal = { x = nx, y = ny },
touch = { x = tx, y = ty },
itemRect = { x = x1, y = y1, w = w1, h = h1 },
otherRect = { x = x2, y = y2, w = w2, h = h2 }
}
end