I can't understand collision - Please help me understand

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
xNick1
Party member
Posts: 267
Joined: Wed Jun 15, 2016 8:27 am
Location: Rome, Italy

Re: I can't understand collision - Please help me understand

Post by xNick1 »

For instance I wanna press a button.

When I press my mouse button I want to check if I'm actually inside the button.
If I'm inside the button with my cursor I wanna play a sound and I move to the main menu.

Code: Select all

function Menu2:mousePressedMenuItems(x, y, button, isTouch)
    -- Here I wanna check if the x of my cursor is between the starting x of the button and the ending x of the button.
    -- So I go check like if cursor X is between button x and button x + button width
    
    if x >= self.backButtonX and x <= self.backButtonX + self.backButtonWidth then
    	-- the same goes for the y coordinates
        if y >= self.backButtonY and y <= self.backButtonY + self.backButtonHeight then
            -- I pressed inside the button, so I play a sound and I get back to the main menu
            self.tap:play()
            menuTree = "menuRoot"
        end 
    end
end
The same goes if you want collisions between two game objects instead of a button and the mouse cursor.
You can even detect collisions with object of the same type.
Just iterate through a table.

Code: Select all

trees = { }
treeNum1 = Tree();
treeNum2 = Tree();
table.insert(trees, treeNum1);
table.insert(trees, treeNum2);

for _, tree in ipairs(trees) do
	-- same thing as before, I check if I'm tapping inside one of the trees.
        if x >= tree.x and x <= tree.x + tree.width then
            if y >= tree.y and y <= tree.y + tree.height then
                print("you clicked a tree")
            end
        end
    end
Or you can check if two objects are colliding.
This should give you a start!
NoAim91
Prole
Posts: 38
Joined: Mon Feb 20, 2017 10:28 am
Location: Germany

Re: I can't understand collision - Please help me understand

Post by NoAim91 »

Hi

this video Tutorial (and the whole series) is pretty good for collision: https://www.youtube.com/watch?v=4aucCStbkMs
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: I can't understand collision - Please help me understand

Post by airstruck »

It's much simpler if you store the AABB as a midpoint, a half-width, and a half-height (instead of upper-left-corner-point, width, and height). Then all you need to do is check that the distance between the midpoints is less than the sum of the "half-sizes" along each axis. Storing midpoint instead of upper left corner also makes positioning and rotating objects more intuitive.

For example, you can check collision between two objects where the midpoint is stored in fields "x" and "y" and the half-width and half-height are stored in fields "w" and "h" like this:

Code: Select all

local function checkCollision (a, b)
    return math.abs(a.x - b.x) < a.w + b.w
        and math.abs(a.y - b.y) < a.h + b.h
end
How you resolve collisions depends on what you need to do (would need more information to help with that), but it may be useful to look for the axis along which the objects overlap less, and to look at the relative placement of the objects along that axis. In other words, if `(a.w + b.w) - abs(a.x - b.x)` is greater than `(a.h + b.h) - abs(a.y - b.y)` then they're colliding "horizontally," otherwise they're colliding "vertically."
User avatar
Imaculata
Party member
Posts: 102
Joined: Mon Aug 10, 2015 2:51 pm

Re: I can't understand collision - Please help me understand

Post by Imaculata »

Without diving head first into actual code, the basics of collision detection are this:

You have two objects. For the sake of convenience, lets assume they both have a hitbox that resembles a rectangle: A player, and a wall. Now the player obviously does not look like a rectangle, but that is just the graphics. Behind the scenes little Mario is secretly just a small upright rectangle, that collides with other rectangles.

Checking if two or more of these rectangles collide, is what we call collision detection. We basically check if one rectangle overlaps the other, based on the x/y locations of their respective corners. In the same way, we can also check if a single point is inside a rectangle (convenient for seeing if a rocket collides with a wall), or whether a line intersects with a rectangle (convenient for shooting lasers).

Types of collision detection

The type of collision detection you want to use, depends on how accurate you want it to be. Detecting a point inside a rectangle is obviously easier and quicker than detecting overlapping rectangles. Likewise, if you simply compare the distance between two objects, that is even easier. Most collision detection for 2d games tends to simplify the collision of objects to rectangular shapes, because it is easier.

I'm currently using the bump library for my platforming game. I figured, why try and reinvent the wheel, when others have already tackled this issue way better than I ever could? One of the things bump handles for example, is this collision response, and also tunneling.

Detecting a wall/ceiling/floor

When a player-character collides with a wall, he is usually already inside the wall when the collision is detected. This is why most collision detection corrects the location of the player before the player is drawn. So if my player sprite collides with a wall and stops, what is really happening, is that the rectangle that represents the player intersects with the rectangle that represents the wall. The collision detection then subtracts the distance, so that the player is now next to the wall, instead of inside it. It is important that you first check where the game wants to move the player, and correct the location if there is a collision with a wall, before actually moving the player.

Tunneling

Tunneling is when an object moves so many pixels per frame, that it actually passes right through a collision object, before a collision is even detected. Most collision detection code has a way of dealing with this issue.

Detecting multiple simultaneous collisions

It is important that your collision detection does not just detect one collision, but is able to output a list of all the collisions, and handle them one by one. For example, Mario could collide with both a wall and a coin at the same time. He should collect the coin, and stop when he hits the wall. Those are two collisions that would need to be resolved at the same time.

Collision response

The most important part however, is collision response. Collision response is what your game does when a collision is detected. For example, what happens when Mario touches a coin? What happens when he touches an enemy? What if he hits a wall? For this purpose it helps if every collision object can be identified by type. Because while Mario can collide with coins, his enemies ignore them completely. That's because enemies ignore any collisions with objects that are pickups/powerups. Not every collision has to stop a game object dead in its tracks. Sometimes you want the object to disappear, or be ignored entirely.

In my game I have water-surface blocks for example. When the player passes through them, the game knows if the player is above or below the water. And thus it switches to swimming or normal movement. For this purpose, it helps if you can also output exactly where the collision occurred. Was the player above or below the y-location of the water? Most collision detection libraries have a way of outputting data about any specific collision.

Quick detection

One of the tricky things about hit detection, is that you don't want to be checking collisions with every game object every frame. Because it can quickly become very demanding. So most collision detection has a way of finding out which objects are eligible for collisions. You might not want to check objects that are off screen.... or maybe you do. You might not want to check collisions with objects that the player isn't even remotely close to, or can't collide with. So basically you want your code to single out a group of objects that are going to be checked.
Post Reply

Who is online

Users browsing this forum: No registered users and 38 guests