Scripting

Script component

Script component is used to extend c++ Node objects. You can add a script component to a Node, then the script component will receive onEnter, onExit and update events.

Script component supports both JavaScript and LUA. You should use the proper script component type for the language you are developing with. If you are developing with JavaScript, you would use ComponentJS, if you are developing with Lua, you would use ComponentLUA. But, you cannot mix them or use them in a c++ project! This is because the proper bindings for that language are required and these bindings are only available in their respective project types.

Example with Lua:

// create a Sprite and add a LUA component
auto player = Sprite::create("player.png");

auto luaComponent = ComponentLua::create("player.lua");
player->addComponent(luaComponent);
-- player.lua

local player = {
    onEnter = function(self)
        -- do some things in onEnter
    end,

    onExit = function(self)
        -- do some things in onExit
    end,

    update = function(self)
        -- do some things every frame
    end
}

-- it is needed to return player to let c++ nodes know it
return player

Example with JavaScript:

// create a Sprite and add a LUA component
auto player = Sprite::create("player.png");

auto jsComponent = ComponentJS::create("player.js");
player->addComponent(jsComponent);
// player.js
Player = cc.ComponentJS.extend({
    generateProjectile: function (x, y) {
        var projectile = new cc.Sprite("components/Projectile.png", cc.rect(0, 0, 20, 20));
        var scriptComponent = new cc.ComponentJS("src/ComponentTest/projectile.js");
        projectile.addComponent(scriptComponent);
        this.getOwner().getParent().addChild(projectile);

        // set position
        var winSize = cc.director.getVisibleSize();
        var visibleOrigin = cc.director.getVisibleOrigin();
        projectile.setPosition(cc.p(visibleOrigin.x + 20, visibleOrigin.y + winSize.height/2));

        // run action
        var posX = projectile.getPositionX();
        var posY = projectile.getPositionY();
        var offX = x - posX;
        var offY = y - posY;

        if (offX <= 0) {
            return;
        }

        var contentSize = projectile.getContentSize();
        var realX = visibleOrigin.x + winSize.width + contentSize.width/2;
        var ratio = offY / offX;
        var realY = (realX * ratio) + posY;
        var realDest = cc.p(realX, realY);

        var offRealX = realX - posX;
        var offRealY = realY - posY;
        var length = Math.sqrt((offRealX * offRealX) + (offRealY * offRealY));
        var velocity = 960;
        var realMoveDuration = length / velocity;

        projectile.runAction(cc.moveTo(realMoveDuration, realDest));
    },

    onEnter: function() {
        var owner = this.getOwner();
        owner.playerComponent = this;
        cc.eventManager.addListener({
            event: cc.EventListener.TOUCH_ALL_AT_ONCE,
            onTouchesEnded: function (touches, event) {
                var target = event.getCurrentTarget();
                if (target.playerComponent) {
                    var location = touches[0].getLocation();
                    target.playerComponent.generateProjectile(location.x, location.y);
                    jsb.AudioEngine.play2d("pew-pew-lei.wav");
                }
            }
        }, owner);
    }
});

One difference to keep in mind, between JavaScript and LUA components, is you should return the object in LUA component, in JavaScript, you only have to extend cc.ComponentJS

For more detailed usage, please refer to tests projects: tests/lua-tests/src/ComponentTest and tests/js-tests/src/ComponentTest.