From 4c400f53709fe9ffd5e0c9d3daea898e0aa9f413 Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Tue, 12 Jul 2022 15:48:36 +0000 Subject: [PATCH] add bouncing bolts --- src/systems/debug.lua | 2 +- src/systems/physics.lua | 50 +++++++++++++++++++++++++++++++++++------ src/systems/player.lua | 9 ++++---- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/systems/debug.lua b/src/systems/debug.lua index 7952057..b41d1d0 100644 --- a/src/systems/debug.lua +++ b/src/systems/debug.lua @@ -4,7 +4,7 @@ local rgb = require("helpers.rgb") local DRAW_GRID = false local GRID_COLOR = rgb(30, 30, 30) -local DRAW_COLLIDERS = true +local DRAW_COLLIDERS = false local COLLIDER_COLOR = rgb(200, 20, 200) function Debug:drawColliders() diff --git a/src/systems/physics.lua b/src/systems/physics.lua index 1dde92a..34af99b 100644 --- a/src/systems/physics.lua +++ b/src/systems/physics.lua @@ -7,6 +7,9 @@ local Vec = require("lib.brinevector") function Physics:init() self.bump = bump.newWorld() + self.boundCollisionFilter = function(...) + return self:_collisionFilter(...) + end end function Physics:onMapSwitch(map) @@ -33,8 +36,10 @@ function Physics:removeFromGroup(group, e) end end -local function collisionFilter(entity, other) - if entity.vel or other.vel then +function Physics:_collisionFilter(entity, other) + if entity.bolt then + return "bounce" + elseif entity.vel or other.vel then return "slide" end end @@ -43,10 +48,34 @@ function Physics:resolveCollisions(e, dt) local targetPos = e.pos + e.vel * dt local ox = e.collider[1] local oy = e.collider[2] - local x, y = self.bump:move(e, targetPos.x+ox, targetPos.y+oy, collisionFilter) + local x, y, cols = self.bump:move(e, targetPos.x+ox, targetPos.y+oy, self.boundCollisionFilter) - local step = Vec(x-ox, y-oy) - e.pos - e.vel = step / dt + local skip_moving = false + if #cols > 0 then + e.pos.x = x - ox + e.pos.y = y - oy + skip_moving = true + end + + for _, col in ipairs(cols) do + if col.type == "bounce" then + -- sx and sy and just number for flipped the direction when something + -- bounces. + -- When `normal.x` is zero, sx = 1, otherwise sx = -1. Same with sy + local sx = 1 - 2*math.abs(col.normal.x) + local sy = 1 - 2*math.abs(col.normal.y) + + e.vel.x = e.vel.x * sx + e.vel.y = e.vel.y * sy + if e.acc then + e.acc.x = e.acc.x * sx + e.acc.y = e.acc.y * sy + end + skip_moving = true + end + end + + return skip_moving end function Physics:update(dt) @@ -58,11 +87,18 @@ function Physics:update(dt) e.vel = e.vel * (1 - math.min(e.friction, 1)) ^ dt end + local skip_moving = false if self.pool.groups.collider.hasEntity[e] then - self:resolveCollisions(e, dt) + skip_moving = self:resolveCollisions(e, dt) end - e.pos = e.pos + e.vel * dt + if not skip_moving then + if e.max_speed then + e.pos = e.pos + e.vel:trim(e.max_speed) * dt + else + e.pos = e.pos + e.vel * dt + end + end end end diff --git a/src/systems/player.lua b/src/systems/player.lua index d9a542e..327e4c6 100644 --- a/src/systems/player.lua +++ b/src/systems/player.lua @@ -114,9 +114,10 @@ function Player:tryShootinBolt(player) pos = player.pos + player.aim_dir * 30, vel = player.aim_dir * player.bolt_speed, friction = player.bolt_friction, + max_speed = 400, bolt = true, sprite = {}, - collider = {-4, -4, 4, 4} + collider = {-3, -3, 3, 3} } end end @@ -134,10 +135,10 @@ function Player:spawnPlayer() sprite = {}, friction = 0.998, speed = 800, - bolt_count = 1, - bolt_speed = 500, + bolt_count = 10, + bolt_speed = 2000, bolt_cooldown = 0.2, - bolt_friction = 0.9, + bolt_friction = 0.98, collider = {-6, -6, 6, 6} } end