Cocos2d-js可以实现在网页上运行高性能的2D游戏,实现原理是通过HTML5的canvas标签,该引擎采用Javascript编写,并且有自己的一些语法,因为没有成熟的IDE,一般建立工程是通过WebStorm手动创建文件与文件夹,实现将引擎跑起来,下面详解一下运行过程。

首先,用户最先访问到的是index.html页面,在index.html中引入引擎的启动文件CCBoot.js和自己编写的游戏的启动文件main.js。除此之外,还需要在工程的根目录下写一个project.json,来描述工程,引擎会自动读入这个文件,确定工程的类型、功能设置、引入的模块、自己的js文件列表等。

一般是将cocos2d的引擎拷贝到自己的工程目录下,使用frameworks/cocos2d-html5这个目录下的引擎文件。

下面的流程图说明了cocos2d的基本工作流程:

下面我们以frameworks/cocos2d-html5/template为例分析一下这个工程。

工程的运行结果为在屏幕上显示Hello、屏幕分辨率、Logo等内容。

首先分析一下index.html这个文件。

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title>Cocos2d-html5 Hello World test</title>
  6. <link rel="icon" type="image/GIF" href="res/favicon.ico"/>
  7. <meta name="viewport" content="width=321,user-scalable=no" />
  8. <meta name="apple-mobile-web-app-capable" content="yes"/>
  9. <meta name="full-screen" content="yes"/>
  10. <meta name="screen-orientation" content="portrait"/>
  11. <meta name="x5-fullscreen" content="true"/>
  12. <meta name="360-fullscreen" content="true"/>
  13. <style>
  14. body, canvas, div {
  15. -moz-user-select: none;
  16. -webkit-user-select: none;
  17. -ms-user-select: none;
  18. -khtml-user-select: none;
  19. -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  20. }
  21. </style><pre name="code" class="html"><script src="../CCBoot.js"></script>
  22. <script src="main.js"></script>
  23. <body style="padding:0; margin: 0; background: #000;">
  24. <script src="res/loading.js"></script>
  25. <canvas id="gameCanvas" width="1920" height="1920"></canvas>
  26. </body>

<script src="../CCBoot.js"></script> <script src="main.js"></script></head><body style="padding:0; margin: 0; background: #000;"><script src="res/loading.js"></script><canvas id="gameCanvas" width="1920" height="1920"></canvas></body></html>

  1.  

Head中的大部分标签都是用于说明一些显示的属性,如果是手机网页应用则需要设置这些,如果是普通的网页应用则不必设置,可以省略成如下这样:

  1. <head>
  2. <title>Title</title>
  3. <meta name="viewport" content="user-scalable=no"/>
  4. <meta charset="utf-8"/>
  5. </head>

最重要的是js的引入和canvas标签:

  1. <script src="../CCBoot.js"></script>
  2. <script src="main.js"></script>

这个工程在body中还载入了loading.js,这个只是启动时的loading动画,可以不加。

  1. <body style="padding:0; margin: 0; background: #000;">
  2. <script src="res/loading.js"></script>
  3. <canvas id="gameCanvas" width="1920" height="1920"></canvas>
  4. </body>

要特别注意canvas的id,在json中需要声明它,供引擎使用。

接下来,通过CCBoot.js,引擎会去加载和解析project.json,注意把它放在工程的根目录下,下面我们来看看这个json文件的内容:

  1. {
  2. "debugMode" : 1,
  3. "noCache": true,
  4. "showFPS" : true,
  5. "frameRate" : 60,
  6. "id" : "gameCanvas",
  7. "renderMode" : 0,
  8. "engineDir":"../",
  9.  
  10. "modules" : ["cocos2d"],
  11.  
  12. "jsList" : [
  13. "src/resource.js",
  14. "src/myApp.js"
  15. ]
  16. }

