OOP question

Hi all,

I’m trying to learn object oriented programming in lua. I understand why it’s useful and have gone through several tutorials on OOP in Lua. But I do have a few questions.

In this code from develephant, what does this mean? I know this is a function to create a new character but I am a little lost as to what is happening inside of the function.

function CharacterClass:new( o ) local o = o or {} setmetatable( o, self ) self.\_\_index = self return o end

Also, for adding images and physics bodies, would it be better to have that done inside the main.lua or the class file?

And in this code:

playerClass = {} function playerClass:new( startX, startY ) local player = display.newImage( "images/player.png" ) player.x = startX player.y = startY return player end return playerClass

what does the “return player” line do? If I take it out, I get all kinds of errors. But when I code without using OOP, I don’t do the “return” line when I create new objects. What does this line do and why have I not had to use it before learning OOP?

I would greatly appreciate any help anyone can give.

Thanks!

Hi.

o = o or {} creates a new object if one is not supplied

setMetatable() tells the new object to look things up in the current object

self.__index makes it look up the chain of superclasses

There is a fuller explanation in the lua programming reference book.

The return playerClass line is for a module, so you can require() it.

I think :slight_smile:

As to where to put your images and physics bodies, it depends what your classes do. Classes should encapsulate. This can mean anything from encapsulating program classes - so suppose you write ‘Pacman’ you could have a Ghost class, Player class, Maze class that all interact with each other (and are tightly coupled) or you could go down the MVP/MVC route where you separate the processing and display and state of your game so they are independent. 

This depends on how you encapsulate. In the former, all the ‘ghost’ stuff - state, drawing and so on could go in the same class. In the latter, they go in different classes entirely, all the drawing goes together. Both approaches have advantages and disadvantages. Seperation of state, data, views, controllers makes it more manageable to make changes but longer.

Generally I just plonk:

\_G.Base =  \_G.Base or { new = function(s) local o = {} setmetatable(o,s) s.\_\_index = s s:initialise() return o end, initialise = function() end }

at the start of each source file, which creates a class “Base” with a quasi-constructor initialise() and derive everything from that which is a compacted version of your OOP with initialise() added.

Hi.

o = o or {} creates a new object if one is not supplied

setMetatable() tells the new object to look things up in the current object

self.__index makes it look up the chain of superclasses

There is a fuller explanation in the lua programming reference book.

The return playerClass line is for a module, so you can require() it.

I think :slight_smile:

As to where to put your images and physics bodies, it depends what your classes do. Classes should encapsulate. This can mean anything from encapsulating program classes - so suppose you write ‘Pacman’ you could have a Ghost class, Player class, Maze class that all interact with each other (and are tightly coupled) or you could go down the MVP/MVC route where you separate the processing and display and state of your game so they are independent. 

This depends on how you encapsulate. In the former, all the ‘ghost’ stuff - state, drawing and so on could go in the same class. In the latter, they go in different classes entirely, all the drawing goes together. Both approaches have advantages and disadvantages. Seperation of state, data, views, controllers makes it more manageable to make changes but longer.

Generally I just plonk:

\_G.Base =  \_G.Base or { new = function(s) local o = {} setmetatable(o,s) s.\_\_index = s s:initialise() return o end, initialise = function() end }

at the start of each source file, which creates a class “Base” with a quasi-constructor initialise() and derive everything from that which is a compacted version of your OOP with initialise() added.