how to import classes from a file (middleclass)

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
HappyYoyo09
Prole
Posts: 5
Joined: Tue Nov 26, 2024 8:38 pm

how to import classes from a file (middleclass)

Post by HappyYoyo09 »

I'm using the middleclass library, and I have my classes and my main.lua file separated. I'm trying to figure out how to import classes from the objects.lua file to the main.lua file.

this is my main.lua script, I'm new to lua, so I'm not really sure how importing things with require works

Code: Select all

local class = require "middleclass"
local objects = require "objects"

updateOrder = {} --every object in this array will have its :update(delta) function called in love.update(delta)
drawOrder = {} --similar to update order, but for drawing. its function is :draw(), and it's called in love.draw


local player = Player:new(0,0) --this is where the error occurs, it doesn't have the Player class since I'm not sure how to import the classes from the objects file yet.

player:add()

function love.update(delta)
    for i=1,#updateOrder,1 do
        updateOrder[i]:update(delta)
    end
    
end
the code works when it isn't separated into two separate files, this is the error I get when i try to run the code

Code: Select all

Error

main.lua:8: attempt to index global 'Player' (a nil value)


Traceback

[love "callbacks.lua"]:228: in function 'handler'
main.lua:8: in main chunk
[C]: in function 'require'
[C]: in function 'xpcall'
[C]: in function 'xpcall'
lost-in-code
Prole
Posts: 5
Joined: Mon Feb 15, 2021 3:46 pm

Re: how to import classes from a file (middleclass)

Post by lost-in-code »

Code: Select all

local player = objects.Player:new(0,0)
Maybe ?
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: how to import classes from a file (middleclass)

Post by pgimeno »

Depends on what objects.lua returns. The answer by lost-in-code will work if it returns a table with all the objects.

You have to understand that no matter the class library you're using, they will work the same way with respect to class and self passing:

- Colon syntax is a Lua thing, which is what implicitly passes a `self` parameter to methods. All class libraries will use it.
- Classes themselves are tables, and you need to make these tables available to the program somehow if you want to use them. So you need to pass them like you would any other value.

So, in the case of a library file, if you are using local variables for the classes (highly recommended), you need to return them at the end of the library, so that when you use require() in main, the return value of the require function itself contains them.

So, for example, if you have a library that returns 4, you would do this in the library:

four.lua:

Code: Select all

    return 4
main.lua:

Code: Select all

local four = require('four')
print(four)  -- prints 4
It may sound like a stupid example, but the fact is that with tables, and hence with classes, it's the same thing. If you have a library that implements a single class:
player.lua:

Code: Select all

require [[ your class library of choice ]]
local Player = [[ definition of Player using your library of choice ]]
[[ methods for Player ]]

return Player  -- return it to the main program
and when you require it from main, you read the returned value:
main.lua:

Code: Select all

local Player = require('player')
local player = Player:new(0, 0)
But in your case you have multiple classes in the same file, so you need to return them all. You would do that like you do with any other values.

You could do this, for example:

objects.lua:

Code: Select all

local Player = [[ definition of the player class ]]
local Enemy = [[ definition of the enemy class ]]
return {Player = Player, Enemy = Enemy}
main.lua:

Code: Select all

local objects = require('objects')
local player = objects.Player:new(0, 0)
...
That's one way to do it, but not the only one. You could also do this:
objects.lua:

Code: Select all

local Player = [[ definition of player ]]
local Enemy = [[ definition of enemy ]]
return {Player, Enemy}
and in main.lua:

Code: Select all

local Player, Enemy = unpack(require('objects'))
Or whatever other means. Of course you could also declare the classes as global variables in objects.lua, and then they will be available throughout your program without you needing to even require the objects from each source file that uses them. I don't recommend this but maybe it's the simplest for you.
Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests