## [Solved][Includes Example] Checking collisions and jumping around

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
nikneym
Citizen
Posts: 50
Joined: Sat Mar 09, 2013 1:22 pm
Contact:

### [Solved][Includes Example] Checking collisions and jumping around

Solved! Here is a simple collision check in tile-based universe.

Code: Select all

local map = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 0},
{1, 1, 1, 1, 1},
}

local TILE_WIDTH = 8
local TILE_HEIGHT = 8

local player = {
x = 10,
y = 10,
w = 8,
h = 8,

speed = 50,
}

player.last = {
x = player.x,
y = player.y,
}

player.update = function(dt)
player.last.x, player.last.y = player.x, player.y

if love.keyboard.isDown("left") then
player.x = player.x - player.speed * dt
elseif love.keyboard.isDown("right") then
player.x = player.x + player.speed * dt
end

if love.keyboard.isDown("up") then
player.y = player.y - 100 * dt
end

player.y = player.y + 30 * dt
end

local col = function(x, y)
return player.x < x + TILE_WIDTH
and    x < player.x + player.w
and    player.y < y + TILE_HEIGHT
and    y < player.y + player.h
end

local verticalAligned = function(y)
return player.last.y < y + TILE_HEIGHT and player.last.y + player.h > y
end

local horizontalAligned = function(x)
return player.last.x < x + TILE_WIDTH and player.last.x + player.w > x
end

map.update = function()
for y=1, #map do
for x=1, #map[1] do
local t = map[y][x]
local tileX = TILE_WIDTH * x - TILE_WIDTH
local tileY = TILE_HEIGHT * y - TILE_HEIGHT

if t == 1 then
if col(tileX, tileY) then
if verticalAligned(tileY) then
if player.x + player.w / 2 < tileX + TILE_WIDTH / 2 then
local pushback = player.x + player.w - tileX
player.x = player.x - pushback
else
local pushback = tileX + TILE_WIDTH - player.x
player.x = player.x + pushback
end
elseif horizontalAligned(tileX) then
if player.y + player.h / 2 < tileY + TILE_HEIGHT / 2 then
local pushback = player.y + player.h - tileY
player.y = player.y - pushback
else
local pushback = tileY + TILE_HEIGHT - player.y
player.y = player.y + pushback
end
end
end
end
end
end
end

function love.update(dt)
player.update(dt)
map.update()
end

function love.draw()
love.graphics.push()
love.graphics.scale(8)

for y=1, #map do
for x=1, #map[1] do
local t = map[y][x]

local tileX = TILE_WIDTH * x - TILE_WIDTH
local tileY = TILE_HEIGHT * y - TILE_HEIGHT

if t == 0 then
love.graphics.setColor(40, 40, 160)
elseif t == 1 then
love.graphics.setColor(40, 160, 40)
end

love.graphics.rectangle("fill", tileX, tileY, TILE_WIDTH, TILE_HEIGHT)
end
end

love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", player.x, player.y, player.w, player.h)

love.graphics.pop()
end

Last edited by nikneym on Sun May 10, 2020 5:50 am, edited 2 times in total.

pgimeno
Party member
Posts: 2310
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Checking collisions and jumping around

Collisions are difficult to handle. I suggest you use a library. bump.lua is a good choice for AABBs.

As for Vector2, it sounds like a 2D vector, a vector with 2 components. No idea what libraries you've found and what they do.

nikneym
Citizen
Posts: 50
Joined: Sat Mar 09, 2013 1:22 pm
Contact:

### Re: Checking collisions and jumping around

I tried bump.lua before and I'm sure it can create what I want but I want to make my own platformer collision detection. It don't have to be something super-realistic, just usual NES games-style platformer collisions. Are there any examples or sources about it?

sphyrth
Party member
Posts: 220
Joined: Mon Jul 07, 2014 11:04 am
Contact:

### Re: Checking collisions and jumping around

Sheepolution's Chapter 23 for the collision sample. You can also follow-up with Chapter 24 of that.

Astorek86
Prole
Posts: 20
Joined: Fri Jul 13, 2018 7:35 pm

### Re: Checking collisions and jumping around

