环境:
win7 64位
Cocos2d-JS v3.1
Cocos Code IDE v1.0.0.Final
Cocos Studio v1.6.0.0
对于在cocosstudio场景的搭建,本人是按照此教程:http://www.taikr.com/course/92的第4,5和6课时进行搭建的,资源可以在cocosstudio创建场景时使用cocosstudio的demo捕鱼达人里面的资源,也可以是cocos2d-js demo里面的,本文最后也会上传用到的资源。未在web版上进行测试和改善
正文:
1.导出资源
默认选项就可以了:
2.打开Resources,把文件的资源复制,粘贴到cocos2d-js工程里的res文件下:
3.添加模块
"modules":[ "cocos2d","extensions","external" ],
4.添加位置初始化函数,为了让画布按照比例显示在当前分辨率的模拟器上
initSize:function(node){ var winSize = cc.director.getWinSize(); var scale = winSize.height / 640;//算出缩放比例 node.scale = scale;//按比例进行缩放 node.x = (winSize.width - 960 * scale) / 2; node.y = (winSize.height - 640 * scale) / 2; },笔者在使用cocos studio制作场景时,画布大小为960*640,cocos2d-js工程使用的模拟器分辨率也是960*640,这样直接设XY为(0,0)的话也可以
5.在app.js里面添加onEnter函数(其实在构造函数ctor里面添加也可以),接着加载场景:
var node1 = ccs.sceneReader.createNodeWithSceneFile("res/publish/FishSceneTest.json");//创建场景 this.addChild(node1,1,1);//把场景添加到当前layer, ccs.actionManager.playActionByName("startMenu_1.json","Animation1");//设置ui的动画 this.initSize(node1);//计算合适的显示大小和位置
6.运行测试,这时控制台会提示ui里面的资源找不到路径,解决方法有两种:
一种比较繁琐,就是在FishSceneTest.json文件里面把里面
"path":"Images/startMenuBG.png",所有的路径引用加上res/ ,如:
"path":"res/Images/startMenuBG.png",
另外一种推荐的方法是添加文件搜索路径,在工程的main.js 里面的 cc.game.onStart函数里 添加:
var searchPaths = jsb.fileUtils.getSearchPaths(); var paths = [ 'res' ]; for (var i = 0; i < paths.length; i++) { searchPaths.push(paths[i]); } jsb.fileUtils.setSearchPaths(searchPaths);注意这种方法添加的'res' 最后是不用加斜杠 / 的,C++里面的方法调用搜索路径时会在后面加上“/”。
运行测试,这时应该可以正常加载,如果控制台不停的提示cocos2d: removeAction: Target not found,其实这只是一个BUG,不影响动画。不过笔者尝试把工程的里面171行的
cc.log(cc._LogInfos.ActionManager_removeAction);这句话注释掉,也没用,还是不时在控制台显示,读者若有好的解决方法可以在下方留下解决方法,教教笔者。
7.接着是自定义数据的读取,笔者在别名为fish3、Tag为10017的节点上添加了以下属性
var fish3Attribute = node1.getChildByTag(10017).getComponent("CCComAttribute");//获取自定义属性内容 cc.log("speed:" + fish3Attribute.getFloat("speed"));//读取speed信息,注意没用getDouble这个函数 cc.log("score:" + fish3Attribute.getFloat("score"));//读取score信息,用getInt也可以,笔者只是做个测试
如无意外控制会输出:
JS: speed:5
JS: score:100
8.添加触发器
看了一些网上和官方的介绍,不过还是觉得看例子靠谱,毕竟demo在手,天下我有
该方法在393行开始,把里面用到的东西拖过来,直接用在第7步后面继续添加:
ccs.sendEvent(TRIGGER_EVENT_ENTERSCENE); var listener1 = cc.EventListener.create({ event: cc.EventListener.TOUCH_ONE_BY_ONE,//单点触摸 swallowTouches: true,onTouchBegan: this.onTouchBegan.bind(this),onTouchMoved: this.onTouchMoved.bind(this),onTouchEnded: this.onTouchEnded.bind(this) }); cc.eventManager.addListener(listener1,this);//注册添加的事件 this.initSize(node); },onExit: function () { ccs.actionManager.releaseActions(); ccs.sendEvent(TRIGGER_EVENT_LEAVESCENE); this.unschedule(this.gameLogic,this); this._super(); },onTouchBegan: function (touch,event) { ccs.sendEvent(TRIGGER_EVENT_TOUCHBEGAN); return true; },onTouchMoved: function (touch,event) { ccs.sendEvent(TRIGGER_EVENT_TOUCHMOVED); },onTouchEnded: function (touch,event) { ccs.sendEvent(TRIGGER_EVENT_TOUCHENDED); },onTouchCancelled: function (touch,event) { ccs.sendEvent(TRIGGER_EVENT_TOUCHCANCELLED); },看起来很多,不过如果你的触发器用得很简单,比如只是单击事件,那么那些onTouchMoved后面的也可以不用。
大家可以发现每个函数里面基本都是ccs.sendEvent,这个其实就是加载触发器了。名字对应触发的事件,如TRIGGER_EVENT_TOUCHBEGAN,就是在碰触屏幕开始的时候加载对应的触发事件。
但是现在还不可以加载触发器,还有添加API,在cocos studio 触发器设定好后点生成
这时cocos studio 工程下会多出一个code文件夹,里面有一堆.c和.cpp文件
官方说要把这堆文件添加到工程里面,不过那些教程都基于cocos2d-X,现在我们在用cocos2d-js,难道要自己把这些C++文件绑定到JS里面?
感兴趣的读者可以自己试试,这里咋们不用绑定这么麻烦,看回例子:
既然有了,那就直接拿来用吧,整个TriggerCode文件夹拷贝到自己的工程下,然后在project.josn里面的jsList里面添加刚才粘过来的文件:
"jsList":[ "src/resource.js","src/app.js","src/TriggerCode/Acts.js","src/TriggerCode/Cons.js","src/TriggerCode/EventDef.js" ]
9.代码及资源:
这里的app.js文件,里面有单双击事件,上下左右手势的实现测试,笔者是参考这个教程的:http://cn.cocos2d-x.org/tutorial/show?id=1782
大家看完那个链接消化完毕后可以看一下:手势那里优化了一下,也就是每次手势完成后把当前点重置为空,再加上当前点非空时才进行手势判断,这样就不会从第二次开始,点击屏幕也进行手势判断,而且点击屏幕得到的手势判断也不一定正确,因为当前点要是没有进行touchmoved的话,是保留上一次的值,因此,就算只是点击,也会让touchbegan得到的点跟touchmoved之前保留下来的点进行比较,笔者的表达能力也不怎么强,可能说得很模糊,
(其实也就是懒,懒得改代码,于是就包含单双击,手势的测试了= =)
app.js代码:
var HelloWorldLayer = cc.Layer.extend({ sprite:null,isClick:null,prePos:null,curPos:null,maxDistance:null,space:null,time:null,ctor:function () { ////////////////////////////// // 1. super init first this._super(); ///////////////////////////// // 2. add a menu item with "X" image,which is clicked to quit the program // you may modify it. // ask the window size var size = cc.winSize; // add a "close" icon to exit the progress. it's an autorelease object var closeItem = new cc.MenuItemImage( res.CloseNormal_png,res.CloseSelected_png,function () { cc.log("Menu is clicked!"); },this); closeItem.attr({ x: size.width - 20,y: 20,anchorX: 0.5,anchorY: 0.5 }); var menu = new cc.Menu(closeItem); menu.x = 0; menu.y = 0; this.addChild(menu,1); ///////////////////////////// // 3. add your codes below... // add a label shows "Hello World" // create and initialize a label var helloLabel = new cc.LabelTTF("Hello World","Arial",38); // position the label on the center of the screen helloLabel.x = size.width / 2; helloLabel.y = 0; // add the label as a child to this layer this.addChild(helloLabel,5); // add "HelloWorld" splash screen" this.sprite = new cc.Sprite(res.HelloWorld_png); this.sprite.attr({ x: size.width / 2,y: size.height / 2,scale: 0.5,rotation: 180 }); this.addChild(this.sprite,0); this.sprite.runAction( cc.sequence( cc.rotateTo(2,0),cc.scaleTo(2,1) ) ); helloLabel.runAction( cc.spawn( cc.moveBy(2.5,cc.p(0,size.height - 40)),cc.tintTo(2.5,255,125,0) ) ); this.isClick = false; this.maxDistance = 100.0; this.time = 0; this.scheduleUpdate(); return true; },update : function(dt) { this.time += dt; if(this.time > 7){ cc.log("7秒了"); this.time = 0; } //cc.log(this.time); },onEnter : function() { this._super(); //var node1 = ccs.sceneReader.createNodeWithSceneFile(res.FishSceneTest_json); var node1 = ccs.sceneReader.createNodeWithSceneFile("res/publish/FishSceneTest.json"); this.addChild(node1,1); ccs.actionManager.playActionByName("startMenu_1.json","Animation1"); this.initSize(node1); var fish3Attribute = node1.getChildByTag(10017).getComponent("CCComAttribute"); cc.log("speed:" + fish3Attribute.getFloat("speed")); cc.log("score:" + fish3Attribute.getFloat("score")); //this.schedule(this.gameLogic); ccs.sendEvent(TRIGGER_EVENT_ENTERSCENE); var listener1 = cc.EventListener.create({ event: cc.EventListener.TOUCH_ONE_BY_ONE,swallowTouches: true,onTouchEnded: this.onTouchEnded.bind(this) }); cc.eventManager.addListener(listener1,this); this.space = new cp.Space(); sapce = cp.v(0,-500); },initSize:function(node){ var winSize = cc.director.getWinSize(); var scale = winSize.height / 640; node.scale = scale; node.x = (winSize.width - 960 * scale) / 2; node.y = (winSize.height - 640 * scale) / 2; },onExit: function () { ccs.actionManager.releaseActions(); ccs.sendEvent(TRIGGER_EVENT_LEAVESCENE); this.unschedule(this.gameLogic,this); this._super(); },event) { var point = touch.getLocation(); this.prePos = point; this.scheduleOnce(this.touchDirection,1); ccs.sendEvent(TRIGGER_EVENT_TOUCHBEGAN); if (this.isClick) { this.doubleClick(); this.isClick = false; } else { this.isClick = true ; this.scheduleOnce(function aaa() { if (this.isClick) { cc.log("Single click"); this.isClick = false ; } },0.3); // this.scheduleOnce(function si() { // this.singleClick(3); // },0.3); //this.scheduleOnce(dc,0.3); //dc2(); } return true; },event) { var point = touch.getLocation(); this.curPos = point; ccs.sendEvent(TRIGGER_EVENT_TOUCHMOVED); },event) { ccs.sendEvent(TRIGGER_EVENT_TOUCHENDED); },event) { ccs.sendEvent(TRIGGER_EVENT_TOUCHCANCELLED); },gameLogic: function () { ccs.sendEvent(TRIGGER_EVENT_UPDATESCENE); },singleClick : function(i) { //cc.log("Singleclick" + i); //this.isClick = false; if (this.isClick) { cc.log("Single click"); this.isClick = false ; } },doubleClick : function() { cc.log("Double click !!"); },touchDirection : function(dt) { //cc.log("AAAAAAAAAAAAAAAAA"); if(this.curPos != null){ var sub = cc.pSub(this.curPos,this.prePos); if (Math.abs(sub.x) > Math.abs(sub.y)) { if (sub.x > this.maxDistance) { cc.log("right"); } else if(sub.x < -this.maxDistance){ cc.log("left"); } } else { if (sub.y > this.maxDistance) { cc.log("up"); } else if(sub.y < -this.maxDistance){ cc.log("down"); } } this.curPos = null; } } }); function dc() { // var fdc = new HelloWorldLayer(); // if (fdc.isClick) { // cc.log("Single click"); // fdc.isClick = false ; // } cc.log("Single click"); } var HelloWorldScene = cc.Scene.extend({ onEnter:function () { this._super(); var layer = new HelloWorldLayer(); this.addChild(layer); } });
资源文件: 场景资源