10. Collision,Strength,推箱子
3.6,周五,结束教程,搬运了另一个 BYTEPATH 的教程。
推箱子
lua
function love.update(dt)
for _, v in ipairs(objects) do
v:update(dt)
end
local loop = true
local limit = 0
while loop do
loop = false
limit = limit + 1
if limit > 100 then
break
end
for i = 1, #objects - 1 do
for j = i + 1, #objects do
local collision = objects[i]:resolveCollision(objects[j])
if collision then
loop = true
end
end
end
end
endlua
function Entity:update()
self.last.x = self.x
self.last.y = self.y
self.tempStrength = self.strength
end
function Entity:draw()
love.graphics.draw(self.image, self.x, self.y)
end
function Entity:checkCollision(e)
return self.x < e.x + e.width and
self.x + self.width > e.x and
self.y < e.y + e.height and
self.y + self.height > e.y
end
-- y 对齐,横向撞的
function Entity:wasVerticallyAligned(e)
return self.last.y < e.last.y + e.height and
self.last.y + self.height > e.last.y
end
-- x 对齐,竖向撞的
function Entity:wasHorizontallyAligned(e)
return self.last.x < e.last.x + e.width and
self.last.x + self.width > e.last.x
end
function Entity:resolveCollision(e)
if self.tempStrength > e.tempStrength then
return e:resolveCollision(self)
end
if self:checkCollision(e) then
self.tempStrength = e.tempStrength
if self:wasVerticallyAligned(e) then
-- self 中心在 e 中心的左边,说明 self 是从左边撞上去的
if self.x + self.width / 2 < e.x + e.width / 2 then
local pushback = self.x + self.width - e.x
self.x = self.x - pushback
else
local pushback = e.x + e.width - self.x
self.x = self.x + pushback
end
elseif self:wasHorizontallyAligned(e) then
if self.y + self.height / 2 < e.y + e.height / 2 then
local pushback = self.y + self.height - e.y
self.y = self.y - pushback
else
local pushback = e.y + e.height - self.y
self.y = self.y + pushback
end
end
return true
end
return false
end