Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
problem in inheritence and using "self" keyword — Gideros Forum

problem in inheritence and using "self" keyword

aimoiaimoi Member
edited August 2015 in General questions
Hi everyone,
why making classes for getting instances from them is this much hard in lua and gideros?
I knew a method to simulate classes in lua. it was making a table (for example "boat") with the fields and functions we want and then making a methode like this:
function boat:new()
	return self
end
and whenever we wanted to use the boat object we simply wrote:
theBoat=boat:new()
but in this case when I write
local boat={
	side="left",
	pic=Bitmap.new(Texture.new("boat.png")),
}
 
function boat:GoX()
	if self.pic:getX()<1150 then
		self.pic:setX(self.pic:getX()+10)
		self:move()
	else 
		self.side="right" 
	end
end
and when I use "boat:GoX()" function I get this error
gamesCore.lua:50: attempt to index local 'self' (a nil value)
stack traceback:
	gamesCore.lua:50: in function 'func'
	[string "compatibility.lua"]:32: in function <[string "compatibility.lua"]:31>
so how can I use "self" keyword to be able to use a object's fields inside it's functions?
If anyone could explain what is the easiest and efficient way to simulate java-like classes in lua, it would a great help for me.
Thanks in advance.

Comments

  • keszeghkeszegh Member
    edited August 2015
  • ar2rsawseenar2rsawseen Maintainer
    edited August 2015
    Boat = Core.class()
     
    function Boat:init()
        self.side = "left"
        self.pic = Bitmap.new(Texture.new("boat.png"))
    end
     
    function Boat:GoX()
    	if self.pic:getX()<1150 then
    		self.pic:setX(self.pic:getX()+10)
    		self:move()
    	else 
    		self.side="right" 
    	end
    end
    and usage is like
    local boat = Boat.new()
    boat:GoX()

    Likes: aimoi

    +1 -1 (+1 / -0 )Share on Facebook
  • well, thanks a lot for your answers.
    But even with the "core.class" things I still have problems using self keyword.

    I wrote:
    boat=Core.class()
    function boat:init()
    	self.side="left"
    	self.pic=Bitmap.new(Texture.new("boat.png"))
    	self.done=false
    end
    and defined a function:
    function boat:GoX()
    	if self.pic:getX()<1150 then
    		self.pic:setX(self.pic:getX()+10)
    		self:move()
    		--print(theBoat.pic:getX())
    	else 
    		self.side="right" 
    		--print("AA"..theBoat.side)
    	end
    end
    but again when I call:
    boat:GoX()
    I get:
    gamesCore.lua:47: attempt to index local 'self' (a nil value)
    stack traceback:
    	gamesCore.lua:47: in function 'func'
    	[string "compatibility.lua"]:32: in function <[string "compatibility.lua"]:31>
    line 47 is the exact place that I have written:
    if self.pic:getX()<1150 then
    So it seems like whenever I'm trying to access a function from a field (which is a "Sprite" in this case) of my class (which is the "boat" here) by using "self" keyword, self gives a "nil" instead of pointing to my class object.

    I was wondering about making a metatable for all my boat objects and then set their metatables to that. Is that a better approach that using Core.class?
  • Make sure you use a . instead of : when creating the object:
    local boat = Boat.new()

    Likes: aimoi

    My Gideros games: www.totebo.com
    +1 -1 (+1 / -0 )Share on Facebook
  • totebototebo Member
    edited August 2015
    Oh, and also make sure you use a different instance name than the class (so not use "boat" for both).

    Likes: aimoi

    My Gideros games: www.totebo.com
    +1 -1 (+1 / -0 )Share on Facebook
  • edited August 2015 Accepted Answer
    Quick typing @totebo comment, here you are :P
    Boat=Core.class()
    function Boat:init()
    	self.side="left"
    	self.pic=Bitmap.new(Texture.new("boat.png"))
    	self.done=false
    end
     
    function Boat:GoX()
    	if self.pic:getX()<1150 then
    		self.pic:setX(self.pic:getX()+10)
    		self:move()
    		--print(theBoat.pic:getX())
    	else 
    		self.side="right" 
    		--print("AA"..theBoat.side)
    	end
    end
    function Boat:move()
    end 
     
    -- using it
    local my_boat = Boat.new()
    my_boat:GoX()
     
    -- look out, enemy come
    local pirate_boat = Boat.new()
    pirate_boat:GoX()

    Likes: aimoi

    Coming soon
    +1 -1 (+1 / -0 )Share on Facebook
  • Thank you for your complete answers. (:
    well, first after changing the things you said, I still had the
    attempt to index local 'self' (a nil value)
    problem. Then I remembered somewhere in my code I have used
    Timer.delayedCall(2, self.GoX)
    so I thought let's call the boat:GoX() function out of this structure.. and whooho! It worked.

    But seems like the problem has not been solved yet. I need to make delay there but with this function I get a nil value in 'self' when I call the GoX function of a specific boat. I think it's because the timer function is not sending the object inside the function the way when using ':' it does. So is there a solution for this too?
  • edited August 2015 Accepted Answer
    OK, here you are. Solution is wrap call method inside a function() end. In case of inside Class function call, you can using self (move function example), use instance when call outside Class (pirate_boat example )
    Boat=Core.class()
    function Boat:init(params)
    	params = params or {}
    	self.id = params.id or "a boat";
    	self.side="left"
    	self.pic=Bitmap.new(Texture.new("boat.png"))
    	self.done=false
    	self.vx = 1
    end
     
    function Boat:GoX()
    	if self.pic:getX()<1150 then
    		self.pic:setX(self.pic:getX()+10)
    		self:move()
    		--print(theBoat.pic:getX())
    	else 
    		self.side="right" 
    		--print("AA"..theBoat.side)
    	end
    end
    function Boat:move()
    	Timer.delayedCall(2000, function() 
    		self:changeSide()
    	end)
    end 
     
    function Boat:changeSide()
    	self.vx = -self.vx
    	print("changeSide called from", self.id)
    end
     
    -- using it
    local my_boat = Boat.new({id = "My Boat"})
    my_boat:GoX()
     
    -- look out, enemy come
    local pirate_boat = Boat.new({id = "Enemy Board"})
     
    --- Call out of Class method 
    Timer.delayedCall(2000, function() 
    	pirate_boat:changeSide()
    end)

    Likes: aimoi

    Coming soon
    +1 -1 (+1 / -0 )Share on Facebook
Sign In or Register to comment.