diff options
| author | ne_mene <[email protected]> | 2026-03-12 19:56:43 +0100 |
|---|---|---|
| committer | ne_mene <[email protected]> | 2026-03-12 19:56:43 +0100 |
| commit | d4f1856d357de241320dd6cbf66972c74784c309 (patch) | |
| tree | ef6fd2b6ea7e58bcfc9ca4d9b48469ede9c59bc9 | |
| parent | 8b9f468ffaa169788d1488d2640d2e0e49bb50f3 (diff) | |
hopefully this was a good change
| -rw-r--r-- | main.lua | 11 | ||||
| -rw-r--r-- | src/objs/player.lua | 1 | ||||
| -rw-r--r-- | src/phys.lua | 154 |
3 files changed, 82 insertions, 84 deletions
@@ -13,12 +13,7 @@ function love.load() event_bind(scn.on_draw, "Tilemap", tilemap_draw_sys) set_scene(scn) - new_player(100, 100) - - box1 = phys.Box.new(20, 20, 16, 16, { - layers = {}, - mask = { "hard" }, - }) + player = new_player(100, 100) ground1 = phys.Box.new(5, 50, 64, 16, {}) ground2 = phys.Box.new(64 - 16, 50 + 16, 16, 64, {}) @@ -34,7 +29,6 @@ function love.update(dt) assert(scn, "No scene set.") fire_event(scn.on_update, dt) - box1:update(0, 5, dt) flush_scene() end @@ -47,6 +41,9 @@ function love.draw(dt) assert(scn, "No scene set.") fire_event(scn.on_draw, dt) + ground1:draw() + ground2:draw() + player.box:draw() -- TODO: Take care of weird displays lg.setCanvas() diff --git a/src/objs/player.lua b/src/objs/player.lua index 31df42e..bc71ea7 100644 --- a/src/objs/player.lua +++ b/src/objs/player.lua @@ -49,5 +49,6 @@ function new_player(x, y) }) add_comp(ent, "Player") add_comp(ent, "Sprite", "res/img/player.ase") + return ent end 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 |
