Cocos2d-JS 加载CocosStudio场景及触发器

本文详细介绍了如何使用Cocos2d-JS v3.1和CocosStudio v1.6.0.0搭建游戏场景,包括资源导出、模块添加、位置初始化、触发器设置等步骤,并提供了自定义数据读取和手势识别的实现方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

环境:

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的节点上添加了以下属性


在第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);

        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, 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);
    }
});

资源文件: 场景资源




Cocos2d-JS开发之旅 从HTML 5到原生手机游戏》 《Cocos2d-JS开发之旅——从HTML 5到原生手机游戏》从简单到复杂逐渐深入介绍Cocos2d-JS,包括HTML5和手机原生游戏两个方面的内容。这些内容融汇了作者多年的工作经验和Cocos2d-JS 的亲身使用教训,有助于读者快速掌握游戏开发的方法和避开不必要的麻烦。 《Cocos2d-JS开发之旅——从HTML 5到原生手机游戏》以两个游戏为线索,每一章的学习都为最终实现游戏而准备。除了基础的Cocos2d-JS使用方法,本书还会探讨如何调试发布原生手机游戏和另外一些高级话题。 《Cocos2d-JS开发之旅——从HTML 5到原生手机游戏》适合所有对2D 游戏开发感兴趣的人群,尤其是计算机专业学生、Flash/JS 开发者,因为Cocos2d-JS简单易懂,读者会发现自己已有的基础能快速应用或转移到Cocos2d-JS 游戏的开发中。 目录 第一部分 准 备 篇 第1 章 Cocos2d-JS 介绍 / 22 章 跑起我们的HelloWorld / 10 第一部分总结 / 27 第二部分 做一个简单的小游戏 第3 章 Cocos2d-JS 的平面世界 / 30 第4 章 让世界来点动静 / 51 第5 章 让玩家操纵这个世界 / 72 第6 章 控制小怪按时出现——定时器 / 84 第7 章 游戏界面 / 96 第8 章 不能光说不练——小小碰碰糖 / 122 第9 章 把成果分享到网上 / 143 第二部分总结 / 158 第三部分 再做一个高大上游戏 第10 章 走向高大上的必经之路——简单的性能优化 / 160 第11 章 让主角不再死板 / 173 第12 章 动态的背景 / 188 第13 章 界面的文字有点丑 / 204 第14 章 超炫的效果——粒子系统 / 211 第15 章 尝试做一个更大的游戏——Hungry Hero(上篇)/ 226 第16 章 尝试做一个更大的游戏——Hungry Hero(下篇)/ 235 第三部分总结 / 291 第四部分 把两个游戏做成原生手机游戏 第17 章 咱们也来做APP / 294 第18 章 真是这么美好吗?更多问题来了 / 304 第四部分总结 / 320 第五部分 高 级 篇 第19 章 订阅者模式——事件机制 / 32220 章 屏幕尺寸适配哪家强 / 331 第21 章 让死去的主角灰掉——渲染控制 / 34222 章 动态热更新 / 363 第23 章 想说的还有很多 / 374 第五部分总结 / 376
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值