luatimerlove2d

Using love2d timer, bug reporting 'Error hump/timer.lua:78: attempt to index local 'self' (a number value) '


below is where the error may occur Here is my main.lua and I note the place where I think the error is. What I can't figure out is why this sentence will return a number value? I'm learning Downwell's effect and the tutorial link is here:https://github.com/a327ex/blog/issues/9

Object = require("classic")
GameObject = require("GameObject")
Timer = require 'hump/timer'

function love.load()

  Game_objects = {}
  Game_object = createGameObject('GameObject',100, 100)

  --dealing with canvas
  main_canvas = love.graphics.newCanvas(320, 240)
  main_canvas:setFilter("nearest", "nearest")
  love.window.setMode(960, 720)

  timer = Timer()
--Here!
  timer.after(4, function() Game_object.dead = true end)
end
function love.update(dt)
  timer.update(dt)
  for i = #Game_objects, 1, -1 do
    Game_object = Game_objects[i]
    Game_object:update(dt)
    if Game_object.dead then
      table.remove(Game_objects, i)
    end
  end
end

function love.mousepressed(x,y,button)
  if button == 1 then
      Game_object.dead =true
  end
end
  
function love.draw()
  love.graphics.setCanvas(main_canvas)
  love.graphics.clear()
  for _, Game_object in ipairs(Game_objects) do
    Game_object:draw()
  end
  love.graphics.setCanvas()

  love.graphics.draw(main_canvas, 0, 0, 0, 3, 3)
end

function createGameObject(type,x, y, opts)
  local game_object = _G[type](x, y, opts)
  table.insert(Game_objects, game_object)
  return game_object -- return the instance in case we wanna do anything with it
end

just dont know and it had took me 2 days. can anyone help me~ :(


Solution

  • In terms of classical OOP, with

    timer = Timer()
    

    timer is considered a new instance of the Timer class1. When calling methods, the colon syntax should be used (in love.load)

    timer:after(4, function() Game_object.dead = true end)
    

    and (in love.update)

    timer:update(dt)
    

    so that the implicit self inside the method references the calling instance.


    More completely, when a function is defined with the colon syntax

    function foo:bar(arg)
        print(self, arg)
    end
    

    it is syntactic sugar for the following assignment, where the function has an explicit first argument named self:

    foo.bar = function (self, arg)
        print(self, arg)
    end
    

    Likewise, the syntax of calling a function as foo:bar(42) is syntactic sugar for foo.bar(foo, 42), inserting that implicit first self argument.

    This is why timer.after(4, function () ... end) is assigning 4 to the implicit local self inside the method. The after method is defined1 as

    function Timer:after(delay, func)
        return self:during(delay, _nothing_, func)
    end
    

    which in your case leads to (4):during(delay, _nothing_, func), hence the error.


    1. Source code from hump/timer
    * Lua 5.1: 2.5.8 – Function Calls | 2.5.9 – Function Definitions