Keep getting bad arguments

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
D4rkwolf
Prole
Posts: 5
Joined: Wed Jun 12, 2013 6:53 pm

Keep getting bad arguments

Post 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
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Keep getting bad arguments

Post 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.
Shallow indentations.
D4rkwolf
Prole
Posts: 5
Joined: Wed Jun 12, 2013 6:53 pm

Re: Keep getting bad arguments

Post 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?
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Keep getting bad arguments

Post 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.
Shallow indentations.
D4rkwolf
Prole
Posts: 5
Joined: Wed Jun 12, 2013 6:53 pm

Re: Keep getting bad arguments

Post 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
	
User avatar
Boolsheet
Inner party member
Posts: 780
Joined: Wed Dec 29, 2010 4:57 am
Location: Switzerland

Re: Keep getting bad arguments

Post 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({}).
Shallow indentations.
D4rkwolf
Prole
Posts: 5
Joined: Wed Jun 12, 2013 6:53 pm

Re: Keep getting bad arguments

Post 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
	
User avatar
micha
Inner party member
Posts: 1083
Joined: Wed Sep 26, 2012 5:13 pm

Re: Keep getting bad arguments

Post 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).
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Keep getting bad arguments

Post by Robin »

Instead of table.remove(enemies,remEnemy(i)), do table.remove(enemies,remEnemy).
Help us help you: attach a .love.
Post Reply

Who is online

Users browsing this forum: 101Corp, Bing [Bot] and 3 guests