Page 1 of 1

Collision with rectangle freezes player?

Posted: Tue Sep 08, 2015 12:42 am
by ntnick
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
In the love.load function the player and walls are loaded:

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!

Re: Collision with rectangle freezes player?

Posted: Tue Sep 08, 2015 3:37 am
by TurtleP
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

Re: Collision with rectangle freezes player?

Posted: Tue Sep 08, 2015 2:47 pm
by Cookie10monster
Where your code does

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!

Re: Collision with rectangle freezes player?

Posted: Tue Sep 08, 2015 5:06 pm
by ntnick
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.

Re: Collision with rectangle freezes player?

Posted: Tue Sep 08, 2015 7:36 pm
by MadByte
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

Re: Collision with rectangle freezes player?

Posted: Tue Sep 08, 2015 9:48 pm
by ntnick
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? :awesome:

Re: Collision with rectangle freezes player?

Posted: Tue Sep 08, 2015 9:54 pm
by MadByte
Sure, do whatever you want with it.