跳转至内容

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
end
lua
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