Page 1 of 1

Cant find the error in my code. "attempt to index global `self´ (a nil value)"

Posted: Sun Feb 03, 2019 10:10 pm
by Koelpimo
Hello!

I am very new to programming but I wanted to make a small own game so I learned JavaScript first and now Lua. I have written my code and it worked well until I wanted to do the code of the playable character into a library (classic.lua; class) https://github.com/rxi/classic/blob/master/classic.lua

Now my code won´t work but i cant find the error. Heres the .love file.

I hope you can help me and thank you in advance! :)

Re: Cant find the error in my code. "attempt to index global `self´ (a nil value)"

Posted: Mon Feb 04, 2019 10:41 am
by pgimeno
Hi, welcome to the forums.

There are a number of issues in your code. One is that there is an imbalance of if...end inside function Butterfly:update(), which makes it end prematurely, causing the rest of the code execute before calling the function. That's what's causing the first error. Try to be rigorous with the pairing of each 'if' with its corresponding 'elseif' or 'else' or 'end' at the same indentation, and also with the number of indentations, so it's easier for you to catch these problems. When being rigorous about the indentation, your code looks like this (I'm using two spaces for each, you can use as many as you want as long as you are consistent; 4 is a common convention):

Code: Select all

function Butterfly:update(dt)

  local  currentFrame = currentFrame + 10 * dt
  if currentFrame >= 14 then
    currentFrame = 1

    local frame_width = 64
    local frame_height = 64
    maxFrames = 13
    currentFrame = 1
    for i = 0, 3 do
      for j = 0, 3 do
        table.insert(frames, love.graphics.newQuad(j * frame_width, i * frame_height, frame_width, frame_height, self.width, self.height))
        if #frames == maxFrames then
          break
        end
      end
    end
  end
end

if love.keyboard.isDown("d") then
  self.x = self.x + 300 * dt
elseif love.keyboard.isDown("a") then
  self.x = self.x - 300 * dt
end
if love.keyboard.isDown("s") then
  self.y = self.y + 300 * dt
elseif love.keyboard.isDown("w") then
  self.y = self.y - 300 * dt
end

if self.x < 0 then
  self.x = 0
elseif self.x + 64 > love.graphics.getWidth() then
  self.x = love.graphics.getWidth() - 64
end
if self.y < 0 then
  self.y = 0
elseif self.y + 64 > love.graphics.getHeight() then
  self.y = love.graphics.getHeight() - 64
end
Note that I have only changed indentation; I have not moved any code. But just by being rigorous, it's now evident that there's a lot of code outside the function, that should be inside it. Most code editors have options to indent/unindent code blocks, so it's not really that hard if you make use of that facility.

But fixing that (by moving the 'end' to the right place and reindenting properly) does not end the problems. You have this line:

Code: Select all

local  currentFrame = currentFrame + 10 * dt
In that line, you're looking up the value of a preexisting variable, currentFrame, and setting it to a newly defined local, currentFrame. Since it didn't exist before, its value is nil, and that will cause an error when attempting to do the addition.

You can solve it in a number of ways. I suggest it to be a field of the butterfly, so that if you add more butterflies, they don't flap their wings in perfect sync, but each has its own frame counter.

Apart from that, in love.draw() you're calling butterfly:update(), not butterfly:draw().

There are other issues, but I hope that's enough for you to get started.