js开发html5游戏怎么样,用JavaScript开发HTML5与C++游戏

这是个对cocos JS的简单经验谈,让大家明白引擎原理,以及使用JS开发过程中要注意的事项,但不会涉及太多基本编程知识以及基础安装等,在阅读本文前请先对Javascript与Cocos有基本了解。

Cocos JS项目组成

首先,你可能会问:为什么cocos JS能同时开发HTML5与C++游戏?

我们先看看cocos JS 3.x(3.3)项目目录构成:

先建立一个项目:

cocos new HelloCococJS -p com.163.cocosjs -l js --ios-bundleid com.163.cocosjs

88ea458c5002?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

文件结构

大家看图上的标注:

cocos2d-html5引擎:纯html5引擎,在浏览器上的图形处理全靠它了;

js-bindings:为什么JS可以写原生游戏,关键就在这里;

runtime-src:原生的runtime工程,基础的Class文件,Android到iOS甚至Win32的工程;

tools:JSBinding工具

最让人好奇的是js-bindings,进入里面,里面有3个目录:

bindings:绑定脚本,一个脱水层,用于把cocos JS耦合到到原生引擎,稍候会讲到绑定原理;

cocos2d-x:cocos2d-x的C++引擎,就是那个原生引擎了;

external:里面就只有SpiderMonkey JS引擎,Firefox就是用它了,相比V8引擎,在kraken time与sunspider time测试中略胜V8。

88ea458c5002?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

上图:鲜红色为Firefox,分数越低越好

上图:鲜红色为Firefox,分数越低越好

看到这里,相信不少同学已经发出“哦~”一声,原来如此!

没错,cocos JS组件内包含了3个引擎1个工具:

在HTML5时,运行的是cocos2d-html5引擎,采用canvas或WebGL渲染;

在打包成原生时,SpiderMonkey做JS脚本运行解释器打包进去,同时编译cocos2d-x C++,前者通过JSB让JS调用后者的C++处理图形,原生除了JS外,已经与html5完全无关了,JS就是脚本语言,类似Lua。

88ea458c5002?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

JSBinding原理

JSBinding项目最初由zynga实现,用于胶合JS与Objective C的cocos2d-iphone,项目Github: jsbindings

JavaScript Bindings for C / Objective-C (JSB) is the "glue" code (or wrapper code) that sits between native code (C or Objective-C) and JavaScript (JS) code. JSB allows calling native code from JS and vice-versa.

现在已经移植到这里来,用于把cocos2d-x生成对应的JS接口,方法大致为:

编写配置文件.ini,通过tools下的bindings-generator,把C++类生成对应的辅助C++脚本以及Javascript接口脚本。

配置文件.ini作用

JSB本身就是一个工具,在项目中不负责运行代码,只生成C++对应的JS,而配置文件就是生成的规则,例如JSBinding 上的描述:

// CCAnimation (from cocos2d-iphone v2.0)

+(id) animationWithAnimationFrames:(NSArray*)arrayOfAnimationFrames delayPerUnit:(float)delayPerUnit loops:(NSUInteger)loops;

默认生成以下JS:

// ugly

cc.CCAnimation.animationWithAnimationFrames_delayPerUnit_loops_( frames, delay, loops );

通过规则配置,

method_properties = CCAnimation # animationWithAnimationFrames:delayPerUnit:loops: = name:"create",

可以生成:

// more JS friendly

cc.Animation.create( frames, delay, loops );

JS调用C++细节

JS:

gnode = cc.Node.create();

JSB C++:

JSBool js_cocos2dx_CCNode_create(JSContext *cx, uint32_t argc, jsval *vp)

{

if (argc == 0) {

cocos2d::CCNode* ret = cocos2d::CCNode::create();

jsval jsret;

do {

if (ret) {

js_proxy_t *proxy = js_get_or_create_proxy(cx, ret);

jsret = OBJECT_TO_JSVAL(proxy->obj);

} else {

jsret = JSVAL_NULL;

}

} while (0);

JS_SET_RVAL(cx, vp, jsret);

return JS_TRUE;

}

JS_ReportError(cx, "wrong number of arguments");

return JS_FALSE;

}

到这里,相信大家明白其中原理了,更深入的可以看文件夹:tools/bindings-generator/test 里的例子。

好了,JSBinding原理就简单说到这里。

实践心得

明白了上面的原理,假如要用JS作用脚本写原生游戏,应该怎么做呢?

在实践过程中,JS中大部分在 cc 命名空间下的接口都有对应的C++ API,小部分html5引擎特有的,有可能是历史遗留,幸好在开发过程中H5是可以实时预览的,也可以容易的放到iOS原生模拟器中看,如果出现类似JSB class not found的错误基本就是这个原因了,换一个写法就可以,这也是一个坑,需要慢慢踩。这里主要说一下JS怎么编码,因为JS自由度太大,所以最好结合JSB原理遵守一些规范。

(如有错误请不吝指正)

规范命名空间,例如 var tt = {} || tt;

JS类:统一用cc.Class.extend来实现,例如:

tt.Monster = cc.Class.extend({

id: ""

level: 1,

texture: null

});

这个好处是让JS类做到类似C++那样的继承,构造函数中通过this._super()可以调用父类构造函数;

除了cc,ccui这些引擎指定的命名空间可能会调用C++外,所有JS的编写与浏览器中编写没有任何区别;

效率问题:一般来说,不可交互的动画动作,都直接转化成C++接口,之后再也与JS无关不用担心效率问题;

可交互动作,例如touch事件拖动精灵,减少JS里的复杂运算增加效率,但经过测试拖动精灵原生中没有让人感觉有区别;

资源:虽然加载方式不一样,但原生使用上区别不大,两个点:一是touch事件接口有区别有坑要避雷,二是cocos studio只支持1.6及以前的json文件,以及最新cocos 2.1的json文件。

this.stage = guiReader.widgetFromJsonFile(res.StageUI_json);

this.addChild(this.stage, 200);

this.player = ccui.helper.seekWidgetByName(this.stage, "Player");

其它:虽然很多JS写法比较便利,例如 sripte.x = 20 ,但建议写成 sprite.setPositionX(20),只为避雷;

包大小问题

采用JSB写游戏的好处是可以真正的多端运行,但从原理可知这是怎么一个回事,如果要做原生,唯一问题就是包大小了,SpiderMonkey本身就近10m的.so文件,最后打出的iOS近10M,apk包7M,纯C++的iOS才2M多,元芳怎么看?

扩展思考

看了上面的原理,应该不难知道Egret也是类似这么干了吧,但Egret优点是JS的编写用了TypeScript,微软的进阶版JS,更OO和利于组件模块化。

时间有限,先介绍到这里,下一篇会写关于网络请求相关。

参考文献

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值