[library] bump.lua v3.1.4 - Collision Detection

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
Nuthen224
Citizen
Posts: 50
Joined: Sun Jul 28, 2013 9:40 pm

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by Nuthen224 » Sun Aug 13, 2017 3:59 pm

@g0r1ll4 Bounce is very important! I recommend looking at the image found here. https://raw.githubusercontent.com/kikit ... bounce.png

Bounce will calculate collisions after the bounce occurs too, in the angle that it bounces.
With slide it would calculate collisions along the direction of the slide.
At normal speeds it might not even be the difference of a pixel, but it would be more noticeable as the speed of the object increases and FPS decreases. Although it seems like a small difference, it has a lot of technical difference. Using the proper one will save you from some edge-case (literally) bugs down the road. :awesome:

User avatar
fairenough
Prole
Posts: 12
Joined: Fri Aug 11, 2017 4:44 pm
Contact:

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by fairenough » Mon Aug 14, 2017 12:52 pm

Nuthen224 wrote:
Sat Aug 12, 2017 1:25 am
Hi fairenough. I have used bump for a few projects. I looked over your code snippets and no issues stood out to me. Could you post a .love so I could take a closer look at the issue?
Attached!

I really appreciate you taking a look at it. Let me know if you have any questions about what the heck I did. Like I said, still new to Lua/Love so I'm sure its a fairly jumbled mess.
Attachments
project.love
(3.18 MiB) Downloaded 89 times

User avatar
Nuthen224
Citizen
Posts: 50
Joined: Sun Jul 28, 2013 9:40 pm

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by Nuthen224 » Mon Aug 14, 2017 6:35 pm

Ok, I spotted the issue.
In the player collision code, you can fix the issue by changing the code from this:

Code: Select all

if coll.touch.y > goalY then  -- We touched below (remember that higher locations have lower y values) our intended target.
  self.hasReachedMax = true -- this scenario does not occur in this demo
  self.isGrounded = false
elseif coll.normal.y < 0 then
  self.hasReachedMax = false
  self.isGrounded = true
end
to this:

Code: Select all

if coll.normal.y > 0 then  -- We touched below (remember that higher locations have lower y values) our intended target.
  self.hasReachedMax = true -- this scenario does not occur in this demo
  self.isGrounded = false
elseif coll.normal.y < 0 then
  self.hasReachedMax = false
  self.isGrounded = true
end
The reason is because even when colliding with a wall, there is still a value for touch.y (and that condition is true some of the time). By instead checking the normal, it will guarantee to only check when the player is hitting something from actually below.

Your code is very readable btw! :awesome:

And one other thing, when you require files, it is case sensitive. When I tried to run the .love there was an error about 'mainmenu' (but it worked after I unpacked it).

User avatar
fairenough
Prole
Posts: 12
Joined: Fri Aug 11, 2017 4:44 pm
Contact:

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by fairenough » Mon Aug 14, 2017 6:37 pm

Nice! Thank you, that actually makes a ton of sense!

And good tip on the require thing. I know about things being case sensitive, but I must have overlooked that one. Thanks again!!

User avatar
Nuthen224
Citizen
Posts: 50
Joined: Sun Jul 28, 2013 9:40 pm

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by Nuthen224 » Mon Aug 14, 2017 7:26 pm

No problem. If you have any other questions, feel free to ask! :)

User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by kikito » Tue Aug 15, 2017 9:52 am

Hi everyone,

It has taken me a while to post here, I was away from keyboard but I saw all the questions/answers on my mobile phone.

