How to access methods for instances of a class?
Hi,
I'm just starting so I'm still trying to get a good understanding of the basics.
here is a simplified version of what I am trying to do : basically adding a number of balls to the screen and move them.
My questions are contained in the code and will be easier to understand in the context.
Any pointer is greatly appreciated :)
Code
main.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | require ("Balls") require ("Ball") local Game = {} function Game:startSetup() local Balls = Balls:new() Balls:setup() end Game:startSetup() Balls:animate() -- How can I change the position of an instance of my Ball class? -- I would like to move my objects (circles) independantly -- -> ................ |
balls.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | Balls = {} Balls_mt = {__index = Balls} function Balls:new() local new_inst = {} setmetatable(new_inst, Balls_mt) return new_inst end -- --------------------------------------- -- SETUP -- --------------------------------------- function Balls:setup() -- Set Balls Defaults local params = { { radius=20, xdir=1, ydir=1, xspeed=2.8, yspeed=6.1, r=255, g=0, b=0, posx=400, posy=150 }, { radius=50, xdir=-1, ydir=-1, xspeed=1.8, yspeed=1.5, r=115, g=23, b=33, posx=200, posy=200 } } for i, j in pairs(params) do ball = Ball:new(j) end end -- --------------------------------------- -- ANIMATE -- --------------------------------------- function Balls:animate() local _Balls=self -- Question : How to access .move method for each instance of the Ball class? for i, ball in pairs(_Balls) do ball:move() -- Doesn't work | Error : attempt to index local 'ball' (a function value) end end return Balls |
ball.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | Ball = {} Ball_mt = {__index = Ball} function Ball:new(params) local new_inst = {} setmetatable(new_inst, Ball_mt) -- Default Location local default_xpos = display.contentWidth*0.5 local default_ypos = display.contentHeight*0.5 -- Draw Ball local new_inst = display.newCircle(default_xpos, default_ypos, params.radius ) new_inst.x = params.posx new_inst.y = params.posy -- Copy params to new_inst for i, j in pairs(params) do new_inst[i] = j end return new_inst end -- I need to access that function from main.lua and balls.lua function Ball:move() print ("Move Ball") end return Ball |
My questions
1. I believe that if I understand how to access methods for instances of a class I will be able to make progress
2. Is there a table that stores all the instances of a class?
Thank you :)
Replies
Thank you for the answer.
I am not sure how your suggestion is suited to my case?
1 2 3 4 5 | local _Balls=self -- Question : How to access .move method for each instance of the Ball class? for i, ball in pairs(_Balls) do ball:move() -- Doesn't work | Error : attempt to index local 'ball' (a function value) end |
ball.move() doesn't work either.
I want to access the method for my instances (are methods same as properties in programming?), and I believe that I already pass the instance to the move function because ball is taken from _Balls and local _Balls=self .
I can't see where I would need to modify my script and the relevancy of your answer doesn't appear clearly to my eyes.
Can you elaborate?
I am also finding this a little confusing, I can easily do what I want to do with a single instance of a display object e.g. ball but when I create multiple instances its becomes unclear how to access a single instance. On day day 2 of learning will check back here to hopefully get a clearer picture.
Hum, why are you using:
local _Balls=self
?
As pairs need the table containing your balls.
I'm not confortable with your sample. Here is mine:
balls.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | Ball = {} Ball_mt = {__index = Ball} -- Note the use of '.' instead of ':' because it's not a method of an instance function Ball.new() local new_inst = {} -- setmetatable(new_inst, Ball_mt) -- removed! -- Default Location local default_xpos = display.contentWidth*0.5 local default_ypos = display.contentHeight*0.5 -- Create Display Object for Ball local new_inst = display.newCircle(default_xpos, default_ypos, params.radius ) new_inst.x = params.posx new_inst.y = params.posy return setmetatable(new_inst,Ball_mt) end -- I need to access that function from main.lua and balls.lua function Ball:move(dist) print ("Move Ball") self.x = self.x + dist -- example of accessing a property end return Ball |
Now how to create 2 balls and move them :
1 2 3 4 5 6 7 | _balls = require("balls") local ball1 = _balls.new() local ball2 = _balls.new() ball1:move(5) ball2:move(10) |
-- Edit -> I replaced
function Ball:new()
by
function Ball.new()
because new is not a class method and do not need to receive the hidden self parameter.
Read more here:
http://www.lua.org/pil/16.html
HAHA, much better. Thx for the insight. I found this tutorial which also has a great approach to OOP if any one needs further help.
http://www.ludicroussoftware.com/blog/2011/07/06/simple-oop-with-inheritance-in-corona/
On the way to being able to get stuck in.
HAHA, much better. Thx for the insight. I found this tutorial which also has a great approach to OOP if any one needs further help.
http://www.ludicroussoftware.com/blog/2011/07/06/simple-oop-with-inheritance-in-corona/
On the way to being able to get stuck in.
HAHA, much better. Thx for the insight. I found this tutorial which also has a great approach to OOP if any one needs further help.
http://www.ludicroussoftware.com/blog/2011/07/06/simple-oop-with-inheritance-in-corona/
On the way to being able to get stuck in.
Opps, it kept asking me to verify. BUG
dmekersa >
Thank you very much for taking the time to answer. I appreciate.
I will take the time to study (started a few days ago and I was stuck).
I have a question :
In your example each ball is manually created
local ball1 = _balls.new()
How would you create a function so that you can populate Balls (10 at once for example) and still access each instance easily later?
Would you store the names in a table or, what would be the best practice?
Me too, same question. Does not seem intuitive to manually declare each ball?
In a table, using table.insert then browsing the table with pairs, example :
1 2 3 | for k in pairs(listBall) do listBall[k]:move() end |
dmekersa
Thank you. I have read the docs at lua-users (and more) but I guess I will learn more with time.
I have a last question : I can't access methods on my instances of Ball after I have stored them in a table, but I can access some of their properties.
-> attempt to call method 'move' (a nil value)
Where am I mistaking?
If someone could point me in the right direction, that would be great.
Thank you!
Code
main.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | _balls = require ("Balls") _ball = require ("Ball") require ("libraries") local Game = {} function Game:startSetup() local Balls = _balls.new() local listBalls = _balls:setup() print (listBalls[1].x) -- Displays "400", great until there listBalls[1]:move(50) -- Doesn't work.How can I access function move() in ball.lua end Game:startSetup() |
balls.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | Balls = {} Balls_mt = {__index = Balls} local listBalls = {} function Balls.new() local new_inst = {} setmetatable(new_inst, Balls_mt) return (new_inst) end -- --------------------------------------- -- SETUP -- --------------------------------------- function Balls:setup() -- Set Balls Defaults local params = { { radius=20, xdir=1, ydir=1, xspeed=2.8, yspeed=6.1, r=255, g=0, b=0, posx=400, posy=150 }, { radius=50, xdir=-1, ydir=-1, xspeed=1.8, yspeed=1.5, r=115, g=23, b=33, posx=200, posy=200}, { radius=20, xdir=1, ydir=1, xspeed=2.8, yspeed=6.1, r=255, g=0, b=0, posx=400, posy=350 } } for i, j in pairs(params) do local ball = _ball.new(j) table.insert(listBalls, ball) ball = nil end return (listBalls) end return Balls |
ball.lua
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | Ball = {} Ball_mt = {__index = Ball} function Ball.new(params) local new_inst = {} setmetatable(new_inst, Ball_mt) -- Default Location local default_xpos = display.contentWidth*0.5 local default_ypos = display.contentHeight*0.5 -- Create Display Object for Ball new_inst = display.newCircle(default_xpos, default_ypos, params.radius ) new_inst.x = params.posx new_inst.y = params.posy return (new_inst) end function Ball:move(dist) print ("Move Ball") --self.x = self.x + dist -- example of accessing a property end return Ball |
Note
On top of my previous question here is another one :
When I use
return setmetatable(new_inst,Ball_mt)
I can access my "move" method but print (listBalls[1].x) gives me a nil
On the other hand :
return (new_inst)
I can't access my "move" method but print (listBalls[1].x) gives me 400 (correct value)
attempt to call method 'move' (a nil value)> I would like to store access .x and other properties on my ball objects AND access the method from the class move().
How would I achieve that?
Also in the docs Lua Simple classes setmetatable is not done on return.
Can somebody explain me what I should learn from that difference?
Thank you!

If anyone could please take a look at my last message above, it probably shouldn't take more than 2 minutes for someone a bit experienced.
This guy on the picture is worried that I will never be able to start working on my platformer.
Help him, help me.
Thank you
Do you have a copy of require libraries.lua?
Thanks.
Hi Jeremy,
in fact libraries.lua is nothing special, just my own lua file for testing purposes.
Try this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | Ball = {} Ball_mt = {__index = Ball} function Ball.new(params) local new_inst = {} -- Default Location local default_xpos = display.contentWidth*0.5 local default_ypos = display.contentHeight*0.5 -- Create Display Object for Ball new_inst = display.newCircle(default_xpos, default_ypos, params.radius ) new_inst.x = params.posx new_inst.y = params.posy setmetatable(new_inst, Ball_mt) return (new_inst) end function Ball:move(dist) print ("Move Ball") --self.x = self.x + dist -- example of accessing a property end return Ball |



When you call a function with ":" like ball:move() there is an hidden parameter call "self" which point to the instance. Use self.[anyproperty] to access instance properties.
Hope it helps.