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

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

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

Post by MadByte »

I think I found a bug or I do something horribly wrong.
For my current project I need that the player can move out of screen on one side (x or y axis) and then gets
teleported to the opposit side. I made up an simplified example to make sure that its not a problem in my game code.

It should look like this:
Image
The red box gets teleported to the opposit side.

Now what happens when I move out of the screen and Im directly above or underneath (or left of or right of) a collidable object is
that a collision gets detected without that the red box is even near the other object.
(note: everytime you see the red box spawn underneath means that it detected a collision -> the object get
deleted and I had to reset the game)
Image

löve file:
offscreenBug.love
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 »

You are using world:move in a "teleport" situation, which is the opposite of what it was designed to do. Let me explain.

Collisions in bump are continuous. If a bullet moves at 100 pixels per frame, bump can still detect when it hits a 10-pixel wall. This is more or less what is happening in your example: when your player "leaves the screen to the left" and then "repositions himself to the right", and you just keep using world:move to notify that change, bump sees it as if the player was a "very fast bullet which had moved from the left to the right of the screen". If instead of an "exit block" you had a "solid block" (with a "slide" or "touch" collision type), then the player would have stopped when he was touching it, on its left.

world:move exclusively handles this kind of continuous movement. It doesn't matter if the movement is 1 pixel or 1000 pixels. Anything in between is collided against. This is by design, and usually desirable.

But this also means that if there's "teleporting" in a game, where movement is not continuous, it needs to be handled in a special way. In your case, you should be using world:update when a teleportation occurs. This method just changes the coordinates associated with an item in the world, without performing any collision detection. But keep using world:move for your regular non-teleporting moves.
When I write def I mean function.
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

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

Post by MadByte »

Thats understandable and easy to fix.
Thanks for the explanation!
pevzi
Prole
Posts: 27
Joined: Tue Apr 02, 2013 4:09 pm
Contact:

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

Post by pevzi »

