[fork] Lua support for cocos2d-x

for cocos2d-x master branch: https://github.com/dualface/cocos2d-x
for cocos2d-x 0.9.2 branch: https://github.com/dualface/cocos2d-x/tree/luafix-0.9.2
for cocos2d-x 0.10.2 branch: https://github.com/dualface/cocos2d-x/tree/luafix-0.10.0

Lua Support FIX Readme

  • CCScheduler support local function
  • Support autorelease C*+ object
    * When C*+ object deleted, set Lua object userdata to nil
  • Add CCNode:setPosition(x, y), CCNode::getPosition(), huge performance boost
  • Remove needless class and functions from tolua*+ .pkg files, improved performance
    * CCMenuItem support script function
    * CCScene script callback
    * CCLayer touch & multi-touches events handler
    h2. How to use:
    <pre>
    — use CCSchedule::scheduleScriptFunc
    local scheduler = CCScheduler:sharedScheduler
    local handle — save script callback handle
    local frameCount = 0
    local function onEnterFrame
    print
    frameCount = frameCount* 1
    if frameCount >= 60 then
    — remove script callback
    scheduler:unscheduleScriptFunc(handle)
    end
    end

handle = scheduler:scheduleScriptFunc(onEnterFrame, 1.0 / 60, false)

-- use CCMenuItem:registerScriptHandler()

local function onMenuItemTap(menuItemTag)
    print(menuItemTag) -- output "1"
end

local menuItem = CCMenuItemImage:itemFromNormalImage("button.png", "button.png")
menuItem:registerScriptHandler(onMenuItemTap)

local menu = CCMenu:node()
menu:addChild(menuItem)
menuItem:setTag(1) -- menuItemTag

scene:addChild(menu)

-- use CCScene script callback

local function newScene()
    local scene = CCScene:node()

    local function sceneEventHandler(isOnEnter)
        if isOnEnter then
            if scene.onEnter then scene:onEnter() end
        else
            if scene.onExit then scene:onExit() end
            scene:unregisterScriptEventsHandler()
        end
    end

    scene:registerScriptEventsHandler(sceneEventHandler)
    return scene
end

local myScene = newScene("MyScene")
function myScene:onEnter()
    print("MyScene:onEnter()")
end

function myScene:onExit()
    print("MyScene:onExit()")
end

CCDirector:sharedDirector():runWithScene(myScene)

-- use CCLayer touch event handler

local layer = CCLayer:node()
local function onTouch(event, x, y)
    -- event: CCTOUCHBEGAN, CCTOUCHMOVED, CCTOUCHENDED, CCTOUCHCANCELLED
    print(event, x, y)
    if event == CCTOUCHBEGAN then return true end
end

layer:registerScriptTouchHandler(onTouch, false)

-- use CCLayer multi-touches event handler

local layer = CCLayer:node()
local function onTouches(event, points)
    -- event: CCTOUCHBEGAN, CCTOUCHMOVED, CCTOUCHENDED, CCTOUCHCANCELLED
    print(event)

    for i = 1, #points, 2 do
        print(string.format("x: 0.2f, y: 0.2f", points[i], points[i + 1]))
    end
end

layer:registerScriptTouchHandler(onTouches, true)

TODO:

  • When C++ object deleted, remove Lua object userdata

scheduler.lua module

module("scheduler", package.seeall)

scheduler = CCScheduler:sharedScheduler()

function enterFrame(listener, isPaused)
    return scheduler:scheduleScriptFunc(listener, display.animationInterval, isPaused or false)
end

function schedule(listener, interval, isPaused)
    return scheduler:scheduleScriptFunc(listener, interval, isPaused or false)
end

function unschedule(handle)
    scheduler:unscheduleScriptFunc(handle)
end
remove = unschedule

function performWithDelay(time, listener)
    local handle
    handle = scheduler:scheduleScriptFunc(function()
        scheduler:unscheduleScriptFunc(handle)
        listener()
    end, time, false)
end

How to use:

require("scheduler")

local function onEnterFrame(dt)
    print(dt)
end

scheduler.enterFrame(onEnterFrame)

----

scheduler.performWithDelay(2.0, function()
    print("DELAY 2.0 seconds")
end)

transition.lua module

module("transition", package.seeall)

function to(target, action, args)
    local delay = args.delay or 0
    local time = args.time or 0.2
    local onComplete = args.onComplete or onComplete

    if type(time) ~= "number" then time = 0.2 end

    if type(delay) == "number" and delay > 0 then
        action:retain()
        scheduler.performWithDelay(delay, function()
            target:runAction(action)
            action:release()
        end)
    else
        target:runAction(action)
    end

    if type(onComplete) == "function" then
        scheduler.performWithDelay(delay + time, onComplete)
    end
end

function fadeIn(target, args)
    local action = CCFadeIn:actionWithDuration(args.time or 0.2)
    to(target, action, args)
end

function fadeOut(target, args)
    local action = CCFadeOut:actionWithDuration(args.time or 0.2)
    to(target, action, args)
end

How to use:

require("transition")

local image = CCSprite:spriteWithFile("hello.png")
scene:addChild(image)

transition.fadeOut(image, {
    time = 1.0,     -- fadeout duration 1.0 second
    delay = 3.0,    -- before fadeout, wait 3.0 seconds
    onComplete = function()
        print("fadeout completed")
        image:removeFromParentAndCleanup(true);
        image = nil
    end
})

awksome.

very Good ! 3Q _