Search code examples
classmodulelualove2d

Classes and modules and Lua, oh my


I'm working on a game in Lua, and so far I have everything working with everything in one document. However, to better organize everything, I've decided to expand it into modules, and while I figure I could probably get it working more or less the same, I figure now might be an opportunity to make things a little more clear and elegant.

One example is enemies and enemy movement. I have an array called enemyTable, and here is the code in Update that moves each enemy:

    for i, bat in ipairs(enemyTable) do
        if bat.velocity < 1.1 * player.maxSpeed * pxPerMeter then
            bat.velocity = bat.velocity + 1.1 * player.maxSpeed * pxPerMeter * globalDelta / 10
        end

        tempX,tempY = math.normalize(player.x - bat.x,player.y - bat.y)

        bat.vectorX = (1 - .2) * bat.vectorX + (.2) * tempX
        bat.vectorY = (1 - .2) * bat.vectorY + (.2) * tempY

        bat.x = bat.x + (bat.velocity*bat.vectorX - player.velocity.x) * globalDelta
        bat.y = bat.y + bat.velocity * bat.vectorY * globalDelta

        if bat.x < 0 then
            table.remove(enemyTable,i)
        elseif bat.x > windowWidth then
            table.remove(enemyTable,i)
        end     
    end

This code does everything I want it to, but now I want to move it into a module called enemy.lua. My original plan was to create a function enemy.Move() inside enemy.lua that would do this exact thing, then return the updated enemyTable. Then the code inside main.lua would be something like:

enemyTable = enemy.Move(enemyTable)

What I'd prefer is something like:

enemyTable.Move()

...but I'm not sure if there's any way to do that in Lua? Does anyone have any suggestions for how to accomplish this?


Solution

  • Sounds like you just want the metatable of enemyTable to be the enemy module table. Lua 5.1 reference manual entry for metatables

    Something like this.

    enemy.lua

    local enemy = {}
    
    function enemy:move()
        for _, bat in ipairs(self) do
            ....
        end
    end
    
    return enemy
    

    main.lua

    local enemy = require("enemy")
    
    enemyTable = setmetatable({}, {__index = enemy})
    
    table.insert(enemyTable, enemy.new())
    table.insert(enemyTable, enemy.new())
    table.insert(enemyTable, enemy.new())
    
    enemyTable:move()