Characters in some games skirt around an obstacle when trying to butt against its edge. Any ideas how to implement this behavior with bump?
(don't mind the artifacts)
mario_jump.gif
mario_jump.gif (78.28 KiB) Viewed 3949 times
zelda.gif
zelda.gif (69.49 KiB) Viewed 3949 times
User avatar
Skeiks
Citizen
Posts: 51
Joined: Wed Jan 28, 2015 1:51 pm

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

Post by Skeiks »

pevzi wrote:Characters in some games skirt around an obstacle when trying to butt against its edge. Any ideas how to implement this behavior with bump?
(don't mind the artifacts)
mario_jump.gif
zelda.gif
There are two ways that I know of to handle this that aren't specific to bump. The first way is to break apart your character object. Instead of using one big rectangle to handle collisions for your player, use multiple "tracers". I don't know how you could implement this in bump (so really I'm not answering your question at all, am I?) but I figure I'll post it anyway. Maybe you could use bumps collision detection methods to implement this and eschew the collision resolution, but as far as I can see there isn't any specific way to get this functionality using bump unmodified.

Image


Imagine that each one of those points (R,G,B,Bl for Black) is its own little 2px by 2px rectangle in bump. They move with the character and they detect collisions with the world.

When the RED points touch an object, they'll move the player to the LEFT until they no longer detect a collision.
When the BLUE points touch an object, they'll move the player to the RIGHT until they no longer detect a collision.
When the GREEN points touch an object, they'll move the player DOWNWARDS until they no longer detect a collision.
When the BLACK points touch an object, they'll move the player UP until they no longer detect a collision.

This has the effect of keeping the player out of the ground, and makes movement smooth. When the edge of the player touches an object, the player doesn't get caught. He'll move downwards and be pushed the left, just like in your GIF. You'll have to adjust the position of the "tracers" to get your movement right, but this is the method I use in pretty much every game I make.

This method does have its downsides. Resolving collisions leads to some weird shit. For example, if the player is moving fast enough horizontally and you resolve collisions on the upper bounds before you resolve on the walls, the player will teleport above the wall. Vice versa for falling fast enough and being teleported to the left or right. You can solve these by placing the tracers smartly, and moving them in conjunction with how fast the player is moving.

------------------------

The second method I see pretty often is people representing their characters polygonally using circles, or rectangles with circles above them. which is definitely not possible in bump.

Image

I'm almost 99% sure Mario Bros used the "tracer" method but here's a representation of it as a circle. I'm also 99% sure that Sonic used the tracer method too, but that's beside the point.

With this method you could use any old physics engine, and this way ceiling collisions are smooth. I've even seen some games (smooth platformers, think Fancy Pants Adventures ) using a full circle for their player, or a rounded rectangle would work too.


Sorry if this isn't too helpful, I expect kikito might have more answers for you.
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 »

I think old zeldas (and definitively the first Marios) didn't have the luxury of breaking appart their main character into several rectangles, nor using vector math. I suspect they didn't even use rectangles, but pixels (you can do this if you have a fixed time step, like they did in MC kids).

I also know that, at least in A Link to the Past, Miyamoto used a simple but very effective trick: when you pressed "up", "down", "left" or "right", Link didn't really move in those directions. Instead, it made little adjustments to "align himself with the underlying world grid". So if he was slightly misaligned to the left with respect to the center of the current tile, and you pressed down, his walking direction would be "down but a bit to the right too". That, combined with a player being smaller than the tiles, and a "slide" collision, would made Link not to "snag" near corners.

I'm almost certain that's the same trick they use in other tile-based Zeldas, and I wouldn't be surprised if they did something similar with mario.

This article explains this technique in more detail: http://troygilbert.com/deconstructing-z ... mechanics/
When I write def I mean function.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

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

Post by pgimeno »

I've checked the Zelda image frame by frame:

Image

It seems to me that what is happening is this. The player is divided into 4 rectangles (quadrants).

- If pressing down and the bottom right rectangle is colliding but not the bottom left, the player is moved left (as in the example). Possibly diagonally so that the slide resolution does the right thing.
- If pressing down and the bottom left rectangle is colliding but not the bottom right, the player is moved right.
- Similarly for the other 3 directions.
User avatar
Skeiks
Citizen
Posts: 51
Joined: Wed Jan 28, 2015 1:51 pm

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

Post by Skeiks »

kikito wrote:I think old zeldas (and definitively the first Marios) didn't have the luxury of breaking appart their main character into several rectangles, nor using vector math. I suspect they didn't even use rectangles, but pixels (you can do this if you have a fixed time step, like they did in MC kids).

I also know that, at least in A Link to the Past, Miyamoto used a simple but very effective trick: when you pressed "up", "down", "left" or "right", Link didn't really move in those directions. Instead, it made little adjustments to "align himself with the underlying world grid". So if he was slightly misaligned to the left with respect to the center of the current tile, and you pressed down, his walking direction would be "down but a bit to the right too". That, combined with a player being smaller than the tiles, and a "slide" collision, would made Link not to "snag" near corners.

I'm almost certain that's the same trick they use in other tile-based Zeldas, and I wouldn't be surprised if they did something similar with mario.

This article explains this technique in more detail: http://troygilbert.com/deconstructing-z ... mechanics/
In reference to bump I thought it would be best to describe the tracers as rectangles, but I really should've just went with pixels or points. The method I use is pretty similar to what I read in McKids, I generally use tile sets and assign them values based on their shapes. I then check for world collisions against the tileset. Then again I also use fixed timesteps for most of my games.

The offset method is pretty creative and probably saved a lot of computing power with collisions. According to the article you linked though they stopped using it in LTTP.
Observant readers will observe (as they are known to do) that this “feature” doesn’t appear in the SNES sequel, The Legend of Zelda: A Link to the Past. Even though the gameworld is still tile-based, player (and enemy/NPC) movement is not strictly aligned on any grid. We get the same corrections though, but using different mechanisms.

Movement is corrected by “rounding” the corners of most things Link can collide with. Thus, when he encounters them the “physics” of the game deflects him at a 45-degree angle along his direction of movement (e.g., if he was moving north/up and encountered a corner he would move northwest/east until he passed the corner).
And I think that makes sense for newer games. If in a newer zelda, the character aligned with a grid as you walked, the game would feel a lot less free.
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 »

According to the article you linked though they stopped using it in LTTP.
You are completely right. I said it from memory and didn't read the article completely when I linked to it.

Doing the 45 degrees solution is however more difficult to do in bump than the grid adjustment thing. The first one just requires altering the way the collision resolution is done, while the latter can be accomplished by changing the velocity of the player slightly.
When I write def I mean function.
User avatar
pgimeno
Party member
Posts: 3544
Joined: Sun Oct 18, 2015 2:58 pm

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

Post by pgimeno »

I've made a proof of concept of what I meant. Sorry it took this long.

I thought bump would have support for moving multiple rectangles as a unit, but that doesn't seem to be the case, so I reworked the idea to use bump's queryRect. In total it requires checking at most three rectangles each pass. It can be made better by making it stick to the wall once it's around the corner, but that's not the focus of this demo.

Rather than using half the character width as a fixed margin, the margin is adjustable.
Attachments
corners.love
(1.71 KiB) Downloaded 151 times
Post Reply

Who is online

Users browsing this forum: No registered users and 43 guests