Page 1 of 1

floor not working

Posted: Fri Jun 20, 2014 10:49 pm
by thewifitree
I started a platformer today and everything was going fine, but I found an issue with the floor. The player slowly falls through the floor and I can't figure out why this is happening. Please help!

Code: Select all

block = {}
player = {}

--load the images
backgroung_img = love.graphics.newImage("textures/photo.png")
block_img = love.graphics.newImage("textures/block.png")
player_img = love.graphics.newImage("textures/player.png")

function love.load()
	player.x = 0
	player.y = 0
	
	table.insert(block, {x = 0, y = 50})
	table.insert(block, {x = 50, y = 50})
end

function love.draw()
	x, y = love.mouse.getPosition()
	
	--draw the background
	love.graphics.setColor(255, 130, 130, 255)
	love.graphics.draw(backgroung_img, 0, 0)
	
	--draw the blocks
	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(block_img, x, y)
	for i, v in pairs(block) do 
		love.graphics.draw(block_img, block[i].x, block[i].y)
	end
	
	--draw the player
	love.graphics.setColor(255, 130, 130, 255)
	love.graphics.draw(player_img, player.x, player.y)
end

function love.update(dt)
	x, y = love.mouse.getPosition()
	if love.mouse.isDown("l") then
		table.insert(block, {x = x, y = y})
	end
	
	--Gravity!
	for i, v in pairs(block) do 
		if CheckCollision(player.x, player.y, 50, 50, block[i].x, block[i].y, 50, 50) then	
		else
			player.y = player.y + 10*dt
		end
	end
	
	--move left
	if love.keyboard.isDown("left") then
		player.x = player.x - 190*dt
	end
	
	--move right
	if love.keyboard.isDown("right") then
		player.x = player.x + 190*dt
	end
	
end

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

Re: floor not working

Posted: Fri Jun 20, 2014 10:58 pm
by Zilarrezko
Try instead that if the playerY + (whatever you're using for gravity) is inside the box then don't add the player's Y

The code would be that.

Code: Select all

for i, v in pairs(block) do 
      if CheckCollision(player.x, player.y + 10*dt, 50, 50, block[i].x, block[i].y, 50, 50) then   
      else
         player.y = player.y + 10*dt
      end
   end
I haven't tested this with that code, but that's the method I use. It's not pixel perfect, but it works for me.

Re: floor not working

Posted: Fri Jun 20, 2014 11:02 pm
by moikmellah
This is problematic:

Code: Select all

--Gravity!
for i, v in pairs(block) do
   if CheckCollision(player.x, player.y, 50, 50, block[i].x, block[i].y, 50, 50) then   
   else
      player.y = player.y + 10*dt
   end
end
What you're effectively doing here is checking EVERY block in the level, and for each block checked, moving downward if there's no collision. Instead, try looping through your blocks to check for collisions, storing the result in a single boolean variable, and then check that variable only once at the end for movement:

Code: Select all

local collBool = false

for i, v in pairs(block) do
   if collBool then break end
   collBool = collBool or CheckCollision(player.x, player.y, 50, 50, block[i].x, block[i].y, 50, 50)
end

if not(collBool) then
   player.y = player.y + 10*dt
end

Re: floor not working

Posted: Fri Jun 20, 2014 11:07 pm
by thewifitree
I tried this code, and now the players y axis doesn't change at all :?

Re: floor not working

Posted: Fri Jun 20, 2014 11:17 pm
by Zilarrezko
Ah that's correct!
my bad, my bad. Go with moikmellah's code there. (I would still put that thing i mentioned in the check collision personally. But it probably won't matter that much. Of course that depends on what you're implementing.)
I tried this code, and now the players y axis doesn't change at all :?
Let me try and fix it.

Code: Select all

local collision = false

for i= 1, #block do
   if collision then break end
   collision = CheckCollision(player.x, player.y, 50, 50, block[i].x, block[i].y, 50, 50)
end

if collision == false then
   player.y = player.y + 10*dt
end
probably had something to do with that or, or something.

Re: floor not working

Posted: Fri Jun 20, 2014 11:49 pm
by thewifitree
I tried this out and the bug still isn't fixed. Maybe I'm placing the lines of code you gave me in the wrong spot?

Code: Select all

block = {}
player = {}
local collision = false

--load the images
background_img = love.graphics.newImage("textures/photo.png")
block_img = love.graphics.newImage("textures/block.png")
player_img = love.graphics.newImage("textures/player.png")

function love.load()
	player.x = 0
	player.y = 0
	
	table.insert(block, {x = 0, y = 50})
	table.insert(block, {x = 50, y = 50})
end

function love.draw()
	x, y = love.mouse.getPosition()
	
	--draw the background
	love.graphics.setColor(255, 130, 130, 255)
	love.graphics.draw(background_img, 0, 0)
	
	--draw the blocks
	love.graphics.setColor(255, 255, 255, 255)
	love.graphics.draw(block_img, x, y)
	for i, v in pairs(block) do 
		love.graphics.draw(block_img, block[i].x, block[i].y)
	end
	
	--draw the player
	love.graphics.setColor(255, 130, 130, 255)
	love.graphics.draw(player_img, player.x, player.y)
end

function love.update(dt)
	x, y = love.mouse.getPosition()
	if love.mouse.isDown("l") then
		table.insert(block, {x = x, y = y})
	end
	
	--Gravity!
	for i= 1, #block do
		if collision then break end
	collision = CheckCollision(player.x, player.y, 50, 50, block[i].x, block[i].y, 50, 50)
	end

	if collision == false then
		player.y = player.y + 10*dt
	end
	
	--move left
	if love.keyboard.isDown("left") then
		player.x = player.x - 190*dt
	end
	
	--move right
	if love.keyboard.isDown("right") then
		player.x = player.x + 190*dt
	end
	
end

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

Re: floor not working

Posted: Sat Jun 21, 2014 12:06 am
by Zilarrezko
Put the local collision variable just before that for loop is run. A local variable when initiated in a function is cleared from memory after the function is done running. When you have it in the file like you have it there outside of the functions... I believe the functions can't see it.

So like this

Code: Select all

function love.update(dt)
   x, y = love.mouse.getPosition()
   if love.mouse.isDown("l") then
      table.insert(block, {x = x, y = y})
   end
   
   --Gravity!
   local collision = false --Right there
   for i= 1, #block do
      if collision then break end
   collision = CheckCollision(player.x, player.y, 50, 50, block[i].x, block[i].y, 50, 50)
   end

   if collision == false then
      player.y = player.y + 10*dt
   end
   
   --move left
   if love.keyboard.isDown("left") then
      player.x = player.x - 190*dt
   end
   
   --move right
   if love.keyboard.isDown("right") then
      player.x = player.x + 190*dt
   end
   
end

Re: floor not working

Posted: Sat Jun 21, 2014 12:33 am
by thewifitree
Thank you so much!