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

Showcase your libraries, tools and other projects that help your fellow love users.
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.0.1 - Collision Detection

Post by kikito »

Jasoco wrote: Edit: I did it! At least it looks like I did.

Basically I made a separate callback in the player object called "moveWithPlatform" that accepts the vx and vy of the platform. When the player is standing on a platform it gets a "attachedToPlatform" string that refers to the platform in question. Then in that platform's object, it checks to see if the player is attached to it and if so it calls the "moveWithPlatform" callback for the player which uses Bump's collision callbacks to make sure it handles collisions the same way the player would by itself.

Hi, I have given this a few tries but did not manage to make it work super-great.

Do you mind sharing it? :ultraglee: Maybe that way I will go faster.
When I write def I mean function.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

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

Post by Jasoco »

Kind of simple really.

In the player object you have a self.attachedToPlatform string which is initially an empty string. In my collision code I check the Y normal for objects that I am standing on and check to see if it is considered a moving platform and set the string to that platform's nameID. (For instance "platform_1".) Before the collision loop I set the string to empty. This I've found is important.

Then in the platform's object I check the player's attachedToPlatform to see if it matches the platform's nameID. If so, the following code is called AFTER the platform's X and Y are set. (Also important) Make sure of course the platforms are moved before the player.

Code: Select all

if game.player.attachedToPlatform == self.nameID then
	game.player:moveWithPlatform(dt, xs, ys)
end
As for the moveWithPlatform function, it's a very simple secondary collision checker:

Code: Select all

function smbPlayer:moveWithPlatform(dt, vx, vy)
	local world = self.world

	local future_x = self.x + vx * dt
	local future_y = self.y + vy * dt

	local next_x, next_y, cols, len = world:move(self, future_x, future_y, playerFilter)

	self.x, self.y = next_x, next_y
end
This ensures the player is not moved into a wall accidentally by using its same filter function.

I have also used this method to make ShyGuys. i.e. enemies that act like both a moving platform and a pass-through platform. i.e. you can stand on them, but they will walk through you. Unfortunately it seems to cause a problem with me detecting when it has collided with the player as no amount of changing the collision type combinations have made it register a collision with the player that still lets the player move freely through it. So I might need to have a secondary collision detection just to check if I collided with an enemy.

Hey, why not just take my current .love?
smb2.love
(169.82 KiB) Downloaded 300 times
Notes:
C to jump
SPACE to pick-up/dig (Enemies can't be picked up yet. Nor can you kill them.)
SHIFT to run

The bottom platform is solid and moves on its own and will sink by 8 pixels when you land on it. The top platform will only start moving when you step on it and has a non-working path feature.

Pluck the mushroom block out of the tub to drain the water because it's awesome!

Sand is also fun to dig through.
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.0.1 - Collision Detection

Post by kikito »

Hi there,

Thanks for uploading the game - it looks cool :) (I could not find the sand through)

The problem I am having is a bit different through - I am doing pass-through platforms. When they move up/down they tend to "drop the player", which is very annoying. I will give a look at your code to see if I can do something with it, but it seems that I need to rethink some stuff.
When I write def I mean function.
User avatar
Doctory
Party member
Posts: 441
Joined: Fri Dec 27, 2013 4:53 pm

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

Post by Doctory »

kikito wrote: (I could not find the sand through)
the sand is the yellow things that lead to the top
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

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

Post by Jasoco »

kikito wrote:Hi there,

Thanks for uploading the game - it looks cool :) (I could not find the sand through)

The problem I am having is a bit different through - I am doing pass-through platforms. When they move up/down they tend to "drop the player", which is very annoying. I will give a look at your code to see if I can do something with it, but it seems that I need to rethink some stuff.
Yep. I had that problem too which is why I had to use the method I settled on. Don't mind my terrible code. I will clean it up when I can. But it works. And if you have suggestions for better methods, feel free to share.

I made a lot of changes since that code I posted so I might make an OT tonight or tomorrow for the project so I'm not cluttering the Bump thread.

And yes, the sand is the yellow stuff.
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.0.1 - Collision Detection

Post by kikito »

Ok I finally got it working. It was much more hairier than I anticipated.

I'm attaching a demo with pass-through, path-driven, working platforms. I have also put the source code in the github repo:

https://github.com/kikito/bump.lua/tree/platforms

