Page 22 of 23

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

Posted: Sun Aug 13, 2017 3:59 pm
by Nuthen224
@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:

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

Posted: Mon Aug 14, 2017 12:52 pm
by fairenough
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.

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

Posted: Mon Aug 14, 2017 6:35 pm
by Nuthen224
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).

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

Posted: Mon Aug 14, 2017 6:37 pm
by fairenough
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!!

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

Posted: Mon Aug 14, 2017 7:26 pm
by Nuthen224
No problem. If you have any other questions, feel free to ask! :)

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

Posted: Tue Aug 15, 2017 9:52 am
by kikito
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.

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

Posted: Wed Aug 30, 2017 5:57 pm
by MadByte
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.

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

Posted: Wed Aug 30, 2017 6:36 pm
by kikito
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.

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

Posted: Wed Aug 30, 2017 7:02 pm
by MadByte
!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 260 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" ?

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

Posted: Thu Aug 31, 2017 7:27 pm
by Jasoco
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.