Accessing parent class

Hello,

I’m making a simple game in which I have a main character built from a lua class. I have my main.lua file and hero.lua. In the main.lua file I do something like this :

char = hero.new()  

In my hero.lua file’s constructor I have :

local newhero = {     who = "hero",     frameNumber = 1,     displayHero = nil }  

Now back in my main.lua file, I create a sprite that is stored in char.displayHero. Afterwards, I add a physics body to char.displayHero in order to detect some collisions. When these collision events do occur, let’s say event.object1 is the char.displayHero, how do I access its parent (char) ?

Please let me know if the question isn’t clear and thank you for any help.

There’s no ‘built-in’ Lua mechanism to get the ‘parent’ of an object, because the same object can be an item in many tables.

What you could do is just create a custom parent property yourself pointing back to the parent object.  Specifically, when you create the sprite and store it in char.displayHero, you could write char.displayHero.parent = char.  That way, you have a reference from the sprite back to the parent.

Hope this helps.

  • Andrew

Hello,

Thank you for the reply. I actually tried this but I couldn’t get it to work. I have the exact same line of code (char.displayHero.parent = char). This is what my collision event handling function looks like :

function onCollision( event )          local parent = event.object1.parent          if ( event.phase == "began" ) then             if event.object1.parent ~= nil then                 print (parent.who)             end     end end  

As collisions occur, only “nil” is printed out in the console as opposed to “hero” or any other kind of object I have moving about. Any ideas why ?

What is ‘who’?  Is that a custom field you defined on the ‘char’ object?

  • Andrew

Yes it is. It’s in the constructor of my hero.lua file. Its value is not modified or even read anywhere else in the code.

local newhero = {     who = "hero",     frameNumber = 1,     displayHero = nil }  

I think something isn’t working quite right with char.displayHero.parent = char. Here’s a test I did : (the comments are the output)

 

    char.displayHero.parent = char     print (char.displayHero.parent)                        --  table : 00ED7A70     local test = char.displayHero.parent     print (test.who)                                    --    nil     print (char.who)                                    --  hero  

Well, the following works fine for me:

[lua]

local char = {}

char.who = “hero”

char.displayHero = {}

char.displayHero.parent = char

print (char.displayHero.parent)                        –  table : 00ED7A70

local test = char.displayHero.parent

print (test.who)                                    –    hero

print (char.who)                                    –  hero

[/lua]

The last five lines are your lines exactly, except that all three prints work.  The first three lines are just me constructing a simple object.

So, it seems like it must have to do with your constructor.  Can you post your full constructor code?

  • Andrew

This is the constructor from my hero.lua file

function hero.new(startingTile)    -- constructor local newhero = {     who = "hero",     frameNumber = 1,     displayHero = nil,     lastIdlePos = "idleUp",     pos = startingTile,     heroSequenceData =     {         { name="idleUp", start=3, count=1, time=3000 } ,                  { name="idleDown", start=6, count=1, time=3000 } ,                  { name="idleRight", start=9, count=1, time=3000 } ,                  { name="idleLeft", start=12, count=1, time=3000 } ,                  { name="runUp", start=3, count=3, time=400 } ,                  { name="runDown", start=6, count=3, time=400 } ,                  { name="runRight", start=9, count=3, time=400 } ,                  { name="runLeft", start=12, count=3, time=400 } ,                  { name="random", frames={ 3, 9, 6, 12 }, time=300 }     } } return setmetatable( newhero, hero\_mt ) end  

Here’s the code from my other lua file :

    char = hero.new(1)     char.displayHero =  display.newSprite( heroSheet, char.heroSequenceData )     char.displayHero.xScale = tileDimension / tileDefaultSize     char.displayHero.yScale = tileDimension / tileDefaultSize     char.displayHero.x = tileArray[1].displayTile.x     char.displayHero.y = tileArray[1].displayTile.y     char.displayHero:setSequence(char.lastIdlePos)     char.displayHero:play()          char.displayHero.parent = char     print (char.displayHero.parent)                        --  table : 00ED7A70     local test = char.displayHero.parent     print (test.who)                                    --    nil     print (char.who)                                    --  hero  

Nothing is jumping out at me that looks wrong.  It might have something to do with your metatable.

