Page 1 of 1

### [Solved] Collision Check in 2D Platformer

Posted: Sun Feb 03, 2019 8:01 pm
Hi all. I've been trying to understand basic platformer mechanics like jumping. Thanks to this post: https://love2d.org/wiki/Tutorial:Baseline_2D_Platformer i got the basics about it but there is a major problem.

I've tried to make platformer like this:

Code: Select all

``````--might be weird but...
lp=love.graphics;
lk=love.keyboard;

function love.update(dt)
heroUpdate(dt);
end

function love.draw()
mapDraw(10, 10);
heroDraw();
end

hero={
x=10,
y=20,
w=10,
h=10,

speed=75,

velocity=0,
jump=-50,
gravity=-70,
};

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

local w=10;
local h=10;

function collision(x, y)
if hero.x < x+w and
hero.x+hero.w > x and
hero.y < y+h and
hero.y+hero.h > y then
return true;
else
return false;
end
end

function mapDraw(mapX, mapY)
for y=1, #map do
for x=1, #map[1] do
if map[y][x]==0 then
lp.setColor(30, 30, 30);
elseif map[y][x]==1 then
--collision happens
if collision(mapX+(w*x)-w, mapY+(y*h)-h) then
hero.velocity=0;
lp.setColor(255, 40, 255);
else
lp.setColor(255, 255, 40);
end
end

lp.rectangle("fill", mapX+(w*x)-w, mapY+(y*h)-h, w, h);
end
end
end

function heroUpdate(dt)
if lk.isDown("left") then
hero.x=hero.x-hero.speed*dt;
elseif lk.isDown("right") then
hero.x=hero.x+hero.speed*dt;
end

if lk.isDown("space") or lk.isDown("up") then
if hero.velocity==0 then
hero.velocity=hero.jump;
end
end

if hero.velocity~=0 then
hero.y=hero.y+hero.velocity*dt;
hero.velocity=hero.velocity-hero.gravity*dt;
end
end

function heroDraw()
lp.setColor(255, 40, 40);
lp.rectangle("fill", hero.x, hero.y, hero.w, hero.h);
end
``````
According to this code, (which is full of bugs) player walks through boxes and after a jump, it hangs on the air on the same direction with the last box it collide. So,

How can i make it fall after it tries to walk on the same direction?
How can i make the boxes solid? (like when it hits it instantly stops.)

Thank you alot!

### Re: [Need help] Collision Check in 2D Platformer

Posted: Tue Feb 05, 2019 2:41 pm
Hi, I'm checking your .love file.

I would recommend doing something like that

love.update(dt) : You put the logic
love.draw(): You draw your game

You can use AABB function like :

Code: Select all

``````function CheckCollision(obj1, obj2)
return (obj1.x < obj2.x+ obj2.w and
obj2.x < obj1.x+obj1.w and
obj1.y < obj2.y+obj2.h and
obj2.y < obj1.y+obj1.h), (obj2.y < obj1.y+obj1.h)
end``````
When you collides with another box example:

Code: Select all

``````player={x=0,y=0,w=25,h=25,oldx=0,oldy=0,ground=false}
boxes={}
table.insert(boxes,{x=40,y=0,w=50,h=50})
...

function love.update(dt)
--first you move your player
player_move()
--you check the collisions
collisions()
end

function CheckCollision(obj1, obj2)
return (obj1.x < obj2.x+ obj2.w and
obj2.x < obj1.x+obj1.w and
obj1.y < obj2.y+obj2.h and
obj2.y < obj1.y+obj1.h), (obj2.y < obj1.y+obj1.h)
end

function collisions()
for _,box in ipairs(boxes) do
local col,ground=CheckCollision(player,box)
if col then
--if collides move player to old position
player.x=player.oldx
player.y=player.oldy

player.ground=ground
end
end

function player_move()
if love.keyboard.isdown("a") then
player.x=player.x-50
elseif love.keyboard.isdown("d") then
player.x=player.x+50
end

if love.keyboard.isdown("w") then
player.ground =false
....
end

--save old position
player.oldx=player.x
player.oldy=player.y

if not player.ground then
--gravity
end
end
``````
You need to use a bolean ground and disable gravity when you collides with box and ground is true.
I not tried the code, but the logic is the same like you need,I hope it helps.

Sorry I'm no a english speaker.

### Re: [Need help] Collision Check in 2D Platformer

Posted: Wed Feb 06, 2019 9:16 am
i still couldn't make it. i think i understand the logic but what's the difference between for ipairs() and single for loop? in order to create the map, do i have to write every boxes' x and y one by one?

by the way, i'm not an english speaker too

### Re: [Need help] Collision Check in 2D Platformer

Posted: Wed Feb 06, 2019 11:06 am
There are several ways to deal with collisions if you have a tilemap. AdrianN just showed a way for boxes that are not tile-based.
Here is a nice tutorial (not in lua, but easily to implement) that looks further into topic: https://jonathanwhiting.com/tutorial/collision/

The problem with your code is that you check collision after movement and if there was one you only set speed to 0. What you should do instead is to respond to such collision, reverse the wrong movement somehow. Some types of response (or avoiding collision totally) are explained in above tut

### Re: [Need help] Collision Check in 2D Platformer

Posted: Wed Feb 06, 2019 2:27 pm
nikneym wrote:
Wed Feb 06, 2019 9:16 am
i still couldn't make it. i think i understand the logic but what's the difference between for ipairs() and single for loop?
Ipairs is the same if you use for loop. Ipairs only check if table's value is null.

Code: Select all

``````--check null and stop
for _, obj in ipairs(table) do

end

--equal to for loop
for _, obj in pairs(table) do

end

for i=1,#table,1 do

end``````
nikneym wrote:
Wed Feb 06, 2019 9:16 am
in order to create the map, do i have to write every boxes' x and y one by one?
Sorry I forgot you tile map, thanks karolek.
You can use this logic:

Code: Select all

``````local tilewidth, tileheight=32,32
local map={
{0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 0, 0},
{1, 0, 0, 0, 0, 1},
{1, 1, 0, 0, 1, 1},
{1, 1, 1, 1, 1, 1},
};

...
function Issolid(v)
if v==1 then
return true
else
return false
end
end

function collisions()
for j=1,#map,1 do
for i=1,#map[j], 1  do
local t={}
t.x=(i-1)*tilewidth
t.w=tilewidth
t.y=(j-1)*tileheight
t.h=tileheight
local col,ground=CheckCollision(player,t)
if col and Issolid(map[j][i]) then
--if collides move player to old position
player.x=player.oldx
player.y=player.oldy

player.ground=ground
end
end
end
end

``````
Transform map array position to x,y axis. You can change issolid value(1 is wall) and add more values with table and loop (2= water,3 = grass ...)

### Re: [Need help] Collision Check in 2D Platformer

Posted: Fri Feb 08, 2019 9:55 pm
it works great now. also, thanks for the ipairs() mechanic man!