Page 1 of 1

Keep getting bad arguments

Posted: Wed Jun 12, 2013 7:16 pm
by D4rkwolf
I keep getting an error

lua.main:40: bad argument 'ipairs' (table expected, got nil)

I have no clue why it's saying this

Code: Select all

function love.load()
	bg = love.graphics.newImage("bg.png")
	
	player = {} --new table for player
	player.x = 300 -- x,y coordinates of the player
	player.y = 450
	player.speed = 100
	
	enemies = {}
	
	for i=0,7 do
	enemy = {}
	enemy.width = 40
	enemy.height = 20
	enemy.x = i * (enemy.width + 60) + 100
	enemy.y = enemy.height + 100
	table.insert (enemies, enemy)
	end
end

function love.keyreleased(key)
	if (key== " ") then
		shoot()
	end
end
	

function love.update (dt)
--keyboard for player
	if love.keyboard.isDown("left") then
	  player.x = player.x - player.speed*dt
	elseif love.keyboard.isDown("right") then
	  player.x = player.x + player.speed*dt
	  end
	  
	  local remEnemy = {}
	  local remShot = {}
	  
	  --update the shots
	  for i,v in ipairs(player.shots) do
	  
		--move them up up up up
		v.y = v.y - dt * 100
		
		--mark shots that are not visible for removal
		if v.y < 0 then
			table.insert(remShot, i)
		end
		
		--collision detection enemy
		for ii,vv in ipairs(enemies) do
			if CheckCollision(v.x,v.y,2,5,vv.x,vv.y,vv.width,vv.height) then
			
			--mark that enemy for removal
			table.insert(remEnemy, ii)
			--remove shot
			table.insert(remShot, i)
			end
		end
	end
	
	--remove the marked enemies
	for i,v in ipairs(remEnemy) do
		table.remove(enemies,v)
	end

	for i,v in ipairs(remShot) do
		table.remove(player.shots, v)
	end
	
	--update enemies
	for i,v in ipairs(enemies) do
		--slow fall
		v.y = v.y+dt
		--check collision of ground
		if v.y > 465 then
			--lose
		end
	end
end
	


function love.draw()
	--draw that BG
	love.graphics.setColor(255,255,255,255)
	love.graphics.draw(bg)
	
	--ground
	love.graphics.setColor(0,255,0,255)
	love.graphics.rectangle("fill", 0, 465, 800, 150)

	--player sprite
	love.graphics.setColor (255,255,0,255)
	love.graphics.rectangle ("fill", player.x, player.y, 30, 15)
	
	--player shots
	loge.graphics.setColor(255,255,255,255)
	for i,v in ipairs(player.shots) do
		love.graphics.rectangle("fill", v.x,v.y, 2, 5)
	end	
end

function shoot()

	local shot = {}
	shot.x = player.x+player.width/2
	shot.y = player.y
	
	table.insert(player.shots, shot)
	end
	
	--collision detection function
	--checks if a and b overlap
	--w and h mean width and height
	
function CheckCollision(ax1,ay1,aw,ah, bx1,by1,bw,bh)
		
		local ax2,ay2,bx2,by2 = ax1 + aw, ay1+ ah, bx1 + bw, by1 + bh
		return ax1 > bx2 and ax2 > bx1 and ay1 > by2 and ay2 > by1
	end

Re: Keep getting bad arguments

Posted: Wed Jun 12, 2013 7:37 pm
by Boolsheet
You try to iterate over the table in player["shots"], but you never assign something to there.

You want to create it in love.load.

Code: Select all

function love.load()
   bg = love.graphics.newImage("bg.png")
   
   player = {} --new table for player
   player.x = 300 -- x,y coordinates of the player
   player.y = 450
   player.speed = 100
   player.shots = {}
Later in the code you also use player.width but never set it.

Re: Keep getting bad arguments

Posted: Wed Jun 12, 2013 8:25 pm
by D4rkwolf
I'm still getting the same issue after amending the code except it's main.lua:8: attempt to call shots (nil value)...Maybe I just don't have a clue as to what I'm doing. how could I make this work properly?

Re: Keep getting bad arguments

