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这个文件。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Cocos2d-html5 Hello World test</title>
<link rel="icon" type="image/GIF" href="res/favicon.ico"/>
<meta name="viewport" content="width=321,user-scalable=no" />
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="full-screen" content="yes"/>
<meta name="screen-orientation" content="portrait"/>
<meta name="x5-fullscreen" content="true"/>
<meta name="360-fullscreen" content="true"/>
<style>
body, canvas, div {
-moz-user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
-khtml-user-select: none;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
</style><pre name="code" class="html"><script src="../CCBoot.js"></script>
<script src="main.js"></script>
<body style="padding:0; margin: 0; background: #000;">
<script src="res/loading.js"></script>
<canvas id="gameCanvas" width="1920" height="1920"></canvas>
</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>


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

<head>
<title>Title</title>
<meta name="viewport" content="user-scalable=no"/>
<meta charset="utf-8"/>
</head>

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

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

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

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

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

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

{
"debugMode" : 1,
"noCache": true,
"showFPS" : true,
"frameRate" : 60,
"id" : "gameCanvas",
"renderMode" : 0,
"engineDir":"../", "modules" : ["cocos2d"], "jsList" : [
"src/resource.js",
"src/myApp.js"
]
}

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

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

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

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

var s_HelloWorld = "HelloWorld.jpg";
var s_CloseNormal = "CloseNormal.png";
var s_CloseSelected = "CloseSelected.png"; var g_resources = [
//image
s_HelloWorld,
s_CloseNormal,
s_CloseSelected ];

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

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

cc.game.onStart = function(){
if(!cc.sys.isNative && document.getElementById("cocosLoading")) //If referenced loading.js, please remove it
document.body.removeChild(document.getElementById("cocosLoading")); var designSize = cc.size(480, 800);
var screenSize = cc.view.getFrameSize(); if(!cc.sys.isNative && screenSize.height < 800){
designSize = cc.size(320, 480);
cc.loader.resPath = "res/Normal";
}else{
cc.loader.resPath = "res/HD";
} cc.view.setDesignResolutionSize(designSize.width, designSize.height, cc.ResolutionPolicy.SHOW_ALL); //load resources
cc.LoaderScene.preload(g_resources, function () {
cc.director.runScene(new MyScene());
}, this);
};
cc.game.run();

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

注意最后一句:

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

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

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

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

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

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

它的代码如下:

var MyLayer = cc.Layer.extend({
helloLabel:null,
sprite:null, init: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 director the window size
var size = cc.director.getWinSize(); // add a "close" icon to exit the progress. it's an autorelease object
var closeItem = new cc.MenuItemImage(
s_CloseNormal,
s_CloseSelected,
function () {
cc.log("close");
},this);
closeItem.setAnchorPoint(0.5, 0.5); var menu = new cc.Menu(closeItem);
menu.setPosition(0, 0);
this.addChild(menu, 1);
closeItem.setPosition(size.width - 20, 20); /////////////////////////////
// 3. add your codes below...
// add a label shows "Hello World"
// create and initialize a label
this.helloLabel = new cc.LabelTTF("Hello", "Impact", 38);
// position the label on the center of the screen
this.helloLabel.setPosition(size.width / 2, size.height - 40);
// add the label as a child to this layer
this.addChild(this.helloLabel, 5); // add "Helloworld" splash screen"
this.sprite = new cc.Sprite(s_HelloWorld);
this.sprite.setAnchorPoint(0.5, 0.5);
this.sprite.setPosition(size.width / 2, size.height / 2);
this.sprite.setScale(size.height / this.sprite.getContentSize().height);
this.addChild(this.sprite, 0);
}
}); var MyScene = cc.Scene.extend({
onEnter:function () {
this._super();
var layer = new MyLayer();
this.addChild(layer);
layer.init();
}
});

首先第一行可以看到对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. SCNN车道线检测--(SCNN)Spatial As Deep: Spatial CNN for Traffic Scene Understanding(论文解读)

    Spatial As Deep: Spatial CNN for Traffic Scene Understanding 收录:AAAI2018 (AAAI Conference on Artific ...

  2. 手写JAVA虚拟机(三)——搜索class文件并读出内容

    查看手写JAVA虚拟机系列可以进我的博客园主页查看. 前面我们介绍了准备工作以及命令行的编写.既然我们的任务实现命令行中的java命令,同时我们知道java命令是将class文件(字节码)转换成机器码 ...

  3. MYSQL 表左连接 ON AND 和ON WHERE 的区别

    首先是针对左右连接,这里与inner join区分 在使用left join时,on and 和on where会有区别 1. on的条件是在连接生成临时表时使用的条件,以左表为基准 ,不管on中的条 ...

  4. github windows pycharm 设置

    Window 上pycharm数据上传到github 在window上操作 1),安装git(百度) 进入git , bin目录执行 git-bash.exe 1)  gengyantao@DESKT ...

  5. VLAN之间单臂路由通信

    实验目的 理解单臂路由的应用场景 掌握路由器子接口的配置方法 掌握子接口封装VLAN的配置方法 理解单臂路由的工作原理 实验原理 单臂路由解决用户需要跨越VLAN实现通信的情况. 原理:通过一台路由器 ...

  6. 用burpsuite暴力破解后台

    [实验原理] Burp Suite是Web应用程序测试的最佳工具之一,其多种功能执行各种任务.请求的拦截和修改,扫描web应用程序漏洞,以暴力破解登录表单,执行会话令牌等多种的随机性检查. Burp ...

  7. dephi FillChar 的几种写法

    //在 delphi 新版中, char 已经是双字节了.故应该重新自己写一个函数,取名为 FillByte ,才无歧义. procedure TForm1.Button2Click(Sender: ...

  8. Winform DevExpress控件库(一) DevExpress控件库的安装与新建第一个DevExpress项目

    前言:因为这段时间要接触到DevExpress控件库,而我本身甚至对winform的控件都了解甚少,所以处在学习中,写下博客主要是为了方便后期的回顾,当然也可以给一些新人第一次接触时做为学习的参考,以 ...

  9. post插件

    分享牛系列,分享牛专栏,分享牛.在项目开发中,http请求方式是最常见的了.怎么模拟http请求呢?方法有很多种,可以使用httpclient直接模拟请求,也可以使用火狐post插件方式,这个章节主要 ...

  10. 去除CSDN 博客页广告的历程

    第一招 方式1 方式2 第二招 第三招 素材准备 必备知识 代码部分 测试 总结 作为CSDN的忠实用户,我觉得它挺不错的.美中不足的是广告,虽然相比于微博啊,开源中国啊这些博客站点,它的广告已经算是 ...