I have a class in Lua called Reel with the following function:
function Reel:didCompleteFixAnimation()
self.x = self.x + 1
end
I am passing the function to CCCallFunc in another class method like so:
local animationAction = CCMoveTo:create(_fixReelAnimationDuration, point)
local callbackAction = CCCallFunc:create(self.didCompleteFixAnimation)
local actions = CCSequence:createWithTwoActions(animationAction, callbackAction)
sprite:runAction(actions)
didCompleteFixAnimation does get called after the completion of the action sequence, however the reference to ‘self’ is nil. I get the following error message:
reel.lua:145: attempt to index local ‘self’ (a nil value)
To answer my own question, I ended up having to extend CCCallFunc with a static method createWithTable that accepts a table and a function as a parameter, I call it like this:
local callbackAction = CCCallFunc:createWithTable(self, self. didCompleteFixAnimation)
The github commit is here in case anyone else needs to have CCCallFunc call a Lua function and pass a table as an argument:
I have another way to pass parameter to CCCallFunc.
-- To read easier, I write a function looks like schedule once.
function performWithDelay(node, callback, delay)
local delay = CCDelayTime:create(delay)
local callfunc = CCCallFunc:create(callback)
local sequence = CCSequence:createWithTwoActions(delay, callfunc)
node:runAction(sequence)
return sequence
end
-- Solution is in callback function. I use parent function save parameters, use child function as main functionality.
function changeScene(...)
local args = ...
local ret = function ()
-- body
local aboutGame = args.screen.create()
CCDirector:sharedDirector():replaceScene(aboutGame)
end
return ret
end
-- Finally, here is a usage.
performWithDelay(sceneGame, changeScene({screen=aboutscreen}), 1)
Based on original idea, we can improve performWithDelay function as below:
-- wrapper for callback with arguments
function callbackWithArgs(callback, args)
local params = args
local ret = function ()
-- body
callback(args)
end
return ret
end
-- performWithDelay version 2
function performWithDelay(node, callback, delay, args)
local delay = CCDelayTime:create(delay)
local callfunc = CCCallFunc:create(callbackWithArgs(callback, args)
local sequence = CCSequence:createWithTwoActions(delay, callfunc)
node:runAction(sequence)
return sequence
end
-- your callback will be simple
function changeScene(args)
-- body
local aboutGame = args.screen.create()
CCDirector:sharedDirector():replaceScene(aboutGame)
end
-- Finally, here is a usage.
performWithDelay(sceneGame, changeScene, 1, {screen=aboutscreen})