环境:
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){笔者在使用cocos studio制作场景时,画布大小为960*640,cocos2d-js工程使用的模拟器分辨率也是960*640,这样直接设XY为(0,0)的话也可以
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;
},
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();注意这种方法添加的'res' 最后是不用加斜杠 / 的,C++里面的方法调用搜索路径时会在后面加上“/”。
var paths = [
'res'
];
for (var i = 0; i < paths.length; i++) {
searchPaths.push(paths[i]);
}
jsb.fileUtils.setSearchPaths(searchPaths);
运行测试,这时应该可以正常加载,如果控制台不停的提示cocos2d: removeAction: Target not found,其实这只是一个BUG,不影响动画。不过笔者尝试把工程的里面171行的
cc.log(cc._LogInfos.ActionManager_removeAction);这句话注释掉,也没用,还是不时在控制台显示,读者若有好的解决方法可以在下方留下解决方法,教教笔者。
7.接着是自定义数据的读取,笔者在别名为fish3、Tag为10017的节点上添加了以下属性
在第5步的下面添加以下代码:
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);看起来很多,不过如果你的触发器用得很简单,比如只是单击事件,那么那些onTouchMoved后面的也可以不用。
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);
},
大家可以发现每个函数里面基本都是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, 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, 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,
onTouchBegan: this.onTouchBegan.bind(this),
onTouchMoved: this.onTouchMoved.bind(this),
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();
},
onTouchBegan: function (touch, 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;
},
onTouchMoved: function (touch, event) {
var point = touch.getLocation();
this.curPos = point;
ccs.sendEvent(TRIGGER_EVENT_TOUCHMOVED);
},
onTouchEnded: function (touch, event) {
ccs.sendEvent(TRIGGER_EVENT_TOUCHENDED);
},
onTouchCancelled: function (touch, 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);
}
});
资源文件: 场景资源