## OOP in Love2D

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
jthistle
Prole
Posts: 5
Joined: Mon Sep 05, 2016 7:47 pm

### OOP in Love2D

I'm having some trouble with writing a class in Lua with Love2D. I use the following code for my class:

Code: Select all

Planet = {
bgColour = {0,0,0},
landColour = {0,0,0},
size = 100,
landPoints = {

}
} -- the class table

function Planet:new()
self = setmetatable({}, self)

self.__index = self -- failed table lookups on the instances should fallback to the class table, to get methods

self.bgColour = {love.math.random(0,255), love.math.random(0,255), love.math.random(0,255)}
self.landColour = {love.math.random(0,255), love.math.random(0,255), love.math.random(0,255)}
self.size = 100
self.landPoints = {}

-- create the terrain
for j=1,love.math.random(1,10) do
tempPoints = {}

-- start point
table.insert(tempPoints, love.math.random(-self.size, self.size))
table.insert(tempPoints, love.math.random(-self.size, self.size))

-- each continent has a set of points for drawing
for i=1,love.math.random(5,8) do
lastPoint = {tempPoints[tableLength(tempPoints)-1], tempPoints[tableLength(tempPoints)]}

sizeCoef = 2

table.insert(tempPoints, love.math.random(lastPoint[1]-(self.size/sizeCoef), lastPoint[1]+(self.size/sizeCoef)))
table.insert(tempPoints, love.math.random(lastPoint[2]-(self.size/sizeCoef), lastPoint[2]+(self.size/sizeCoef)))
end

table.insert(self.landPoints, tempPoints)
end

return self
end

function Planet:getSize()
return self.size
end

function Planet:draw(centre)
-- Draw the planet (table centre as {x=number, y=number})

love.graphics.push()
love.graphics.translate(centre.x, centre.y)
love.graphics.setColor(self.bgColour)
love.graphics.circle("fill", 0,0, self.size)
love.graphics.setColor(self.landColour)
love.graphics.stencil(function () love.graphics.circle("fill", 0,0, self.size) end , "replace", 1, false)
love.graphics.setStencilTest("greater", 0)

for ind, points in pairs(self.landPoints) do
love.graphics.polygon("fill", points)
end

love.graphics.setStencilTest()
love.graphics.pop()
end
However, when I create a new instance:

Code: Select all

planet = Planet:new()
and then try to run a method:

Code: Select all

print(planet:getSize())
I get the error:

Code: Select all

Attempt to call method getSize (a nil value)
I've tried rewriting it again and again, in different ways, but this error has always come up. The class constructor is stored in a separate file which I require at the start of the main.lua file. Any help? Thanks in advance.

Azhukar
Party member
Posts: 478
Joined: Fri Oct 26, 2012 11:54 am

### Re: OOP in Love2D

Here's how you can implement a class:

Code: Select all

local classMeta = {
__call = function(self,...) --creates a new class instance
local new = setmetatable({},self)
if (self.init ~= nil) then
new:init(...) --constructor
end
return new
end,
}
local function newClass() --creates a new class
local class = setmetatable({},classMeta) --allows new class to be called as a function
class.__index = class
return class
end

classPlanet = newClass()

classPlanet.size = 100 --default class value

function classPlanet:init()
self.bgColour = {love.math.random(0,255), love.math.random(0,255), love.math.random(0,255)}
self.landColour = {love.math.random(0,255), love.math.random(0,255), love.math.random(0,255)}
self.landPoints = {}
end

function classPlanet:getSize()
return self.size
end

planet = classPlanet()
print(planet:getSize())
There's many class libraries to pick from if you look.

bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

### Re: OOP in Love2D

The problem is fairly simple, and is caused by these lines:

Code: Select all

function Planet:new()
self = setmetatable({}, self)

self.__index = self -- failed table lookups on the instances should fallback to the class table, to get methods

The problem is that in the last line self points to the object you're constructing, but not the class. I've got to say, replacing self is a fairly confusing thing to do in the first place. The easiest way to solve this is to not try to set __index every time you create an instance (everybody seems to be doing this lately, is there some tutorial that tells people to do this?), but to set it once beforehand. So replacing those lines with the following should work.

Code: Select all

Planet.__index = Planet

function Planet:new()
self = setmetatable({}, self)

Of course I should recommend not replacing self, so you don't confuse yourself or any future readers.

jthistle
Prole
Posts: 5
Joined: Mon Sep 05, 2016 7:47 pm

### Re: OOP in Love2D

Ah, thanks bartbes, that worked great. Yes, you're right, I got it from a tutorial - evidently not a very good one. Thanks!

zorg
Party member
Posts: 2995
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

### Re: OOP in Love2D

jthistle wrote:
Sat Oct 21, 2017 5:47 pm
Ah, thanks bartbes, that worked great. Yes, you're right, I got it from a tutorial - evidently not a very good one. Thanks!
Could you share which tut you got the info from? maybe they can fix it or something.
Me and my stuff True 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.

jthistle
Prole
Posts: 5
Joined: Mon Sep 05, 2016 7:47 pm

### Re: OOP in Love2D

Sorry zorg, I can't seem to find it. It was quite an old non Love-related OOP tutorial in Lua though, so I doubt it would be changed now.

### Who is online

Users browsing this forum: No registered users and 25 guests