按照json的标准格式,这个文件说明了工程的调试模式、是否缓存、是否显示帧率、最大帧率、canvas的id、渲染模式、还有引擎的路径,注意引擎路径这里,因为这个模版工程是寄生在frameworks之内的,因此它的上一层目录就是引擎,对于一般的工程一定要找到引擎的正确位置,在frameworks/cocos2d-html5。

其中,jList是要加载的js文件列表,在这里加载后,以后在任何文件的任何位置都可以访问这些js文件。

下面我们看一下工程的目录结构:

src中一般用于存放自己的js文件,也就是jsList中要加载的那些文件,而资源文件一般放到res中,为了保证性能,资源文件不应当在一开始就全部加载到工程中,而应当进行懒加载,即使用时才加载,为了方便加载资源,一般会写一个resource.js来对资源路径和分类进行封装,下面我们来看看resource.js的内容:

  1. var s_HelloWorld = "HelloWorld.jpg";
  2. var s_CloseNormal = "CloseNormal.png";
  3. var s_CloseSelected = "CloseSelected.png";
  4.  
  5. var g_resources = [
  6. //image
  7. s_HelloWorld,
  8. s_CloseNormal,
  9. s_CloseSelected
  10.  
  11. ];

当前工程只有三种图片,HelloWorld的Logo、一个按钮的两种状态,首先定义变量存储图片路径,然后用一个数组存储一次性要用到的所有资源,因为这个模版只有一个场景,因此只需要一个资源数组,这个资源数组可以在main.js中进入场景时传入,实现在场景切换完成后同时实现资源的加载。

由于index.html中包含了main.js,因此会运行main.js,下面我们看main.js的内容:

  1. cc.game.onStart = function(){
  2. if(!cc.sys.isNative && document.getElementById("cocosLoading")) //If referenced loading.js, please remove it
  3. document.body.removeChild(document.getElementById("cocosLoading"));
  4.  
  5. var designSize = cc.size(480, 800);
  6. var screenSize = cc.view.getFrameSize();
  7.  
  8. if(!cc.sys.isNative && screenSize.height < 800){
  9. designSize = cc.size(320, 480);
  10. cc.loader.resPath = "res/Normal";
  11. }else{
  12. cc.loader.resPath = "res/HD";
  13. }
  14.  
  15. cc.view.setDesignResolutionSize(designSize.width, designSize.height, cc.ResolutionPolicy.SHOW_ALL);
  16.  
  17. //load resources
  18. cc.LoaderScene.preload(g_resources, function () {
  19. cc.director.runScene(new MyScene());
  20. }, this);
  21. };
  22. cc.game.run();

这里用到了cc.game这个类,重写了它的onStart方法,在cocos2d-js中,所有的API都是以cc开头,全部使用点语法,在调用cc.game.run()方法之后,cc.game会自动调用onStart方法,从而实现工程设置与场景的加载。

注意最后一句:

  1. //load resources
  2. cc.LoaderScene.preload(g_resources, function () {
  3. cc.director.runScene(new MyScene());
  4. }, this);

用到了cc.LoaderScene的preload方法来切换场景,这个方法的参数如下:

  1. cc.LoaderScene.preload(resources, cb, target)

其中第一个参数是在切换场景时要加载的资源,这里的g_resources是在上述的resource.js中定义的;第二个参数是要加载的内容,用大括号包围,其内写上切换的代码;第三个参数是目标,一般都是填写this。

要实现切换场景,使用的是cc.director的runScene方法,director的含义是导演,这个类的命名十分的形象,说明这个类是控制场景切换和游戏走向的,可以从中获取场景的一些数据和切换场景。

传入的参数是一个场景的实例,MyScene这个类是在哪里定义的呢?注意到jsList中还有一个文件myApp.js没被提到过,它便是定义MyScene类的文件。