Thinks that made it work incorrectly:
  • Non-pass-through platforms are comparatively easier - being "solid" you can rely on "the player not going through them" in lots of cases.
  • I made platforms move first. If they encounter a player, they will "move him", but I also use the pass-through collision filter there (otherwise a platform moving up could "grab the player by the stomach" and move him up). I named the "grab" method player:setGround(platform).
  • Since platforms move first, when the player filters platforms out, he must use the *previous* platform's y to filter, not the "current" one. So platforms need to "store its previus-y" so the player can use them later.
  • Instead of using a string to represent every platform, I use the platform itself as ground (at some point I end up doing self.ground = platform)
  • I realized that when dealing with platforms, at least in bump, you have to treat vertical and horizontal speed differently. Gravity makes them different, for one.
  • I had assumed in a couple places that "the ground doesn't move" (i.e. changeVelocityByCollisionNormal resets velocity to 0 - it should be to the other's velocity).
  • I had to add a special var (player.rvx) representing the "relative x velocity to the ground". It's added to the ground speed when the player is in the ground. Calculating it instead of in setGround allows me to not to have to pass dt around a lot, and is a bit cleaner IMHO.
  • I moved a couple methods from Entity to Player - I think they can be moved back to Entity. The reason why I left them in Player was so that you could see all the changes in one place.
I think that's it. Let me know if you need clarification. There're probably a couple places where the code could be simplified a bit, but it is clean enough IMHO.
Attachments
bump-platforms.love
(19.67 KiB) Downloaded 213 times
When I write def I mean function.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

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

Post by Jasoco »

That's pretty cool. I'll have to try and implement that method into my project. The method I am currently using works fine as long as I was compensating for the movement manually within the other object as well. Which I guess is a bit of extra code as I'd have to write the same code for enemies and other objects that can sit on platforms like bombs.

What if you make them solid, will they properly push other objects? What I'm wondering about is making SMW style moving walls that push the player and enemies around. And detect if the player object is being pushed on both sides (Or above and below), i.e. being crushed. (Think the moving layers modern Mario games since SMB3 have had. Like the ceiling in the first fortress in SMB3 or the large moving stone blocks in many of the castles in SMW or the many similar moving blocks in the NSMB series.)
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.0.1 - Collision Detection

Post by kikito »

What if you make them solid, will they properly push other objects?
Yes. Objects intersecting with them when they are moved out will get "pushed outwards" on their collision resolution phase (provided that the "pushers" get moved before the "pushed").

However, this kind of "pushing" is not tunneling-invulnerable. This is, a small-enough platform, moving fast enough, pushing a small-enough object, can end up "traversing" the object or pushing it in the wrong direction.

The way to fix this is to implement a "push" method in the pushed objects, and invoke it on the pushers, with the appropiate dx and dy (which is calculated like this: velocity*(1-col.ti)*dt:

Here's the code for the Platforms / Pushers

Code: Select all

local filter = function(other)
  if other.pushable then return 'cross' end
end

function Pusher:update(dt)
  local actualX, actualY, cols, len = self.move(self.x + self.vx * dt, self.y + self.vx * dt, filter)
  self.x, self.y = actualX, actualY
  local col, ti, dx, dy
  for i=1,len do
    col = cols[i]
    dx = self.vx * (1 - col.ti) * dt
    dy = self.vy * (1 - col.ti) * dt
    col.other:push(dx, dy)
  end
end
Here's the code for the "Pushable" items (i.e. the player)

Code: Select all

function Pushable:push(dx,dy)
  local actualX, actualY, cols, len = self.move(self.x + dx, self.y + dy, filter)
  self.x, self.y = actualX, actualY
  -- do something with cols, if needed
end
That would make platforms move things around taking tunelling into account.

Now that I have answered your question, I have another one: I am considering adding the "item" itself to the filter parameters, as Doctory requested. and I am pondering wether it would be more useful to put it as the first (filter(item, other)) or the last param (filter(other, item)).
  • Putting item first feels more "the Lua way", since "self" comes first. You could define 'filter' as a class method and it would work. But it breaks backwards-compatibility.
  • Putting it last would be totally compatible with what we have now, but we lose the possibility of defining filter as a method, and it's a bit less idiomatic
Since you seem to be my most advanced (or at least vocal ;) ) user of bump, which option would you prefer? I'm currently leaning towards putting it first, even if it breaks compatibility a bit (we gain some things and it's just a matter of replacing (other) by (item, other) )
When I write def I mean function.
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

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

Post by Jasoco »

kikito wrote:Now that I have answered your question, I have another one: I am considering adding the "item" itself to the filter parameters, as Doctory requested. and I am pondering wether it would be more useful to put it as the first (filter(item, other)) or the last param (filter(other, item)).
  • Putting item first feels more "the Lua way", since "self" comes first. You could define 'filter' as a class method and it would work. But it breaks backwards-compatibility.
  • Putting it last would be totally compatible with what we have now, but we lose the possibility of defining filter as a method, and it's a bit less idiomatic
Since you seem to be my most advanced (or at least vocal ;) ) user of bump, which option would you prefer? I'm currently leaning towards putting it first, even if it breaks compatibility a bit (we gain some things and it's just a matter of replacing (other) by (item, other) )
I was thinking this exact same thing. Complete with conundrum of which would go first.

I would suggest making it second, but if you do it first I am not objecting as it's simple enough to update our code in like 2 minutes tops. I was going to suggest this too. Since we sometimes want to be able to reference the object itself from within the filter. I see you used the same method I did where you made the filter a function belonging to the entity so you could put self inside it easily. That's the same thing I had to do. If you let us have self as a parameter, then we don't have to worry about that anymore. Putting it first won't be a big deal to fix our code. I mean it's not like it's the first time we've had to rewrite code to implement a new version of a library or even a new version of Löve.
User avatar
Doctory
Party member
Posts: 441
Joined: Fri Dec 27, 2013 4:53 pm

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

Post by Doctory »

is there a way to move objects without doing collisions?
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests