[SOLVED] Problem of local nil value with collision

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.
User avatar
Le Codex
Prole
Posts: 31
Joined: Thu Feb 09, 2017 10:56 am
Location: France
Contact:

[SOLVED] Problem of local nil value with collision

Post by Le Codex »

Hi. I'm a new learner in Löve and I'm actually learning with the tutorials of Sheepolution. I started mking a little game where you shoot at red squares, but it happens that sometimes the programm fails and show me this error:
main.lua:107: attempt to index local 'obj2' (a nil value)


Traceback

main.lua:107: in function 'checkCollision'
main.lua:75: in function 'update'
[C]: in function 'xpcall'
This error doesn't occur every time, and I didn't find a way to trigger it every time. I'm adding my code so you could please help me solve this problem:

main:

Code: Select all

function love.load()
  Object = require "classic"
  require "player"
  require "wall"
  require "enemy"
  require "gun"
  require "bullet"
  
  walls = {}
  bullets = {}
  player = Player()
  enemies= {}
  gun = Gun()
  
  bulletTimer = 0
  windowWidth = love.graphics.getWidth()
  windowHeight = love.graphics.getHeight()
  
  for i=1,10 do
    table.insert(walls, Wall())
  end
  
  for i=1,3 do
    table.insert(enemies, Enemy())
  end
end

function love.update(dt)
  bulletTimer = bulletTimer - 2 * dt
  player:update(dt)
  gun:update(dt)
  
  for i=#enemies,1,-1 do
    enemies[i]:update(dt)
    
    if checkCollision(player, enemies[i]) then
      player.x = 0
      player.y = 0
    end
  end
  
  for i=#walls,1,-1 do
    if checkCollision(player, walls[i]) then
      player.y = player.y - player.yspeed
      player.x = player.x - player.xspeed
      walls[i].color = {255, 255, 255, 255}
    end
    
    for j=#enemies,1,-1 do
      if checkCollision(enemies[j], walls[i]) then
        enemies[j].xspeed = - enemies[j].xspeed
      end
    end
    
    for j=#bullets,1,-1 do
      if checkCollision(bullets[j], walls[i]) then
        table.remove(bullets, j)
      end
    end
  end
  
  for i=#bullets,1,-1 do
    nope = 0
    bullets[i]:update(dt)
  
    if bullets[i].x > windowWidth or bullets[i].y > windowHeight or bullets[i].x < 0 or bullets[i].y < 0 then
       table.remove(bullets, i)
       nope = 1
    end
    
    if nope == 0 then
      for j=#enemies,1,-1 do
        if checkCollision(enemies[j], bullets[i]) then
          table.remove(enemies, j)
          table.remove(bullets, i)
        end
      end
    end
  end
end

function love.draw()
  for i=1,#walls do
    walls[i]:draw()
  end
  
  for i=1,#bullets do
    bullets[i]:draw()
  end
  
  for i=1,#enemies do
    enemies[i]:draw()
  end
  
  player:draw()
  gun:draw()
end

function checkCollision(obj, obj2)
  local obj_left = obj.x
  local obj_right = obj.x + obj.width
  local obj_top = obj.y
  local obj_bottom = obj.y + obj.height

  local obj2_left = obj2.x
  local obj2_right = obj2.x + obj2.width
  local obj2_top = obj2.y
  local obj2_bottom = obj2.y + obj2.height
  
  if obj_right > obj2_left and
  obj_left < obj2_right and
  obj_bottom > obj2_top and
  obj_top < obj2_bottom then
    return true
  else
    return false
  end
end

