This the the class code:
-------------------- -- REQUIRE -------------------- -- STORYBOARD local sb = require "storyboard" -------------------- -- ENUM -------------------- local state = { idle = "idle", move = "move", eat = "eat", play = "play", sleep= "sleep" } -------------------- -- FISH CLASS -------------------- local fish = {} local fish\_mt = { \_\_index = fish } -- CONSTRUCTOR function fish.new( fishData ) -- Create the instance of the fish (sprite) local fishSheet = graphics.newImageSheet( fishData.sheetPath, fishData.sheetSetting ) local instance = display.newSprite( fishSheet, fishData.spriteSequence ) instance.state = state.idle -- Cant play animation here will crash randomly as this is a local copy instance.x = display.contentWidth \* 0.5 instance.y = display.contentHeight \* 0.5 return setmetatable( instance, fish\_mt ) end -- MEMBER FUNCTIONS function fish:playAnim() self:setSequence( self.state ) self:play() end function fish:changeState( newState ) if ( self.state ~= newState ) then self.state = newState -- NYI end end -- RETURN return fish
My problem:
-
I can’t call setSequence or play outside or inside the class. Example:
local obj = require “objclass” local function game() --local fishData = {Some data here} local fish = obj.new( fishData ) – fish:setSequence( “idle” ) – fish:play() – OR – fish:playAnim() end
Either uncommenting line 5 and 6, or uncommenting 8 will crash. Is there a way I can play animation of a sprite created inside a class? Any help would be appreciated.
Why can’t you just return the fish, instead of returning setmetatable?
I’m not well versed in metatables, but that’s what I get off the top of my head.
Something like this:
[lua]
-
- – REQUIRE
-
- – STORYBOARD
- local sb = require “storyboard”
-
-
- – ENUM
-
- local state = {
- idle = “idle”,
- move = “move”,
- eat = “eat”,
- play = “play”,
- sleep= “sleep”
- }
-
-
- – FISH CLASS
-
- local fish = {}
- local fish_mt = { __index = fish }
-
- – CONSTRUCTOR
- function fish.new( fishData )
- – Create the instance of the fish (sprite)
- local fishSheet = graphics.newImageSheet( fishData.sheetPath, fishData.sheetSetting )
- local instance = display.newSprite( fishSheet, fishData.spriteSequence )
-
- instance.state = state.idle
- – Cant play animation here will crash randomly as this is a local copy
- instance.x = display.contentWidth * 0.5
- instance.y = display.contentHeight * 0.5
- setmetatable( instance, fish_mt )
- return instance
- end
-
- – MEMBER FUNCTIONS
- function fish:playAnim()
- self:setSequence( self.state )
- self:play()
- end
-
- function fish:changeState( newState )
- if ( self.state ~= newState ) then
- self.state = newState
- – NYI
- end
- end
-
- – RETURN
- return fish
[/lua]
Why can’t you just return the fish, instead of returning setmetatable?
I’m not well versed in metatables, but that’s what I get off the top of my head.
Something like this:
[lua]
-
- – REQUIRE
-
- – STORYBOARD
- local sb = require “storyboard”
-
-
- – ENUM
-
- local state = {
- idle = “idle”,
- move = “move”,
- eat = “eat”,
- play = “play”,
- sleep= “sleep”
- }
-
-
- – FISH CLASS
-
- local fish = {}
- local fish_mt = { __index = fish }
-
- – CONSTRUCTOR
- function fish.new( fishData )
- – Create the instance of the fish (sprite)
- local fishSheet = graphics.newImageSheet( fishData.sheetPath, fishData.sheetSetting )
- local instance = display.newSprite( fishSheet, fishData.spriteSequence )
-
- instance.state = state.idle
- – Cant play animation here will crash randomly as this is a local copy
- instance.x = display.contentWidth * 0.5
- instance.y = display.contentHeight * 0.5
- setmetatable( instance, fish_mt )
- return instance
- end
-
- – MEMBER FUNCTIONS
- function fish:playAnim()
- self:setSequence( self.state )
- self:play()
- end
-
- function fish:changeState( newState )
- if ( self.state ~= newState ) then
- self.state = newState
- – NYI
- end
- end
-
- – RETURN
- return fish
[/lua]
@JeffreyQjr: I’ve ever seen metatables before, but I would think that’s the source of your problem. Could you post the error you’re receiving? Another way to do this would be to attach the member functions to the spriteObject, and return the spriteObject when .new is called. That’s how I’m handling this situation in my game.
Good luck!
Hello, thanks for the reply.
This was quite long ago when I was trying to test out how modular classes work as shown here: http://www.coronalabs.com/blog/2011/09/29/tutorial-modular-classes-in-corona/
I’ve changed my approach to this without using meta table, so I no longer have the code to reproduce this unfortunately. However I think the main problem is that the instance isn’t a table like what is shown on the above link. But I can’t be 100% sure because I am not really good with meta tables and not sure how they work.
Just in case you needed an answer to the original question; I suspect it’s because you can’t setmetatable on a Corona display object - as they already have metatables attached.
The solution is often to hold a proxy to the display object as part of the object: i.e:
[lua]
function fish.new( fishData )
– Create the instance of the fish (sprite)
local fishSheet = graphics.newImageSheet( fishData.sheetPath, fishData.sheetSetting )
local instance = {}
instance.sprite = display.newSprite( fishSheet, fishData.spriteSequence )
instance.state = state.idle
– Cant play animation here will crash randomly as this is a local copy
instance.x = display.contentWidth * 0.5
instance.y = display.contentHeight * 0.5
setmetatable( instance, fish_mt )
return instance
end
[/lua]
Then makes the calls that are currently failing on the proxy: self.sprite:setSequence()
@JeffreyQjr: I’ve ever seen metatables before, but I would think that’s the source of your problem. Could you post the error you’re receiving? Another way to do this would be to attach the member functions to the spriteObject, and return the spriteObject when .new is called. That’s how I’m handling this situation in my game.
Good luck!
Hello, thanks for the reply.
This was quite long ago when I was trying to test out how modular classes work as shown here: http://www.coronalabs.com/blog/2011/09/29/tutorial-modular-classes-in-corona/
I’ve changed my approach to this without using meta table, so I no longer have the code to reproduce this unfortunately. However I think the main problem is that the instance isn’t a table like what is shown on the above link. But I can’t be 100% sure because I am not really good with meta tables and not sure how they work.
Just in case you needed an answer to the original question; I suspect it’s because you can’t setmetatable on a Corona display object - as they already have metatables attached.
The solution is often to hold a proxy to the display object as part of the object: i.e:
[lua]
function fish.new( fishData )
– Create the instance of the fish (sprite)
local fishSheet = graphics.newImageSheet( fishData.sheetPath, fishData.sheetSetting )
local instance = {}
instance.sprite = display.newSprite( fishSheet, fishData.spriteSequence )
instance.state = state.idle
– Cant play animation here will crash randomly as this is a local copy
instance.x = display.contentWidth * 0.5
instance.y = display.contentHeight * 0.5
setmetatable( instance, fish_mt )
return instance
end
[/lua]
Then makes the calls that are currently failing on the proxy: self.sprite:setSequence()