cocos官网最近更新,很多教程都没有了,这让本来就少的js资料,更少了。。。
这里是3.x版本的jsbinding,测试版本3.12,理论上3.x都会支持没,不负任何责任,有问题欢迎留言交流
参考文章:http://www.cocos2d-x.org/wiki/Binding_Custom_Class_To_Js_Runtime
自动绑定
bindings-generator, 它可以生成相对应的C++的绑定文件和相对应的JS接口,届时,你只需要调用生成的相对应的JS接口,它将自动转换成原来的C++的类,相当于直接调用原来的C++方法或者类。
用到的工具
1、cocos引擎
2、python2.7 ps:python版本必须是32位
3、py-ymal
4、cheetah
(关于3和4的安装,自行google)
5、Android NDK 版本一定要是r9b,不管它cocos版本要求的是什么版本的ndk,这里一定要用r9b,不然不成功!!!!!切记!!!!
需要手动拷贝引擎里的bindings-generator文件夹到项目的对应目录下
按照上面的文档翻译为中文如下:(win32下测试正常,原文环境是mac,估计推测应该win和mac都支持)
1、按照正常的方法编写需要绑定的C++类,这里使用测试类,位置: 项目根目录\framework\runtime-src\Classes\my\CustomClass.h & .cpp, 内容如下:
#pragma once
// CustomClass.h
#ifndef __CUSTOM__CLASS
#define __CUSTOM__CLASS
#include "cocos2d.h"
namespace cocos2d {
class CustomClass : public cocos2d::Ref
{
public:
CustomClass();
~CustomClass();
bool init();
std::string helloMsg();
CREATE_FUNC(CustomClass);
};
} //namespace cocos2d
#endif // __CUSTOM__CLASS
// CustomClass.cpp
#include "CustomClass.h"
USING_NS_CC;
CustomClass::CustomClass(){
}
CustomClass::~CustomClass(){
}
bool CustomClass::init(){
return true;
}
std::string CustomClass::helloMsg() {
return "Hello from CustomClass::sayHello";
}
2、在 项目根目录\frameworks\cocos2d-x\tools\tojs 下模仿cocos2dx.ini新建文件,cocos2dx_custom.ini,内容如下:
[cocos2dx_custom]
# the prefix to be added to the generated functions. You might or might not use this in your own
# templates
prefix = cocos2dx_custom
# create a target namespace (in javascript, this would create some code like the equiv. to `ns = ns || {}`)
# all classes will be embedded in that namespace
target_namespace = tt
android_headers = -I%(androidndkdir)s/platforms/android-14/arch-arm/usr/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.7/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/libs/armeabi-v7a/include -I%(androidndkdir)s/sources/cxx-stl/gnu-libstdc++/4.8/include
android_flags = -D_SIZE_T_DEFINED_
clang_headers = -I%(clangllvmdir)s/lib/clang/3.3/include
clang_flags = -nostdinc -x c++ -std=c++11 -U__SSE__
cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/my -I%(cocosdir)s/cocos/base -I%(cocosdir)s/cocos/platform/android
cocos_flags = -DANDROID -DCOCOS2D_JAVASCRIPT
cxxgenerator_headers =
# extra arguments for clang
extra_arguments = %(android_headers)s %(clang_headers)s %(cxxgenerator_headers)s %(cocos_headers)s %(android_flags)s %(clang_flags)s %(cocos_flags)s %(extra_flags)s
# what headers to parse
headers = %(cocosdir)s/../runtime-src/Classes/my/CustomClass.h
# what classes to produce code for. You can use regular expressions here. When testing the regular
# expression, it will be enclosed in "^$", like this: "^Menu*$".
classes = CustomClass.*
# what should we skip? in the format ClassName::[function function]
# ClassName is a regular expression, but will be used like this: "^ClassName$" functions are also
# regular expressions, they will not be surrounded by "^$". If you want to skip a whole class, just
# add a single "*" as functions. See bellow for several examples. A special class name is "*", which
# will apply to all class names. This is a convenience wildcard to be able to skip similar named
# functions from all classes.
skip =
rename_functions =
rename_classes =
# for all class names, should we remove something when registering in the target VM?
remove_prefix =
# classes for which there will be no "parent" lookup
classes_have_no_parents =
# base classes which will be skipped when their sub-classes found them.
base_classes_to_skip = Ref Clonable
# classes that create no constructor
# Set is special and we will use a hand-written constructor
abstract_classes =
# Determining whether to use script object(js object) to control the lifecycle of native(cpp) object or the other way around. Supported values are 'yes' or 'no'.
script_control_cpp = no
对于ini配置文件,这里我们修改了以下内容:
1).文件第1行中括号内的:cocos2dx_ui 修改为:cocos2dx_custom
2).prefix = cocos2dx_ui 修改为:prefix = cocos2dx_custom
3).target_namespace = ccui 修改为:target_namespace = tt
4).headers = (太长了这里省略) 修改为:headers=%(cocosdir)s/../runtime-src/Classes/my/CustomClass.h
这里的位置是根据自己的实际位置去填写,%(cocosdir)s的位置就是项目根目录frameworks\cocos2d-x目录
5).classes = CustomClass.*
这里等号后面的等于自己的C++类的名称
3、在ini文件同级目录下有一个genbindings.py文件,打开之后在custom_cmd_args = {}括号里面填上
'cocos2dx_custom.ini' : ('cocos2dx_custom', 'jsb_cocos2dx_custom'),
这里我会把文件中, cmd_args = {….}括号里面的内容注释掉,这样不会重新生成cocos本身的绑定文件,以节约时间。
4,在此目录下,cmd执行genbindings.py文件,如果不出错,会提示:
generating userconf.ini...
Generating bindings for cocos2dx_custom...
Using userconfig
[('androidndkdir', 'D:\\CocosEnvironment\\android-ndk-r9b'), ('clangllvmdir', 'D:\\CocosEnvironment\\android-ndk-r9b\\toolchains\\llvm-3.3\\prebuilt\\windows-x86_64'), ('cocosdir', 'C:\\Users\\guangbao\\Desktop\\test\\frameworks\\cocos2d-x'), ('jsbdir', 'C:\\Users\\guangbao\\Desktop\\test\\frameworks\\cocos2d-x\\cocos\\scripting\\js-bindings'), ('cxxgeneratordir', 'C:\\Users\\guangbao\\Desktop\\test\\frameworks\\cocos2d-x\\tools\\bindings-generator'), ('extra_flags', '-D__WCHAR_MAX__=0x7fffffff -U__MINGW32__'), ('clang_version', '3.3')]
.... Generating bindings for target spidermonkey
.... .... Processing section cocos2dx_custom
----------------------------------------
Generating javascript bindings succeeds.
----------------------------------------
表示生成绑定文件成功。
5、用vs打开我们的工程,打开解决方案libjscocos2d,在auto目录下导入刚刚生成的两个文件,文件目录在 项目根目录\frameworks\cocos2d-x\cocos\scripting\js-bindings\auto下,名为jsb_cocos2dx_custom.cpp&jsb_cocos2dx_custom.hpp
这里可能会提示“无法打开包括文件CustomClass.h”,只需在解决方案libjscocos2d上右击->属性->C/C++->附加包含目录,打开之后添加新的目录:$(EngineRoot)..\runtime-src\Classes\my即可
6,在AppDelegate.cpp文件中添加以下代码:
#include "scripting/js-bindings/auto/jsb_cocos2dx_custom.hpp"
....
sc->addRegisterCallback(register_all_cocos2dx_custom);
....
7,在js代码中调用:
var cla = tt.CustomClass.create();
var msg = cla.helloMsg();
cc.log("msg = " + msg);
然后vs运行项目,控制台输出:JS: msg = Hello from CustomClass::sayHello
就表示已经成功了
注意:编写ini文件的时候,clang_flags = …. 最后一定要加上 -U__SSE__,否则会报错:details = “use of undeclared identifier ‘_aligned_malloc’”>