Posted: Wed Jun 12, 2013 9:28 pm
by Boolsheet
It's not the same issue if it is a different error. :P

I think (I can't be sure because you didn't show the code you have now) you used parentheses () instead of braces {}. Parentheses are used for function calls, braces are used for the table constructor.

Re: Keep getting bad arguments

Posted: Wed Jun 12, 2013 9:34 pm
by D4rkwolf
Here's what I have

Code: Select all

function love.load()
	bg = love.graphics.newImage("bg.png")
	
	player = {} --new table for player
	player.x = 300 -- x,y coordinates of the player
	player.y = 450
	player.speed = 100
	player.shots {}
	enemies = {}
	
	for i=0,7 do
	enemy = {}
	enemy.width = 40
	enemy.height = 20
	enemy.x = i * (enemy.width + 60) + 100
	enemy.y = enemy.height + 100
	table.insert (enemies, enemy)
	end
end

function love.keyreleased(key)
	if (key== " ") then
		shoot()
	end
end
	

function love.update (dt)
--keyboard for player
	if love.keyboard.isDown("left") then
	  player.x = player.x - player.speed*dt
	elseif love.keyboard.isDown("right") then
	  player.x = player.x + player.speed*dt
	  end
	  
	  local remEnemy = {}
	  local remShot = {}
	  
	  --update the shots
	  for i,v in ipairs(player.shots) do
	  
		--move them up up up up
		v.y = v.y - dt * 100
		
		--mark shots that are not visible for removal
		if v.y < 0 then
			table.insert(remShot, i)
		end
		
		--collision detection enemy
		for ii,vv in ipairs(enemies) do
			if CheckCollision(v.x,v.y,2,5,vv.x,vv.y,vv.width,vv.height) then
			
			--mark that enemy for removal
			table.insert(remEnemy, ii)
			--remove shot
			table.insert(remShot, i)
			end
		end
	end
	
	--remove the marked enemies
	for i,v in ipairs(remEnemy) do
		table.remove(enemies,v)
	end

	for i,v in ipairs(remShot) do
		table.remove(player.shots, v)
	end
	
	--update enemies
	for i,v in ipairs(enemies) do
		--slow fall
		v.y = v.y+dt
		--check collision of ground
		if v.y > 465 then
			--lose
		end
	end
end
	


function love.draw()
	--draw that BG
	love.graphics.setColor(255,255,255,255)
	love.graphics.draw(bg)
	
	--ground
	love.graphics.setColor(0,255,0,255)
	love.graphics.rectangle("fill", 0, 465, 800, 150)

	--player sprite
	love.graphics.setColor (255,255,0,255)
	love.graphics.rectangle ("fill", player.x, player.y, 30, 15)
	
	--player shots
	loge.graphics.setColor(255,255,255,255)
	for i,v in ipairs(player.shots) do
		love.graphics.rectangle("fill", v.x,v.y, 2, 5)
	end	
end

function shoot()

	local shot = {}
	shot.x = player.x+player.width/2
	shot.y = player.y
	
	table.insert(player.shots, shot)
	end
	
	--collision detection function
	--checks if a and b overlap
	--w and h mean width and height
	
function CheckCollision(ax1,ay1,aw,ah, bx1,by1,bw,bh)
		
		local ax2,ay2,bx2,by2 = ax1 + aw, ay1+ ah, bx1 + bw, by1 + bh
		return ax1 > bx2 and ax2 > bx1 and ay1 > by2 and ay2 > by1
	end
	

Re: Keep getting bad arguments

Posted: Wed Jun 12, 2013 9:46 pm
by Boolsheet
I wrote

Code: Select all

player.shots = {}
You wrote

Code: Select all

player.shots {}
For Lua, this means it should call player.shots with a new table. If you ask yourself why that works, it's syntax sugar. Lua accepts table constructors and string literals for a function call without the parentheses. So it's short for player.shots({}).

Re: Keep getting bad arguments

Posted: Wed Jun 12, 2013 9:54 pm
by D4rkwolf
I got it working!...now I can't figure out why no enemies are drawn, I think I have no idea what I've done