它的代码如下:

  1. var MyLayer = cc.Layer.extend({
  2. helloLabel:null,
  3. sprite:null,
  4.  
  5. init:function () {
  6.  
  7. //////////////////////////////
  8. // 1. super init first
  9. this._super();
  10.  
  11. /////////////////////////////
  12. // 2. add a menu item with "X" image, which is clicked to quit the program
  13. // you may modify it.
  14. // ask director the window size
  15. var size = cc.director.getWinSize();
  16.  
  17. // add a "close" icon to exit the progress. it's an autorelease object
  18. var closeItem = new cc.MenuItemImage(
  19. s_CloseNormal,
  20. s_CloseSelected,
  21. function () {
  22. cc.log("close");
  23. },this);
  24. closeItem.setAnchorPoint(0.5, 0.5);
  25.  
  26. var menu = new cc.Menu(closeItem);
  27. menu.setPosition(0, 0);
  28. this.addChild(menu, 1);
  29. closeItem.setPosition(size.width - 20, 20);
  30.  
  31. /////////////////////////////
  32. // 3. add your codes below...
  33. // add a label shows "Hello World"
  34. // create and initialize a label
  35. this.helloLabel = new cc.LabelTTF("Hello", "Impact", 38);
  36. // position the label on the center of the screen
  37. this.helloLabel.setPosition(size.width / 2, size.height - 40);
  38. // add the label as a child to this layer
  39. this.addChild(this.helloLabel, 5);
  40.  
  41. // add "Helloworld" splash screen"
  42. this.sprite = new cc.Sprite(s_HelloWorld);
  43. this.sprite.setAnchorPoint(0.5, 0.5);
  44. this.sprite.setPosition(size.width / 2, size.height / 2);
  45. this.sprite.setScale(size.height / this.sprite.getContentSize().height);
  46. this.addChild(this.sprite, 0);
  47. }
  48. });
  49.  
  50. var MyScene = cc.Scene.extend({
  51. onEnter:function () {
  52. this._super();
  53. var layer = new MyLayer();
  54. this.addChild(layer);
  55. layer.init();
  56. }
  57. });

首先第一行可以看到对MyLayer类的定义,这里先提一下,cocos2d-JS中对类的继承是通过调用extend方法实现的,传入的为类的具体内容,例如要继承CCLayer类,则按第一行代码写var MyLayer = cc.Layer.extend({...});

再看最后几行代码,定义了一个继承自Scene的类,这里之所以有两个类,是因为切换场景时接收的是Scene,而为了实现用户输入,应到使用Layer,因此一个常用的用法是先定义一个Layer,再定义一个Scene,在Scene中实现把Layer加入到Scene中,然后在Layer中写代码。

CCLayer与CCScene都是继承自CCNode 的类,其中CCLayer比CCScene多了用户输入的功能。

这时候我们再回到上面的preload代码,在那里实例化MyScene,场景在实例化时会调用onEnter方法,只要重写onEnter方法,在场景中加入一个Layer即可。

接下来,在Layer中写主要代码即可,有关cocos2d-js的具体语法详见下一篇。

