## Collision with rectangle freezes player?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
ntnick
Prole
Posts: 8
Joined: Tue Nov 11, 2014 4:51 pm

### Collision with rectangle freezes player?

So I am currently working on my game, and I'm implementing walls and collision.
When the player bumps into a wall, the character freezes and can no longer move.

My code for collision:

Code: Select all

function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
return x1 < x2+w2 and
x2 < x1+w1 and
y1 < y2+h2 and
y2 < y1+h1
end

function cols()
for i, wall in ipairs(walls) do
if(CheckCollision(player.x, player.y, player.sprite:getWidth(), player.sprite:getHeight(), wall.x, wall.y, wall.w, wall.h)) then
if(wall.collide) then
return true
else
return false
end
end
end
end
Code for movement:

Code: Select all

function love.update(dt)

if(love.keyboard.isDown('escape')) then
love.event.push('quit')
end

if(love.keyboard.isDown('up','w')) then
if(not cols()) then
player.y = player.y - (player.speed * dt)
end
end

if(love.keyboard.isDown('down','s')) then
if(not cols()) then
player.y = player.y + (player.speed * dt)
end
end

if(love.keyboard.isDown('left','a')) then
if(not cols()) then
player.x = player.x - (player.speed * dt)
end
end

if(love.keyboard.isDown('right','d')) then
if(not cols()) then
player.x = player.x + (player.speed * dt)
end
end

end

Code: Select all

player = { x = 100, y = 100, speed = 150, sprite = love.graphics.newImage('char.png') }
walls  = {
{ fillMode = "fill", x = 50, y = 50, w = 100, h = 20, collide = true },
{ fillMode = "line", x = 50 + 100, y = 50, w = 100, h = 20, collide = false }
}
Any help would be greatly appreciated. Thanks!

TurtleP
Party member
Posts: 147
Joined: Thu Mar 22, 2012 9:20 pm
Contact:

### Re: Collision with rectangle freezes player?

try just doing

Code: Select all

function cols()
for i, wall in ipairs(walls) do
return CheckCollision(player.x, player.y, player.sprite:getWidth(), player.sprite:getHeight(), wall.x, wall.y, wall.w, wall.h) and wall.collide
end
end

Prole
Posts: 21
Joined: Wed Apr 15, 2015 10:51 pm

### Re: Collision with rectangle freezes player?

Code: Select all

function CheckCollision(x1,y1,w1,h1, x2,y2,w2,h2)
return x1 < x2+w2 and
x2 < x1+w1 and
y1 < y2+h2 and
y2 < y1+h1
end

change it to

Code: Select all

return x1 <= x2+w2 and
x2 <= x1+w1 and
y1 <= y2+h2 and
y2 <= y1+h1
end
It might be that your character is going into the wall because you are using < and > symbols, using <= and >= symbols should fix it is this is the problem
Good luck!

ntnick
Prole
Posts: 8
Joined: Tue Nov 11, 2014 4:51 pm

### Re: Collision with rectangle freezes player?

None of the fixes provided work.
I tried replacing my CheckCollision code with Cookie10Monster's and tested it. It didn't work.
Same with TurtleP's.

Party member
Posts: 509
Joined: Fri May 03, 2013 6:42 pm
Location: Germany

### Re: Collision with rectangle freezes player?

Your problem is that the player get stuck in the rectangle when colliding because your code say "as long as there is any collision dont move". You could try to calculate the future position of the player and use these values to check for a collision ( and stop the player before he actually collides with an object )

My method would be something like this :

Code: Select all

function player:update(dt)
if left then player:move(-player.speed*dt, 0)
elseif right then player:move(player.speed*dt, 0) end
end

function player:move(dx, dy)
local newx, newy = self.x + dx, self.y + dy
if not collision(newx, newy, player.width, player.height, other.x, other.y, other.width, other.height) then
player.x = newx
player.y = newy
end
end
(pseudo code)

This is the idea. here is a more advanced demo of it (hopefully it's kinda understandable).
Collision.love

ntnick
Prole
Posts: 8
Joined: Tue Nov 11, 2014 4:51 pm

### Re: Collision with rectangle freezes player?

MadByte wrote:Your problem is that the player get stuck in the rectangle when colliding because your code say "as long as there is any collision dont move". You could try to calculate the future position of the player and use these values to check for a collision ( and stop the player before he actually collides with an object )

My method would be something like this :

Code: Select all

function player:update(dt)
if left then player:move(-player.speed*dt, 0)
elseif right then player:move(player.speed*dt, 0) end
end

function player:move(dx, dy)
local newx, newy = self.x + dx, self.y + dy
if not collision(newx, newy, player.width, player.height, other.x, other.y, other.width, other.height) then
player.x = newx
player.y = newy
end
end
(pseudo code)

This is the idea. here is a more advanced demo of it (hopefully it's kinda understandable).
Collision.love
Mind if I fork your demo?