function createBullet(x, y)
  table.insert(bullets, Bullet())
  bullets[#bullets].x = x
  bullets[#bullets].y = y
  
  if player.dir == 1 then
    bullets[#bullets].yspeed = -1000
    bullets[#bullets].xspeed = 0
  elseif player.dir == 2 then
    bullets[#bullets].yspeed = 0
    bullets[#bullets].xspeed = 1000
  elseif player.dir == 3 then
    bullets[#bullets].yspeed = 1000
    bullets[#bullets].xspeed = 0
  elseif player.dir == 4 then
    bullets[#bullets].yspeed = 0
    bullets[#bullets].xspeed = -1000
  end
end
I'm using classic.lua to manage Objects

bullet:

Code: Select all

Bullet = Object:extend()

function Bullet:new()
  self.width = 10
  self.height = 10
end

function Bullet:update(dt)
  self.x = self.x + self.xspeed * dt
  self.y = self.y + self.yspeed * dt
end

function Bullet:draw()
  love.graphics.setColor(200, 200, 200, 255)
  love.graphics.rectangle("fill",self.x, self.y, self.width, self.height)
end
enemy:

Code: Select all

Enemy = Object:extend()

function Enemy:new()
  windowWidth = love.graphics.getWidth()
  windowHeight = love.graphics.getHeight()
  
  self.x = love.math.random(100, windowWidth - 100)
  self.y = love.math.random(100, windowHeight - 100)
  self.width = 50
  self.height = 50
  self.xspeed = 50
  self.killed = 0
end

function Enemy:draw()
  love.graphics.setColor(255, 0, 0, 255)
  love.graphics.rectangle("fill", self.x, self.y, self.width, self.height)
end

function Enemy:update(dt)
  self.x = self.x + self.xspeed * dt
  if self.x < 0 then
    self.xspeed = 50
    self.x = 0
  end
  if self.x + self.width > windowWidth then
    self.xspeed = - 50
    self.x = windowWidth - self.width
  end
end
Tell me if you find a solution or if I need to add the code of the player :) .
Last edited by Le Codex on Sun Feb 12, 2017 9:05 am, edited 1 time in total.

Code: Select all

if your.timeSpeed > 0 then universe:update(dt) else universe:destroy() end
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: Problem of local nil value with collision

Post by Beelz »

I believe your problem is this:

Code: Select all

  for i=#bullets,1,-1 do
    nope = 0
    bullets[i]:update(dt)
  
    if bullets[i].x > windowWidth or bullets[i].y > windowHeight or bullets[i].x < 0 or bullets[i].y < 0 then
       table.remove(bullets, i)
       nope = 1
    end
    
    if nope == 0 then
      for j=#enemies,1,-1 do
        if checkCollision(enemies[j], bullets[i]) then
          table.remove(enemies, j)
          table.remove(bullets, i)
        end
      end
    end
  end
What happens is that you remove a bullet, then try to see if it collides after it no longer exists. What I do is give every object a 'dead' variable. When I want it gone, I set 'self.dead = true'. At the very end of the update cycle, I iterate once more removing any objects that have been tagged for removal. This way I don't need to reverse iterate, and it doesn't throw nil errors.

Also, it is easier for anyone helping if you provide a .love file. I threw your main.lua into my editor and the line numbers didn't match up with your traceback, so this is really just my best guess at what I think happened.

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
User avatar
Le Codex
Prole
Posts: 31
Joined: Thu Feb 09, 2017 10:56 am
Location: France
Contact:

Re: Problem of local nil value with collision

Post by Le Codex »

Thanks for your quick response!
I'll try adding the .love file for my new questions or problems.

The thing is that I already fixed that problem with the "nope" variable: If the bullet hits a wall or exits the screen, it's removed and the nope value is set to 1. The part with CheckCollision(enemy, bullet) cannot be executed if the nope value is not 0, which is its value when the for loop loops.

To make researches easier, I add the .love file. Arrow keys to move, space to shoot, red squares are enemies and walls are invisibles unless you touch them.

(I'm French so the comments and the name of the game are in French, but they aren't important : It's simply "Game" and the names of the parts of the code)
Attachments
Jeu.love
(8.53 KiB) Downloaded 128 times

Code: Select all

if your.timeSpeed > 0 then universe:update(dt) else universe:destroy() end
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: Problem of local nil value with collision

Post by Beelz »

I think you uploaded the wrong files. This is a scramble puzzle. :awesome:

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
User avatar
Le Codex
Prole
Posts: 31
Joined: Thu Feb 09, 2017 10:56 am
Location: France
Contact:

Re: Problem of local nil value with collision

Post by Le Codex »

I've never compliated my files into a .love programm, I'm sorry :? .
I think you should open it with 7zip or something like this and start from main.lua, then you could go through the "require" . The names of the other parts are simply what they're used to. The Panda image is useless, so don't mind it.
Thanks for spending time tring to solve my problem, I also keep searching why :3 !
Also, I forgot to say that I use an old version of löve, 0.9.0, due to the very limited capacities of my PC :cry:

Code: Select all

if your.timeSpeed > 0 then universe:update(dt) else universe:destroy() end
User avatar
Beelz
Party member
Posts: 234
Joined: Thu Sep 24, 2015 1:05 pm
Location: New York, USA
Contact:

Re: Problem of local nil value with collision

Post by Beelz »

Hmm that's odd. When I ran your love file this is what I saw(see image below)... That's why I said you uploaded the wrong game. Then I can only open the zip file with 7-zip. After I unzipped and re-zipped with the basic windows utility, it loaded the game right. Not really sure what happened there. :shock:
jeu.png
jeu.png (283.33 KiB) Viewed 8339 times
It's getting late here so I'll have to take an actual look at it tomorrow. I haven't even seen the code yet, I just wanted to say that it's fine to develop in v0.9, but keep in mind most people are using v0.10 which has subtle differences such as the callbacks' parameters. Up until about 2 months ago, I was stuck on an old rig that wasn't capable of running the new versions. To ensure that people didn't need to edit the file to test it out, I did things like this:

Code: Select all

-- for example in kepressed:
if b == 'l' or b == 1 then -- checking against v0.9 and v0.10 
	-- do whatever
end

-- Edit
I'm not sure what's going on with the code block, but the formatting isn't working. :huh: Maybe my computer is just messing with me today.

Code: Select all

if self:hasBeer() then self:drink()
else self:getBeer() end
GitHub -- Website
User avatar
zorg
Party member
Posts: 3449
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Problem of local nil value with collision

Post by zorg »

7z is not zip, they're different compressors; even if some 7z might work with löve, there's no guarantee. Just use plain zips. (Hint: 7zip can iirc export to plain old zip as well)
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
User avatar
Le Codex
Prole
Posts: 31
Joined: Thu Feb 09, 2017 10:56 am
Location: France
Contact:

Re: Problem of local nil value with collision

Post by Le Codex »

Euuuh.... I've nothing to say. I simply don't know why it does this. My game don't use any text functions, so this is really weird :ultrashocked: .
I'll search if it has happened to anyone else, because there is no reason to do this.

(For me when I launch the downloaded game when it was compressed with 7z, it gives me an instantanious error:
boot.lua:374: module 'main' not found:
no field package.preload['main']
no file 'main.dll' in LOVE paths.
no file '.\main.lua'
no file 'C:\Program Files\LOVE\lua\main.lua'
no file 'C:\Program Files\LOVE\lua\main\init.lua'
no file '.\main.dll'
no file 'C:\Program Files\LOVE\main.dll'
no file 'C:\Program Files\LOVE\loadall.dll'

Traceback

[C]: in function 'require'
[C]: in function 'xpcall'
The game works normally if it is in the file with the uncompressed .lua files, and uninstalling and reinstalling LÖVE doesn't do anything... :? )

However, thanks for telling me the problem with 7z, I add the version compressed with the original zipper, and I tested it it works.


(Just one question out of the question: Am I forced to have an "Obey" word in my avatar?)
Attachments
jeu (2).love
(3.11 KiB) Downloaded 116 times

Code: Select all

if your.timeSpeed > 0 then universe:update(dt) else universe:destroy() end
Zireael
Party member
Posts: 139
Joined: Fri Sep 02, 2016 10:52 am

Re: Problem of local nil value with collision

Post by Zireael »

The version works indeed. 7z can compress to .zip format no problem, but I usually do:
right click on files in windows explorer->Send to->Zip package
User avatar
zorg
Party member
Posts: 3449
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: Problem of local nil value with collision

Post by zorg »

Le Codex wrote: Sat Feb 11, 2017 10:39 am(Just one question out of the question: Am I forced to have an "Obey" word in my avatar?)
(You're not forced, but you're missing out on the joke if you don't :3)
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
Post Reply

Who is online

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