cocos2d-js(一)引擎的工作原理和文件的调用顺序的更多相关文章

  1. JSP引擎的工作原理

    JSP运行环境: 执行JSP代码需要在服务器上安装JSP引擎,比较常见的引擎有WebLogic和Tomcat.把这些支持JSP的web服务器配置好后.就可以再客户端通过浏览器来访问JSP页面了.默认端 ...

  2. Optaplanner规划引擎的工作原理及简单示例(2)

    开篇 在前面一篇关于规划引擎Optapalnner的文章里(Optaplanner规划引擎的工作原理及简单示例(1)),老农介绍了应用Optaplanner过程中需要掌握的一些基本概念,这些概念有且于 ...

  3. js:我们应该如何去了解JavaScript引擎的工作原理(转)

    http://www.nowamagic.net/librarys/veda/detail/1579 昨天收到一封来自深圳的一位前端童鞋的邮件,邮件内容如下(很抱歉,未经过他的允许,公开邮件内容,不过 ...

  4. 我们应该如何去了解JavaScript引擎的工作原理

    “读了你的几篇关于JS(变量对象.作用域.上下文.执行代码)的文章,我个人觉得有点抽象,难以深刻理解.我想请教下通过什么途径能够深入点的了解javascript解析引擎在执行代码前后是怎么工作的,ec ...

  5. 【转】我们应该如何去了解JavaScript引擎的工作原理

    原文地址:http://www.nowamagic.net/librarys/veda/detail/1579 昨天收到一封来自深圳的一位前端童鞋的邮件,邮件内容如下(很抱歉,未经过他的允许,公开邮件 ...

  6. doT.js模板引擎及基础原理

    时至今日,基于后端JavaScript(Node.js)和MVC思想也开始流行起来.模板引擎是数据和页面分离工作中最重要的一环,在各大门户网站均有利用到模板引擎. 模板引擎有很多种,但是原理了解也是非 ...

  7. 复杂事件处理引擎—Esper工作原理

    前面对Esper进行了概述,包括事件类型.事件流.事件窗口以及EPL相关内容.当然,上面的知识,对于简单的Esper开发,应该已经足够,能够根据自己业务需求,做出一个满足需要的Esper应用.但是,真 ...

  8. Node.js的require()的工作原理

    大多数人都知道Node.js中require()函数做什么的,但是有多少人知道它的工作原理呢?我们每天使用它加载库包和模块,但是它的内部行为原理很神秘. 我们追寻Node模块系统的核心: module ...

  9. 【转】NativeScript的工作原理:用JavaScript调用原生API实现跨平台

    原文:https://blog.csdn.net/qq_21298703/article/details/44982547 -------------------------------------- ...

随机推荐

  1. Button 使用Command 按钮置灰未更新

    当Button绑定了Command,按钮在窗口弹出.或者其它事件时,会自动置灰. 有时,异步执行时间较长时,界面一些绑定了命令的Button,State不会变化,会一直置灰. 直到再次转移Focus. ...

  2. numpy.squeeze()是干啥的

    例子: a = 3 print np.squeeze(a) # 输出3 a = [3] print np.squeeze(a) # 输出3 a = [[3]] print np.squeeze(a) ...

  3. 基于babylon3D模型研究3D骨骼动画(1)

    3D骨骼动画是实现较为复杂3D场景的重要技术,Babylon.js引擎内置了对骨骼动画的支持,但Babylon.js使用的骨骼动画的模型多是从3DsMax.Blender等3D建模工具转换而来,骨骼动 ...

  4. VueJs(4)---V-model指令

    V-model指令 摘要   限制: v-model只能用在:<input>    <select>    <textarea>  <components&g ...

  5. 关于 minor allele frequency(次等位基因频率)的理解

    引用自NCBI的概念(https://www.ncbi.nlm.nih.gov/projects/SNP/docs/rs_attributes.html#gmaf) Global minor alle ...

  6. TCP的TIME_WAIT状态

    主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时 ...

  7. Android二维码扫描、生成

    Android二维码扫描.生成 现在使用二维码作为信息的载体已经越来越普及,那么二维码的生成以及扫描是如何实现的呢 google为我们提供了zxing开源库供我们使用 zxing GitHub源码地址 ...

  8. Python+Tkinter 密保小工具

    上图 代码 核心 编解码方面 Tkinter界面更新 总结 昨天被一同学告知,网上的一个QQ密码库中有我的一条记录,当时我就震惊了,赶紧换了密码.当然了,这件事也给了我一个警示,那就是定期的更换自己的 ...

  9. 一道有趣的Twitter技术面试题

    来自:http://blog.jobbole.com/50705/ 看下面这个图片” “在这个图片里我们有不同高度的墙.这个图片由一个整数数组所代表,数组中每个数是墙的高度.上边的图可以表示为数组[2 ...

  10. Android事件分发传递回传机制详解

    转载本专栏每一篇博客请注明转载出处地址,尊重原创.此博客转载链接地址:点击打开链接   http://blog.csdn.net/qq_32059827/article/details/5257701 ...