Code: Select all

function love.load()
	bg = love.graphics.newImage("bg.png")
	
	player = {} --new table for player
	player.width = 40
	player.x = 300 -- x,y coordinates of the player
	player.y = 450
	player.speed = 100
	player.shots = {}
	enemies = {}
	
	for i=0,7 do
	enemy = {}
	enemy.width = 40
	enemy.height = 20
	enemy.x = i * (enemy.width + 60) + 100
	enemy.y = enemy.height + 100
	table.insert (enemies, enemy)
	end
end

function love.keyreleased(key)
	if (key== " ") then
		shoot()
	end
end
	

function love.update (dt)
--keyboard for player
	if love.keyboard.isDown("left") then
	  player.x = player.x - player.speed*dt
	elseif love.keyboard.isDown("right") then
	  player.x = player.x + player.speed*dt
	  end
	  
	  local remEnemy = {}
	  local remShot = {}
	  
	  --update the shots
	  for i,v in ipairs(player.shots) do
	  
		--move them up up up up
		v.y = v.y - dt * 100
		
		--mark shots that are not visible for removal
		if v.y < 0 then
			table.insert(remShot, i)
		end
		
		--collision detection enemy
		for ii,vv in ipairs(enemies) do
			if CheckCollision(v.x,v.y,2,5,vv.x,vv.y,vv.width,vv.height) then
			
			--mark that enemy for removal
			table.insert(remEnemy, ii)
			--remove shot
			table.insert(remShot, i)
			end
		end
	end
	
	--remove the marked enemies
	for i,v in ipairs(remEnemy) do
		table.remove(enemies,v)
	end

	for i,v in ipairs(remShot) do
		table.remove(player.shots, v)
	end
	
	--update enemies
	for i,v in ipairs(enemies) do
		--slow fall
		v.y = v.y+dt
		--check collision of ground
		if v.y > 465 then
			--lose
		end
	end
end
	


function love.draw()
	--draw that BG
	love.graphics.setColor(255,255,255,255)
	love.graphics.draw(bg)
	
	--ground
	love.graphics.setColor(0,255,0,255)
	love.graphics.rectangle("fill", 0, 465, 800, 150)

	--player sprite
	love.graphics.setColor (255,255,0,255)
	love.graphics.rectangle ("fill", player.x, player.y, 30, 15)
	
	--player shots
	love.graphics.setColor(255,255,255,255)
	for i,v in ipairs(player.shots) do
		love.graphics.rectangle("fill", v.x,v.y, 2, 5)
	end	
end

function shoot()

	local shot = {}
	shot.x = player.x+player.width/2
	shot.y = player.y
	
	table.insert(player.shots, shot)
	end
	
	--collision detection function
	--checks if a and b overlap
	--w and h mean width and height
	
function CheckCollision(ax1,ay1,aw,ah, bx1,by1,bw,bh)
		
		local ax2,ay2,bx2,by2 = ax1 + aw, ay1+ ah, bx1 + bw, by1 + bh
		return ax1 > bx2 and ax2 > bx1 and ay1 > by2 and ay2 > by1
	end
	

Re: Keep getting bad arguments

Posted: Thu Jun 13, 2013 6:25 am
by micha
D4rkwolf wrote:I got it working!...now I can't figure out why no enemies are drawn.
In the code you posted, there is nothing, that draws any enemies. You only draw the background, the player and the shot.

Here is an unrelated remark. When you remove objects from a table with table.remove, then instead of this:

Code: Select all

   for i,v in ipairs(remEnemy) do
      table.remove(enemies,v)
   end
You should do this:

Code: Select all

for i = #remEnemy,1,-1 do
  table.remove(enemies,remEnemy(i))
end
The reason is, that by table.remove you change the index of all following elements. So if you have three elements (1,2,3) and want to remove the first and second then after the first removal you have (2,3) and the would remove the 3 and get (2) instead of (3).

Re: Keep getting bad arguments

Posted: Thu Jun 13, 2013 3:58 pm
by Robin
Instead of table.remove(enemies,remEnemy(i)), do table.remove(enemies,remEnemy).