I would try a Thing like this:
• Get Inputs and set Variables to store the Movement, but don't modify Player-Position yet. (For example: A Variable called "player.dx": If "a" is pressed, set Variable to -1; if "d" is pressed, set Variable to 1).
• Check Collision on "player.x + player.dx"-Position.
• If Collision is present, set "player.dx" to 0 (< This is some Quick'n Dirty-Solution, but it helps to understand how it works).
• If no Collision is present, simply do nothing.
• move Player-Position ("player.x = player.x + player.dx")

pgimeno
Party member
Posts: 2310
Joined: Sun Oct 18, 2015 2:58 pm

### Re: Checking collisions and jumping around

Astorek86 wrote:
Wed Apr 29, 2020 10:48 pm
If Collision is present, set "player.dx" to 0 (< This is some Quick'n Dirty-Solution, but it helps to understand how it works).
Indeed it's quick and dirty. If the player is going faster than 1 pixel per frame, this will show a separation from the collided rectangle. It would be possible to fix that by looping between the old and the new coordinates with a dx/dy step that skips one pixel at a time.

You also need to do the coordinates one by one, e.g. horizontal, and check for collision, and then vertical and check for collision (or vice versa); otherwise you don't know which side collided first as the OP wanted.

nikneym
Citizen
Posts: 50
Joined: Sat Mar 09, 2013 1:22 pm
Contact:

### Re: [Solved][Includes Example] Checking collisions and jumping around

Well, I went ahead and read all the examples made by Sheepolution. I copied his collision check algorithm into my prototype. He uses classic.lua OOP system and because I'm prototyping, I made a non-OOP tile collision check for everyone who may struggle with this in the future (Jumping in the example should be updated). I generally can't understand someone else's code written in OOP :p

Code: Select all

local map = {
{0, 0, 0, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 0},
{1, 1, 1, 1, 1},
}

local TILE_WIDTH = 8
local TILE_HEIGHT = 8

local player = {
x = 10,
y = 10,
w = 8,
h = 8,

speed = 50,
}

player.last = {
x = player.x,
y = player.y,
}

player.update = function(dt)
player.last.x, player.last.y = player.x, player.y

if love.keyboard.isDown("left") then
player.x = player.x - player.speed * dt
elseif love.keyboard.isDown("right") then
player.x = player.x + player.speed * dt
end

if love.keyboard.isDown("up") then
player.y = player.y - 100 * dt
end

player.y = player.y + 30 * dt
end

local col = function(x, y)
return player.x < x + TILE_WIDTH
and    x < player.x + player.w
and    player.y < y + TILE_HEIGHT
and    y < player.y + player.h
end

local verticalAligned = function(y)
return player.last.y < y + TILE_HEIGHT and player.last.y + player.h > y
end

local horizontalAligned = function(x)
return player.last.x < x + TILE_WIDTH and player.last.x + player.w > x
end

map.update = function()
for y=1, #map do
for x=1, #map[1] do
local t = map[y][x]
local tileX = TILE_WIDTH * x - TILE_WIDTH
local tileY = TILE_HEIGHT * y - TILE_HEIGHT

if t == 1 then
if col(tileX, tileY) then
if verticalAligned(tileY) then
if player.x + player.w / 2 < tileX + TILE_WIDTH / 2 then
local pushback = player.x + player.w - tileX
player.x = player.x - pushback
else
local pushback = tileX + TILE_WIDTH - player.x
player.x = player.x + pushback
end
elseif horizontalAligned(tileX) then
if player.y + player.h / 2 < tileY + TILE_HEIGHT / 2 then
local pushback = player.y + player.h - tileY
player.y = player.y - pushback
else
local pushback = tileY + TILE_HEIGHT - player.y
player.y = player.y + pushback
end
end
end
end
end
end
end

function love.update(dt)
player.update(dt)
map.update()
end

function love.draw()
love.graphics.push()
love.graphics.scale(8)

for y=1, #map do
for x=1, #map[1] do
local t = map[y][x]

local tileX = TILE_WIDTH * x - TILE_WIDTH
local tileY = TILE_HEIGHT * y - TILE_HEIGHT

if t == 0 then
love.graphics.setColor(40, 40, 160)
elseif t == 1 then
love.graphics.setColor(40, 160, 40)
end

love.graphics.rectangle("fill", tileX, tileY, TILE_WIDTH, TILE_HEIGHT)
end
end

love.graphics.setColor(255, 255, 255)
love.graphics.rectangle("fill", player.x, player.y, player.w, player.h)

love.graphics.pop()
end


inJuly
Prole
Posts: 27
Joined: Fri May 01, 2020 9:02 pm

### Re: [Solved][Includes Example] Checking collisions and jumping around

If you want to learn how to handle physics and collisions, these are a couple of things you should learn:

1. AABB collision detection (just brute force in your first few games)
2. Sweep and prune
3. Fixed Resolution grids
4. Quadtrees or BSP Trees or k-d trees (Personally gonna recommend quadtrees)

### Who is online

Users browsing this forum: Bing [Bot] and 30 guests