cocos2d-js解析官方js-test实例入口
来源:互联网 发布:linux内核分析 孟宁 编辑:程序博客网 时间:2024/04/29 14:04
继续上一篇,搭建好cocos2d-js环境后,主要是html5环境,接下来步入入门阶段,许多人都说官网demo是最好的入门资料,今天就剖析官风提供的js-test入口,界面如下:
这上面有个关闭按钮和一个列表,列表列出了demo中所有的功能演示,这个js-tests工程在cocos2d-js的SDK中,以前是在samples目录下,现在最新版的放在tests目录中,目录结构如下:
我们切换到目录js-tests下,在终端运行:cocos run -p web就能打开浏览器查看效果,如果你部署了服务器的话,可以把tests和web目录直接拷贝到服务器目录下,访问对应的目录也能查看效果,注意,要拷贝tests和web目录,因为js-tests中用到了web目录及cpp-tests目录下的资源,如果不确定,把cocos2d-x-3.x.x目录全拷贝吧,也可以做个虚拟目录指向这个目录。
查看效果后,接下来分析主要的几个文件,在此列出你要分析的几个文件,即是需要我们手动修改维护的文件:index.html(首页,入口页),main.js(cocos2d-js的启动与入口),project.json(项目的配置文件),res(资源目录),src(源文件存放目录,一般是js文件,一般有app.js,resource.js)。
1.index.html文件,这里给出源码:
<!DOCTYPE HTML><html><head> <meta charset="utf-8"> <title>Cocos2d-HTML5 Test Cases</title> <link rel="icon" type="image/GIF" href="../cpp-tests/Resources/Images/favicon.ico"/></head><body style="text-align: center;background: #f2f6f8;"><img style="clear:both;margin-bottom: 20px" src="../cpp-tests/Resources/Images/cocos2dbanner.png"/><div></div><div style="display:inline-block;width:auto; margin: 0 auto; background: black; position:relative; border:5px solid black; border-radius: 10px; box-shadow: 0 5px 50px #333"> <!--<canvas id="gameCanvas" width="1200" height="675"></canvas>--> <!--<canvas id="gameCanvas" width="480" height="270"></canvas>--> <canvas id="gameCanvas" width="800" height="450"></canvas> *(1)*</div><script src="../../web/CCBoot.js"></script>*(2)*<script src="main.js"></script>*(3)*</body></html>
在这里注意三个地方,第一个标签canvas,id为gameCanvas,id会在project.json中配置用到。
第二个../../web/CCBoot.js,注意他的路径,此文件不需要我们维护。
第三个main.js,游戏的真正入口函数来了。
2.介绍下project.json项目配置文件,文件太大,截图说明下:
从向往下:第一个是否显示左下角FPS的信息,自己测试。第二个就是index.html中canvas的id 。第三个引擎的目录,注意他的路径,第四个使用到的模块,注意在引擎目录下查找,最后个键头js文件的列表,如果你有自己的js文件,请记得添加。
3.你们在看helloword项目是,看到有resource.js文件,里面定义了用到的资源,但是这里没有这个文件,他把资源定义到了其他文件中,这里定义到src/tests_resources.js中,看下他的截图:
如图,第一个键头指明了js文件存放的路径,注意if判断条件,他是web浏览器才执行的,不是的话情况另当别论,不过本人分析的就是html5的,所以他就进来了,第二个键头指示资源的定义,他使用了相对路径,注意他的res路径指向了tests/cpp-tests/Resources,这个在main.js中指定,到时在说明。这就是资源的定义,代替了我们常见的resource.js文件。
4.进入到main.js,真正的入口,看下他的源码:
if(cc.sys){ var scene3SearchPaths = cc.sys.localStorage.getItem("Scene3SearchPaths"); //html5项目判断不成立,直接跳过,想了解请查看api if (scene3SearchPaths) jsb.fileUtils.setSearchPaths(JSON.parse(scene3SearchPaths));}cc.game.onStart = function(){ //是否支持retina屏 cc.view.enableRetina(false); //判断是不是本地化的还是web的,这里判断为否,直接查看else if (cc.sys.isNative) { var resolutionPolicy = (cc.sys.os == cc.sys.OS_WP8 || cc.sys.os == cc.sys.OS_WINRT) ? cc.ResolutionPolicy.SHOW_ALL : cc.ResolutionPolicy.FIXED_HEIGHT; cc.view.setDesignResolutionSize(800, 450, resolutionPolicy); cc.view.resizeWithBrowserSize(true); var searchPaths = jsb.fileUtils.getSearchPaths(); searchPaths.push('script'); searchPaths.push('src'); var paths = [ 'res/resjs', 'res', 'res/scenetest', 'res/scenetest/ArmatureComponentTest', 'res/scenetest/AttributeComponentTest', 'res/scenetest/BackgroundComponentTest', 'res/scenetest/EffectComponentTest', 'res/scenetest/LoadSceneEdtiorFileTest', 'res/scenetest/ParticleComponentTest', 'res/scenetest/SpriteComponentTest', 'res/scenetest/TmxMapComponentTest', 'res/scenetest/UIComponentTest', 'res/scenetest/TriggerTest' ]; for (var i = 0; i < paths.length; i++) { searchPaths.push(paths[i]); } jsb.fileUtils.setSearchPaths(searchPaths); } else { //注意这里,他设置了res的路径,即资源目录,在资源文件中定义时访问的是这个目录下文件 cc.loader.resPath = '../cpp-tests/Resources' } //预加载资源,g_resources在test_resource.js中定义,加载完成后会调用第二个参数,一个匿名函数 cc.LoaderScene.preload(g_resources, function () { //判断条件不成立,进入else if(window.sideIndexBar && typeof sideIndexBar.start === 'function'){ sideIndexBar.start(); }else{ //这里设置场景,添加layer,运行场景,查看TestController类做了什么,他在test-main.js中定义 var scene = new cc.Scene(); scene.addChild(new TestController()); cc.director.runScene(scene); } }, this);};//运行游戏cc.game.run();
看代码,运行逻辑注释已经解释了,这是针对浏览器的,其他的情况没有去分析,其他情况也就是设置资源的搜索路径,现在理着他运行的步骤一步一步跟踪他到底做了什么。
5.从main.js中看到他创建了个类TestController添加到主场景中,接下来查看这个类都做了什么,他的路径为:
js-tests/src/tests-main.js。查看可知道他继承了类LayerGradient,这是个支持两种颜色的渐变的层,单颜色请查看LayerColor类。这里定义了一些全局变量和类的属性,在此不一一列举了,请看源文件,要分析这个类做了什么,就看下他的生命周期中相应的回调函数,第一个构造函数(ctor),第二个onEnter(进入函数),看下构造函数的源码,解释放在注释中:
//下面三个属性在类中定义_itemMenu:null, _beginPos:0, isMouseDown:false, //构造函数 ctor:function() { //两种渐变的颜色,可修改看效果 this._super(cc.color(0,0,0,255), cc.color(0x46,0x82,0xB4,255)); // globals 这两个为全局属性 director = cc.director; winSize = director.getWinSize(); // add close menu 关闭按钮参数一,二为两种状态的图标,在资源文件中定义,第三个点击时的回调函数 var closeItem = new cc.MenuItemImage(s_pathClose, s_pathClose, this.onCloseCallback, this); //设置他的坐标,左下角为原点,向右X轴增大,向上Y轴增大,这个在右上角 closeItem.x = winSize.width - 30; closeItem.y = winSize.height - 30; //动画是否自动切换图标 var subItem1 = new cc.MenuItemFont("Automated Test: Off"); subItem1.fontSize = 18; var subItem2 = new cc.MenuItemFont("Automated Test: On"); subItem2.fontSize = 18; //自动切换按钮属性设置,回调函数,坐标,是否可见,这里设置不可见,我们看不到效果,请设置可见查看效果 var toggleAutoTestItem = new cc.MenuItemToggle(subItem1, subItem2); toggleAutoTestItem.setCallback(this.onToggleAutoTest, this); toggleAutoTestItem.x = winSize.width - toggleAutoTestItem.width / 2 - 10; toggleAutoTestItem.y = 20; toggleAutoTestItem.setVisible(false); if( autoTestEnabled ) toggleAutoTestItem.setSelectedIndex(1); var menu = new cc.Menu(closeItem, toggleAutoTestItem);//pmenu is just a holder for the close button menu.x = 0; menu.y = 0; // add menu items for tests this._itemMenu = new cc.Menu();//item menu is where all the label goes, and the one gets scrolled //d在这里添加主界面中,各个demo的入口,其中testNames是个数组,存放了对象,接下来在分析 for (var i = 0, len = testNames.length; i < len; i++) { var label = new cc.LabelTTF(testNames[i].title, "Arial", 24); var menuItem = new cc.MenuItemLabel(label, this.onMenuCallback, this); this._itemMenu.addChild(menuItem, i + 10000); menuItem.x = winSize.width / 2; menuItem.y = (winSize.height - (i + 1) * LINE_SPACE); // enable disable if ( !cc.sys.isNative) { if( 'opengl' in cc.sys.capabilities ){ menuItem.enabled = (testNames[i].platforms & PLATFORM_HTML5) | (testNames[i].platforms & PLATFORM_HTML5_WEBGL); }else{ menuItem.setEnabled( testNames[i].platforms & PLATFORM_HTML5 ); } } else { if (cc.sys.os == cc.sys.OS_ANDROID) { menuItem.setEnabled( testNames[i].platforms & ( PLATFORM_JSB | PLATFROM_ANDROID ) ); } else if (cc.sys.os == cc.sys.OS_IOS) { menuItem.setEnabled( testNames[i].platforms & ( PLATFORM_JSB | PLATFROM_IOS) ); } else if (cc.sys.os == cc.sys.OS_OSX) { menuItem.setEnabled( testNames[i].platforms & ( PLATFORM_JSB | PLATFORM_MAC) ); } else { menuItem.setEnabled( testNames[i].platforms & PLATFORM_JSB ); } } } this._itemMenu.width = winSize.width; this._itemMenu.height = (testNames.length + 1) * LINE_SPACE; this._itemMenu.x = curPos.x; this._itemMenu.y = curPos.y; this.addChild(this._itemMenu); this.addChild(menu, 1); // 'browser' can use touches or mouse. 事件的处理,即滚动处理 // The benefit of using 'touches' in a browser, is that it works both with mouse events or touches events if ('touches' in cc.sys.capabilities) cc.eventManager.addListener({ event: cc.EventListener.TOUCH_ALL_AT_ONCE, onTouchesMoved: function (touches, event) { var target = event.getCurrentTarget(); var delta = touches[0].getDelta(); target.moveMenu(delta); return true; } }, this); else if ('mouse' in cc.sys.capabilities) { cc.eventManager.addListener({ event: cc.EventListener.MOUSE, onMouseMove: function (event) { if(event.getButton() == cc.EventMouse.BUTTON_LEFT) event.getCurrentTarget().moveMenu(event.getDelta()); }, onMouseScroll: function (event) { var delta = cc.sys.isNative ? event.getScrollY() * 6 : -event.getScrollY(); event.getCurrentTarget().moveMenu({y : delta}); return true; } }, this); } }
代码注释说最大部分功能,其他的查看源码,构造函数完成后,会调用onEnter函数,下面给出他的源码:
onEnter:function(){ //调用父类方法 this._super(); //设置主界面菜单y坐标 this._itemMenu.y = TestController.YOffset; },
接下来查看testNames数组的结构:
var testNames = [ { title:"ActionManager Test", platforms: PLATFORM_ALL, linksrc:"src/ActionManagerTest/ActionManagerTest.js", testScene:function () { return new ActionManagerTestScene(); } }, { title:"Actions Test", platforms: PLATFORM_ALL, linksrc:"src/ActionsTest/ActionsTest.js", testScene:function () { return new ActionsTestScene(); } }
到了这一步,主界面已经显示出来了,现在就是最后一步,当点击其中一项是,他又干了什么,即回调函数onMenuCallback,查看源码:
onMenuCallback:function (sender) { TestController.YOffset = this._itemMenu.y; var idx = sender.getLocalZOrder() - 10000; // get the userdata, it's the index of the menu item clicked // create the test scene and run it autoTestCurrentTestName = testNames[idx].title; var testCase = testNames[idx]; var res = testCase.resource || []; cc.LoaderScene.preload(res, function () { var scene = testCase.testScene(); console.log(scene); if (scene) { scene.runThisTest(); } }, this); }
到了这一步,接下来要分析的是scene.runThisTest()函数做了什么,怎么切换场景了,自己选择感兴趣地模块分析吧。GOOD LUCK!!!!!1
- cocos2d-js解析官方js-test实例入口
- cocos2d-js解析官方js-test实例入口
- Cocos2d-JS 官方文档
- 【cocos2d-js官方文档】十三、CCSAXParser.js
- 【cocos2d-js官方文档】十三、CCSAXParser.js
- 【cocos2d-js官方文档】一、搭建 Cocos2d-JS 开发环境
- 【cocos2d-js官方文档】一、搭建 Cocos2d-JS 开发环境
- 【cocos2d-js官方文档】一、搭建 Cocos2d-JS 开发环境
- js解析xml 实例
- 【cocos2d-js官方文档】四、基础数据类型
- 【cocos2d-js官方文档】六、cc.async
- 【cocos2d-js官方文档】七、CCFileUtils
- 【cocos2d-js官方文档】八、cc.game
- 【cocos2d-js官方文档】九、cc.loader
- 【cocos2d-js官方文档】十、log
- 【cocos2d-js官方文档】十一、cc.path
- 【cocos2d-js官方文档】十五、cc.sys
- 【cocos2d-js官方文档】十六、create
- idea 快捷键整理 很有用的快捷键
- Linux 日志系统
- Understanding the difficulty of training deep feedforward neural networks
- mysql数据库千万级别数据的查询优化和分页测试
- DHCP字段含义
- cocos2d-js解析官方js-test实例入口
- Using Session State in a Web Service
- 去除字符串空格\t,\n,\r等字符
- mfc c++ navmesh自动寻路实现
- 关于super的笔记
- [转][整理]extern "C"的用法解析
- 一页纸说清楚“什么是推荐系统”
- Git基础
- serverlet 返回json