前回からの続きで、今回は作成したCocosStudioのcsdファイル内csdのNodeのアニメーションをコード上で制御する方法を紹介します
まず、Nodeからアニメーション(ccs.ActionTimeline)を取得するために以下のようなメソッドを用意します
var utils = utils || {}; /** * @param {cc.Node} node * @returns {ccs.ActionTimeline|cc.Action|null} */ utils.getActionTimeLine = function (node) { return node.getActionByTag(node.getTag()); };
このメソッドを利用して、ccs.loadをしているところで以下のように実装します
var HelloWorldLayer = cc.Layer.extend({ ctor:function () { this._super(); /** @type {{node: cc.Node, action: cc.Action}} */ var mainscene = ccs.load(res.MainScene_json); this.addChild(mainscene.node); /** @type {cc.Node} */ var rotateIcon = mainscene.node.getChildByName("RotateIcon"); /** @type {ccs.ActionTimeline} */ var iconTimeLine = utils.getActionTimeLine(rotateIcon); iconTimeLine.play("rotate", true); return true; } });
この状態でproject.jsonやresource.jsなどを修正してから起動すると、子要素のアニメーションがループ再生されるのが確認できると思います
なぜこれで子要素のアニメーションが取得できるかというと、ccs.loadをした際に読み込むcsd(json)データが、CocosStudio v2以降のものであれば、timelineParser-2.x.jsが呼ばれ、そこで以下のような処理をしているからになります
parser.initProjectNode = function(json, resourcePath){ var projectFile = json["FileData"]; if(projectFile != null && projectFile["Path"]){ var file = resourcePath + projectFile["Path"]; if(cc.loader.getRes(file)){ var obj = ccs.load(file, resourcePath); parser.generalAttributes(obj.node, json); if(obj.action && obj.node){ obj.action.tag = obj.node.tag; var InnerActionSpeed = json["InnerActionSpeed"]; if(InnerActionSpeed !== undefined) obj.action.setTimeSpeed(InnerActionSpeed); obj.node.runAction(obj.action); obj.action.gotoFrameAndPause(0); } return obj.node; } else cc.log("%s need to be preloaded", file); } };
読み込んだactionをnodeのタグと同じにした上でrunActionしているのがわかると思います
そのため、nodeからnodeのタグでgetActionByTagをするとccs.ActionTimelineが取得できるというわけです
これを応用して、以下のようなccs.loadのwrapperを用意すると非常に捗ります
/** * @param {string} file * @param {string} [path] * @returns {cc.Node} */ utils.loadCCSNode = function (file, path) { var ccsObj = ccs.load(file, path); var node = ccsObj.node; var action = ccsObj.action; if(action && node){ action.tag = node.tag; node.runAction(action); action.gotoFrameAndPause(0); } return node; };
こうすることにより、nodeとactionを分けずに扱えるため、actionが必要になった時だけutils.getActionTimeLineを呼ぶといった使い方ができるようになるため、オススメです