What happens if you just print(test), print(char), and print(char.displayHero.parent).  Do they all print out the same table reference?

  • Andrew
    print (test)                            -- table : 00E4E180     print (char)                            -- table : 0A1646B8     print (char.displayHero.parent)            -- table : 00E4E180  

hmm… char is supposed to be different I think, the other two are the same table

I now more strongly suspect that it’s something funky going on with your metatable.  Can you post the metatable code?

If I run the following code, all three prints print the same table reference, as expected:

[lua]

local char = {}

char.who = “hero”

char.displayHero = {}

char.displayHero.parent = char

local test = char.displayHero.parent

print(char)

print(test)

print(char.displayHero.parent)

[/lua]

  • Andrew

I’ll be honest… I don’t think I know what the metatable code is and I probably don’t have any…  :ph34r:

Here’s my whole file :

------------------------------------------------- -- -- hero.lua -- ------------------------------------------------- local hero = {} local hero\_mt = { \_\_index = hero }    -- metatable   ------------------------------------------------- -- PRIVATE FUNCTIONS -------------------------------------------------     local function Set (list)   local set = {}   for \_, l in ipairs(list) do set[l] = true end   return set end ------------------------------------------------- -- PUBLIC FUNCTIONS -------------------------------------------------         --------------------------------- -- -- who      : string --            type of character -- ---------------------------------   function hero.new(startingTile)    -- constructor local newhero = {     who = "hero",     frameNumber = 1,     displayHero = nil,     lastIdlePos = "idleUp",     pos = startingTile,     heroSequenceData =     {         { name="idleUp", start=3, count=1, time=3000 } ,                  { name="idleDown", start=6, count=1, time=3000 } ,                  { name="idleRight", start=9, count=1, time=3000 } ,                  { name="idleLeft", start=12, count=1, time=3000 } ,                  { name="runUp", start=3, count=3, time=400 } ,                  { name="runDown", start=6, count=3, time=400 } ,                  { name="runRight", start=9, count=3, time=400 } ,                  { name="runLeft", start=12, count=3, time=400 } ,                  { name="random", frames={ 3, 9, 6, 12 }, time=300 }     } } return setmetatable( newhero, hero\_mt ) end   -------------------------------------------------   -------------------------------------------------     -------------------------------------------------   -------------------------------------------------     -------------------------------------------------   return hero  

Hmm.  You’re metatable doesn’t seem to be doing anything significant here.  But just in case, try replacing the line “return setmetatable( newhero, hero_mt )” with simply “return newhero” and see if that makes a difference.

  • Andrew

hmm, I still have the same problem despite the change.

OK, then you can put that line back to the way it was.

It’s possible that ‘parent’ is a field that’s already used by the sprite object.  Try changing ‘parent’ to ‘myParent’ and see if that makes a difference.

  • Andrew

Ah yes that was it, I thought I already tested that though … must have made a mistake.

Thanks for putting up with my problem Andrew!

Cool, glad you got it working! - Andrew

There’s no ‘built-in’ Lua mechanism to get the ‘parent’ of an object, because the same object can be an item in many tables.

What you could do is just create a custom parent property yourself pointing back to the parent object.  Specifically, when you create the sprite and store it in char.displayHero, you could write char.displayHero.parent = char.  That way, you have a reference from the sprite back to the parent.

Hope this helps.

  • Andrew

Hello,

Thank you for the reply. I actually tried this but I couldn’t get it to work. I have the exact same line of code (char.displayHero.parent = char). This is what my collision event handling function looks like :

function onCollision( event )          local parent = event.object1.parent          if ( event.phase == "began" ) then             if event.object1.parent ~= nil then                 print (parent.who)             end     end end  

As collisions occur, only “nil” is printed out in the console as opposed to “hero” or any other kind of object I have moving about. Any ideas why ?

What is ‘who’?  Is that a custom field you defined on the ‘char’ object?

  • Andrew

Yes it is. It’s in the constructor of my hero.lua file. Its value is not modified or even read anywhere else in the code.

local newhero = {     who = "hero",     frameNumber = 1,     displayHero = nil }  

I think something isn’t working quite right with char.displayHero.parent = char. Here’s a test I did : (the comments are the output)

 

    char.displayHero.parent = char     print (char.displayHero.parent)                        --  table : 00ED7A70     local test = char.displayHero.parent     print (test.who)                                    --    nil     print (char.who)                                    --  hero