Collision with walls

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
Teshi
Prole
Posts: 11
Joined: Mon Feb 01, 2016 6:51 pm

Collision with walls

Post by Teshi » Sun Apr 10, 2016 9:24 pm

Hi im trying to do collision with walls myself but its just hitting the fan. It works kinda, but when i add more walls it just goes to shit. Could anyone offer any help? Im not the best coder and my head is just melting trying to solve this. The problem i think is because of the two "left" walls, collision works for one of them but not the other and i know its to do with how i reset the playercanwalk variable but i dont know how to write it in such a way that it works :(

Code: Select all

map =                                  
{
  walls = 
  {
    wall1 = 
    {
      id = 1, x = 100, y = 605, w = 190, h = 35, block = "up"
    },
    wall2 = 
    {
      id = 2, x = 300 - 40, y = 640-200, w = 35, h = 195, block = "left"
    },
    wall3 =
    {
      id = 3, x = 100, y = 735, w = 300, h = 35, block = "down"
    },
    wall4 =
    {
      id = 4, x = 65, y = 605, w = 35, h = 165, block = "left"
    },
    wall5 =
    {
      id = 5, x = 400, y = 440, w= 35, h = 330, block = "right"
    }
  }
}

function drawWalls(x, y, w, h) 
  love.graphics.setColor(50, 50, 200, 255)
  love.graphics.rectangle("fill", x, y, w, h)
end

function updateWalls()     
  local i,v
  for i,v in pairs(map.walls) do
    local px,py = player:getPos()
    local pxo, pyo = player:getOffset()
    local x, y, w, h, block = v.x, v.y, v.w, v.h, v.block 
    local col = checkCollision(px-pxo, py-pyo, player.width, player.height, x, y, w, h)
    if col == true then
      if block == "left" and player.canwalk.left == true then       
        player.canwalk.left = false                                                     
        
      elseif block == "up" then
        player.canwalk.up = false
        
      elseif block == "down" then
        player.canwalk.down = false
        
      elseif block == "right" then    
        player.canwalk.right = false
      end
    end
    
    if col == false then
      if block ~= "left" and player.canwalk.left == false then
        
        player.canwalk.left = true
      
      end
      if block == "right" then
        player.canwalk.right = true
      
      end
      if block == "up" then    
        player.canwalk.up = true
        
      end
      if block == "down" then
        player.canwalk.down = true
        
      end
    end
  end
end

User avatar
Vimm
Party member
Posts: 113
Joined: Wed Mar 16, 2016 8:14 pm

Re: Collision with walls

Post by Vimm » Mon Apr 11, 2016 8:24 am

Teshi wrote:Hi im trying to do collision with walls myself but its just hitting the fan. It works kinda, but when i add more walls it just goes to shit. Could anyone offer any help? Im not the best coder and my head is just melting trying to solve this. The problem i think is because of the two "left" walls, collision works for one of them but not the other and i know its to do with how i reset the playercanwalk variable but i dont know how to write it in such a way that it works :(

Code: Select all

map =                                  
{
  walls = 
  {
    wall1 = 
    {
      id = 1, x = 100, y = 605, w = 190, h = 35, block = "up"
    },
    wall2 = 
    {
      id = 2, x = 300 - 40, y = 640-200, w = 35, h = 195, block = "left"
    },
    wall3 =
    {
      id = 3, x = 100, y = 735, w = 300, h = 35, block = "down"
    },
    wall4 =
    {
      id = 4, x = 65, y = 605, w = 35, h = 165, block = "left"
    },
    wall5 =
    {
      id = 5, x = 400, y = 440, w= 35, h = 330, block = "right"
    }
  }
}

function drawWalls(x, y, w, h) 
  love.graphics.setColor(50, 50, 200, 255)
  love.graphics.rectangle("fill", x, y, w, h)
end

function updateWalls()     
  local i,v
  for i,v in pairs(map.walls) do
    local px,py = player:getPos()
    local pxo, pyo = player:getOffset()
    local x, y, w, h, block = v.x, v.y, v.w, v.h, v.block 
    local col = checkCollision(px-pxo, py-pyo, player.width, player.height, x, y, w, h)
    if col == true then
      if block == "left" and player.canwalk.left == true then       
        player.canwalk.left = false                                                     
        
      elseif block == "up" then
        player.canwalk.up = false
        
      elseif block == "down" then
        player.canwalk.down = false
        
      elseif block == "right" then    
        player.canwalk.right = false
      end
    end
    
    if col == false then
      if block ~= "left" and player.canwalk.left == false then
        
        player.canwalk.left = true
      
      end
      if block == "right" then
        player.canwalk.right = true
      
      end
      if block == "up" then    
        player.canwalk.up = true
        
      end
      if block == "down" then
        player.canwalk.down = true
        
      end
    end
  end
end

Why dont you test the collision using the method on the wiki? https://love2d.org/wiki/BoundingBox.lua

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

Teshi
Prole
Posts: 11
Joined: Mon Feb 01, 2016 6:51 pm

Re: Collision with walls

Post by Teshi » Mon Apr 11, 2016 8:28 am

Vimm wrote:
Why dont you test the collision using the method on the wiki? https://love2d.org/wiki/BoundingBox.lua

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
The collision does work and I am using that function but my issue is that when i add 2 walls that block movement in the same direction, only one of them works.

User avatar
DaedalusYoung
Party member
Posts: 402
Joined: Sun Jul 14, 2013 8:04 pm

Re: Collision with walls

Post by DaedalusYoung » Mon Apr 11, 2016 10:33 am

Set the player.canwalk booleans all to true before you start the for loop, and get rid of them in the if col == false block. My guess is that alone should work, but you could also try that once you determined that there is a collision, you iterate the walls table, then as soon as you've found the block direction you break out of that loop. The problem is that you find a collision, so you set col to true and search the table to determine the block direction and set player.canwalk to false. All fine, but then you keep searching the walls, only to find there is no collision on later tiles, so you reset the player.canwalk back to true. If you'd break out of the loop after you've found the first collision, no further check will be done, so the player.canwalk boolean will not be reset.

Also...

Code: Select all

local i,v
This is completely unnecessary. :)

Teshi
Prole
Posts: 11
Joined: Mon Feb 01, 2016 6:51 pm

Re: Collision with walls

Post by Teshi » Mon Apr 11, 2016 3:28 pm

DaedalusYoung wrote:Set the player.canwalk booleans all to true before you start the for loop, and get rid of them in the if col == false block. My guess is that alone should work, but you could also try that once you determined that there is a collision, you iterate the walls table, then as soon as you've found the block direction you break out of that loop. The problem is that you find a collision, so you set col to true and search the table to determine the block direction and set player.canwalk to false. All fine, but then you keep searching the walls, only to find there is no collision on later tiles, so you reset the player.canwalk back to true. If you'd break out of the loop after you've found the first collision, no further check will be done, so the player.canwalk boolean will not be reset.

Also...

Code: Select all

local i,v
This is completely unnecessary. :)
Oh wow thank you dude, its working now! Oh right, I think I read it in a tutorial for shooting and since then it became habit to do local i,v.

User avatar
DaedalusYoung
Party member
Posts: 402
Joined: Sun Jul 14, 2013 8:04 pm

Re: Collision with walls

Post by DaedalusYoung » Mon Apr 11, 2016 8:42 pm

Glad it works :)

Yeah, you don't need to declare them as local, they automatically are:
http://www.lua.org/pil/4.3.5.html wrote:The loop variables are local to the loop body (...)

Post Reply

Who is online

Users browsing this forum: No registered users and 23 guests