From d4f1856d357de241320dd6cbf66972c74784c309 Mon Sep 17 00:00:00 2001 From: ne_mene Date: Thu, 12 Mar 2026 19:56:43 +0100 Subject: hopefully this was a good change --- src/phys.lua | 154 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 77 insertions(+), 77 deletions(-) (limited to 'src/phys.lua') diff --git a/src/phys.lua b/src/phys.lua index 8c4455c..3cddd4e 100644 --- a/src/phys.lua +++ b/src/phys.lua @@ -17,18 +17,10 @@ world.layers = {} -- -- You can use whatever physics layer you want, but these are the standard ones -local function aabb_x(ax, aw, bx, bw) - return ax < bx + bw and bx < ax + aw -end - -local function aabb_y(ay, ah, by, bh) - return ay < by + bh and by < ay + ah -end - local function aabb(ax, ay, aw, ah, bx, by, bw, bh) return - ax < bx + bw and bx < ax + aw and - ay < by + bh and by < ay + ah + ax < bx + bw and bx < ax + aw and + ay < by + bh and by < ay + ah end local function add_box_to_layers(box) @@ -44,9 +36,9 @@ phys.Box = {} phys.Box.__index = phys.Box function phys.Box.new( - x, y, - width, height, - opts + x, y, + width, height, + opts ) opts = opts or {} @@ -61,99 +53,107 @@ function phys.Box.new( self.width = width self.height = height - self.layers = opts.layers or {"hard"} + self.layers = opts.layers or { "hard" } self.mask = opts.mask or {} - self.touching_down = false - self.touching_up = false - self.touching_vertically = false - self.touching_left = false - self.touching_right = false - self.touching_horizontally = false + self.touchx = 0 + self.touchy = 0 add_box_to_layers(self) return self end -function phys.Box:get_rect() - return - self.x + self.offsetx, - self.y + self.offsety, - self.width, - self.height +function phys.Box:touching_left() + return self.touchx < 0 end -function phys.Box:update(velx, vely, dt) - local resx = self.x + velx * dt - local resy = self.y + vely * dt +function phys.Box:touching_right() + return self.touchx > 0 +end - local small_side = math.min(self.width, self.height) - local steps = math.ceil(vec_len(velx * dt, vely * dt) / small_side) +function phys.Box:touching_horizontal() + return self.touchx ~= 0 +end - self.touching_down = false - self.touching_up = false - self.touching_vertically = false - self.touching_left = false - self.touching_right = false - self.touching_horizontally = false +function phys.Box:touching_up() + return self.touchy < 0 +end - -- this block is fat. much like a certain croatian... - for i=1, steps do - local p = i / steps +function phys.Box:touching_down() + return self.touchy > 0 +end - local boxx = resx + self.offsetx + velx * dt * p - local boxy = resy + self.offsety + vely * dt * p +function phys.Box:touching_vertical() + return self.touchy ~= 0 +end - for _, layer in ipairs(self.mask) do - for _, other in ipairs(world.layers[layer] or {}) do - if other ~= self then - local ox = other.x + other.offsetx - local oy = other.y + other.offsety +function phys.Box:touching() + return self.touchx ~= 0 and self.touchy ~= 0 +end - if aabb( - boxx, boxy, self.width, self.height, - ox, oy, other.width, other.height +function phys.Box:get_rect() + return + self.x + self.offsetx, + self.y + self.offsety, + self.width, + self.height +end + +function collision_check(box) + local box_x, box_y, box_width, box_height = box:get_rect() + local other_x, other_y, other_width, other_height + + for _, layer in ipairs(box.mask) do + for _, other in ipairs(world.layers[layer] or {}) do + if other == box then + goto continue + end + other_x, other_y, other_width, other_height = other:get_rect() + + if aabb( + box_x, box_y, box_width, box_height, + other_x, other_y, other_width, other_height ) then - if aabb_x(self.x + self.offsetx, self.width, ox, other.width) then - if vely > 0 then - resy = oy - self.height - self.offsety - self.touching_down = true - else - resy = oy + other.height - self.offsety - self.touching_up = true - end - self.touching_vertically = true - elseif aabb_y(self.y + self.offsety, self.height, oy, other.height) then - if velx > 0 then - resx = ox - self.width - self.offsetx - self.touching_left = true - else - resx = ox + other.width - self.offsetx - self.touching_right = true - end - self.touching_horizontally = true - end - end - end + return true end + ::continue:: end + end + return false +end - if self.touching_horizontally then +function phys.Box:update(velx, vely, dt) + local small_side = math.min(self.width, self.height) + local steps = math.ceil(vec_len(velx * dt, vely * dt) / small_side) + + -- this block is fat. much like a certain croatian... + -- not anymore :D + for i = 1, steps do + local p = i / steps + local before + + before = self.x + self.x = self.x + velx * dt * p + if collision_check(self) then + self.touchx = velx > 0 and 1 or -1 velx = 0 + self.x = before end - if self.touching_vertically then + + before = self.y + self.y = self.y + vely * dt * p + if collision_check(self) then + self.touchy = velx > 0 and 1 or -1 vely = 0 + self.y = before end - if self.touching_horizontally or self.touching_vertically then + if self:touching() then break end end - self.x = resx - self.y = resy - return velx, vely end -- cgit v1.3-2-g0d8e