@alberto_lara corner cases are *very* difficult to handle. I'm starting to think there's no way to 100% deal with them, given the constraints we have in LÖVE (floating point math + variable time step). Right know I believe that the best "solution" is sidestepping the problem by "pre-merging" the tiles into a single rectangle. Other options include "tagging" tiles so they "prefer" colliding in one direction instead of the other, or making your player "more intelligent" with regards to collisions (i.e. if he's walking, he should be able to "step over" small stairs without losing velocity). None of the solutions above completely satisfy me. But this is an open problem and I am very open to suggestions.

@g0r1ll4 bounce only lasts for 1 frame, but it gives you a new velocity vector. If you update your item's velocity vector with it, the effects of the collision can last for lots of frames, and will produce a somewhat intuitive bouncing effect. You might have to tweak the results in order to simulate mass/elasticity to suit your particular needs. In the demo, the "grenades" and the "debris" resulting from destroying stuff both use bounce as an illustration.

@Nuthen224 thanks for solving @fairenough's problem! I rarely have the time to go over other people's code any more. Your help is greatly appreciated.
When I write def I mean function.

User avatar
MadByte
Party member
Posts: 495
Joined: Fri May 03, 2013 6:42 pm
Location: Germany

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by MadByte » Wed Aug 30, 2017 5:57 pm

I got another question.
I'm trying to teleport an object from one "portal" to another on contact using world:update(object, object.x, object.y, object.width, object.height) and the object filter set to "cross" to detect the collision without having any collision resolution (from bump). Now, for some reason, it seems like "cross" doesn't allow me to teleport using world:update, while setting the filter to any of the others result in the object to teleport where I want it to go (but with not wanted collision resolution from bump).
Is there something I don't get? Because I would expect "cross" to ignore collision resolution while using world:move, but world:update should move my object to the destination anyway.

User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by kikito » Wed Aug 30, 2017 6:36 pm

MadByte wrote:
Wed Aug 30, 2017 5:57 pm
it seems like "cross" doesn't allow me to teleport using world:update, while setting the filter to any of the others result in the object to teleport where I want it to go
That should not happen. world:update doesn't even look at filters.

If you can, please provide a .love example showing this behavior. Other than that, the only suggestion I have is trying to remove other stuff that you might be doing before/after calling update.
When I write def I mean function.

User avatar
MadByte
Party member
Posts: 495
Joined: Fri May 03, 2013 6:42 pm
Location: Germany

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by MadByte » Wed Aug 30, 2017 7:02 pm

!Edit! with workaround below
kikito wrote:
Wed Aug 30, 2017 6:36 pm
MadByte wrote:
Wed Aug 30, 2017 5:57 pm
it seems like "cross" doesn't allow me to teleport using world:update, while setting the filter to any of the others result in the object to teleport where I want it to go
That should not happen. world:update doesn't even look at filters.

If you can, please provide a .love example showing this behavior. Other than that, the only suggestion I have is trying to remove other stuff that you might be doing before/after calling update.
Thanks for your quick response.
I guess I may be doing something I shouldn't do in my code then. I can provide a *.love but everything is pretty much splitted into different files, so it might be a pain in the a** to find the problem. Here it is anyway:
Portals.love
(14.47 KiB) Downloaded 87 times
Relevant snippets:

Code: Select all

-- OBJECT.lua
local updateCollisionWorld = function(self)
  if not self.collidable then return end
  if self.collisionWorld:hasItem(self) then self.collisionWorld:update(self, self.x, self.y, self.width, self.height)
  else print("Unable to update collision world for Obj ID'"..tostring(self.type)..", "..tostring(self.id).."': object not found!") end
end

function Object:setPosition(x, y)
  self.x = x or self.x or 0
  self.y = y or self.y or 0
  updateCollisionWorld(self)
end

function Object:move(dx, dy)
  local newx, newy = self.x + dx, self.y + dy
  if self.x == newx and self.y == newy then return end
  if self.velocity.y ~= 0 then self.onGround = false end
  if self.collidable then newx, newy = self:processCollisions(newx, newy) end
  self.x = newx
  self.y = newy
end

function Object:processCollisions(x, y)
  local newx, newy = x, y
  local wx, wy, cols, len = self.collisionWorld:move(self, newx, newy, self.filter)
  if len > 0 then 
    for i=1, #cols do
      local other = cols[i].other
      if self.resolveCollision and other.collidable then
        self:resolveCollision(other)
      end
    end
    newx = wx
    newy = wy
  else
    self.onGround = false
  end

  return newx, newy
end

-- ACTOR.lua
function Actor:filter(other)
  if other.type == "Wall" then return "slide" end
  if other.type == "Portal" then return "cross" end
end

function Actor:resolveCollision(other)
  if other.type == "Wall" then
    -- Ground collision
    if self.y+self.height <= other.y then
      self.onGround = true
      self.velocity.y = 0
    end
  elseif other.type == "Portal" then
    other:teleport(self)
  end
end


-- PORTAL.lua
function Portal:teleport(object)
  local dx, dy = self.destination:getPosition()
  local dw, dh = self.destination:getDimensions()
  
  if self.used then return end
  self:use()
  if self.destination then self.destination:use() end
  object:setPosition(dx+dw/2 - object.width/2, dy+dh/2 - object.height/2)
end

Edit Okay I found my problem. It's the Object:processCollision method I posted above. To be more specific, it's this part:

Code: Select all

  local wx, wy, cols, len = self.collisionWorld:move(self, newx, newy, self.filter)
  if len > 0 then 
    for i=1, #cols do
      local other = cols[i].other
      if self.resolveCollision and other.collidable then
        self:resolveCollision(other) -- in here I try to teleport the player(actor) as result of an detected collision...
      end
    end
    newx = wx -- ... but here I basically ignore the changes I made to the position 
    newy = wy -- in the resolveCollision method and use the old ones instead.
  else
To solve it I just let the resolveCollision method return the new x and y position and I use them as newx and newy instead of wx, wy.
It works but I hate the way it is done... I would love to hear some better ideas from you guys..
And what I still don't understand is why does it work without these changes if I use "touch" or "slide" instead of "cross" ?

User avatar
Jasoco
Inner party member
Posts: 3650
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: [library] bump.lua v3.1.4 - Collision Detection

Post by Jasoco » Thu Aug 31, 2017 7:27 pm

I've always had problems teleporting a Bump object so I just remove the object before changing the coordinates then recreate it when it gets to the new location.

I dunno. It works for me.

Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests