Collision with rectangle freezes player?

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
ntnick
Prole
Posts: 8
Joined: Tue Nov 11, 2014 4:51 pm

Collision with rectangle freezes player?

Post 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!
:awesome: :x
User avatar
TurtleP
Party member
Posts: 147
Joined: Thu Mar 22, 2012 9:20 pm
Contact:

Re: Collision with rectangle freezes player?

Post 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
Cookie10monster
Prole
Posts: 21
Joined: Wed Apr 15, 2015 10:51 pm

Re: Collision with rectangle freezes player?

Post 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!
ntnick
Prole
Posts: 8
Joined: Tue Nov 11, 2014 4:51 pm

Re: Collision with rectangle freezes player?

Post 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.
:awesome: :x
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: Collision with rectangle freezes player?

Post 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
ntnick
Prole
Posts: 8
Joined: Tue Nov 11, 2014 4:51 pm

Re: Collision with rectangle freezes player?

Post 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:
:awesome: :x
User avatar
MadByte
Party member
Posts: 533
Joined: Fri May 03, 2013 6:42 pm
Location: Braunschweig, Germany

Re: Collision with rectangle freezes player?

Post by MadByte »

Sure, do whatever you want with it.
Post Reply

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 203 guests