cocos2d-js javascriptbinding实现
cocos2dx新创建项目android部分却少build_native.py 文件需要用cocos 命令行进行编译: 基础配置部分: (for mac) /cocos2d-x-3.x/tools/cocos2d-console/bin下 (ccoos2dx 3.12)
1. chmod u+x cocos.py 2. ./cocos.py new HelloWorldDemo -p com.coco2dx.org -l cpp -d ~/Desktop (创建项目) 3. 先要cd进入proj.android目录 cocos compile -p android (debug 编译) 4. 先要cd进入proj.android目录 cocos compile -p android -m release (release 编译) 5. 下载macport 软件下载:http://www.ccvita.com/434.html(找到对应的操作系统版本) 官网(https://www.macports.org/install.php) - 环境变量设置: 修改.bash_profile 文件 添加: export PATH=/opt/local/bin:$PATH export PATH=/opt/local/sbin:$PATH source .bash_profile (修改环境变量) - 操作指南: sudo port -v selfupdate (mac ports更新) port search name (搜索软件) sudo port install name (安装软件) sudo port uninstall name (卸载软件) port outdated (查看软件版本) sudo port upgrade outdated (升级软件) - mac port 安卓: sudo port install python27 py27-yaml py27-cheetah 6. 下来jsbinding一次你就知道有多坑,js版本必须要把原工程的tools拷贝过来(这里可以直接使用cocos2dx引擎下的tools文件夹即可),否则是不可以 pythongenbindings.py 无法使用的,但是lua比较正常; 7. 进入当前生成项目下的tools 中的 tojs文件加,复制一下cocos2dx_experimental_webView.ini进行修改操作,重命名TestJSB.ini; - 修改项: [TestJSB] # the prefix to be added to the generated functions. You might or might not use this in your own # templates prefix = TestJSB # 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 = my macro_judgement = #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID || CC_TARGET_PLATFORM == CC_PLATFORM_IOS) && !defined(CC_TARGET_OS_TVOS) 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/%(clang_version)s/include clang_flags = -nostdinc -x c++ -std=c++11 -U __SSE__ cocos_headers = -I%(cocosdir)s/cocos -I%(cocosdir)s/cocos/editor-support -I%(cocosdir)s/cocos/platform/android cocos_flags = -DANDROID 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/TestJSB.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 = TestJSB # 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 = # 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 8. 添加c++ 原文件与头文件: - 文件名称: TestJSB.h TestJSB.cpp - 代码: //TestJSB.h // TestJSB.hpp // TestCocosJs // // Created by kaitiren on 16/8/4. // // #ifndef TestJSB_hpp #define TestJSB_hpp #include <stdio.h> #include "cocos2d.h" using namespace cocos2d; class TestJSB : public cocos2d::Layer { public: TestJSB(); ~TestJSB(); void testprint(void); void testString(const char* _str); void testInt(int value); void testLong(long value); void testBool(bool isBoo);
CREATE_FUNC(TestJSB); }; #endif /* TestJSB_h */ ///TestJSB.cpp // // TestJSB.cpp // TestCocosJs // // Created by kaitiren on 16/8/4. // #include "TestJSB.h" TestJSB:: TestJSB() { printf("n TestJSB:: TestJSB() n"); } TestJSB:: ~TestJSB() {
} void TestJSB:: testprint(void) { CCLOG("TestJSB:: testprint(void)"); printf("n TestJSB:: testprint(void) n"); } void TestJSB:: testString(const char* _str) { printf("n TestJSB:: testString(_str): %s n",_str); } void TestJSB:: testInt(int value) { printf("n TestJSB:: testInt: %d n ",value); } void TestJSB:: testLong(long value) { printf("n TestJSB:: testLong: %ld n ",value); } void TestJSB:: testBool(bool isBoo) { printf("n TestJSB:: testBool: %d n",isBoo); } /// cpp 9. 编译pythongenbindings.py 文件,查看错误部分,并且修改,完成后进行添加到xcode工程(注意: 在cocos2d_js_bindings.xcodeproj项目下的auto 文件加进行添加,这里有一个坑是必须要添加到ios项目内,否则识别不到); 坑: 如果cpp文件头文件搜索不到自行添加一下即可; 注意导入头文件部分:#include"../../../../../runtime-src/Classes/TestJSB.h" 修改genbindings.py文件:
cmd_args = { #'cocos2dx.ini': ('cocos2d-x','jsb_cocos2dx_auto'), #'cocos2dx_audioengine.ini': ('cocos2dx_audioengine','jsb_cocos2dx_audioengine_auto'), #'cocos2dx_extension.ini': ('cocos2dx_extension','jsb_cocos2dx_extension_auto'), #'cocos2dx_builder.ini': ('cocos2dx_builder','jsb_cocos2dx_builder_auto'), #'cocos2dx_ui.ini': ('cocos2dx_ui','jsb_cocos2dx_ui_auto'), #'cocos2dx_studio.ini': ('cocos2dx_studio','jsb_cocos2dx_studio_auto'), #'cocos2dx_spine.ini': ('cocos2dx_spine','jsb_cocos2dx_spine_auto'), #'cocos2dx_3d.ini': ('cocos2dx_3d','jsb_cocos2dx_3d_auto'), #'cocos2dx_3d_ext.ini': ('cocos2dx_3d_extension','jsb_cocos2dx_3d_extension_auto'), #'cocos2dx_experimental_webView.ini': ('cocos2dx_experimental_webView','jsb_cocos2dx_experimental_webView_auto'), #'cocos2dx_experimental_video.ini': ('cocos2dx_experimental_video','jsb_cocos2dx_experimental_video_auto'), #'cocos2dx_physics3d.ini': ('cocos2dx_physics3d','jsb_cocos2dx_physics3d_auto'), 'cocos2dx_navmesh.ini': ('cocos2dx_navmesh','jsb_cocos2dx_navmesh_auto'), ################################################# 'TestJSB.ini': ('TestJSB','jsb_testjsb_auto'), 'JSBindingIOSWXManager.ini': ('JSBindingIOSWXManager','jsbinding_ioswxmanager_auto'),#添加部分 } 10. 进入当前项目的Classes中的AppDelegate.cpp: - 修改代码: 添加:"scripting/js-bindings/auto/jsb_testjsb_auto.hpp" 注册代码: sc->addRegisterCallback(register_all_TestJSB); 这里可以从jsb_testjsb_auto.hpp 中查找; 完成后进行xcode build操作; 11. 进行js代码编辑与测试: (进入 app.js HelloWorldScene) - 添加测试代码 var HelloWorldScene = cc.Scene.extend({ onEnter:function () { this._super(); var layer = new HelloWorldLayer(); this.addChild(layer); /// console.log("aaaaaaaassssssss"); /// var testJSB = new my.TestJSB(); testJSB.testprint(); testJSB.testString("pppppppppppppppppppppppp"); testJSB.testInt(123); testJSB.testLong(999999999999); testJSB.testBool(true); } }); 控制台输出如果正常js 调用 c++ 部分结束; 12. 解决c++ 调用 js 部分: (进入jsb_testjsb_auto.cpp文件夹) c++ 模块: bool js_TestJSB_TestJSB_testString(JSContext *cx,uint32_t argc,jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc,vp); bool ok = true; JS::RootedObject obj(cx,args.thisv().toObjectOrNull()); js_proxy_t *proxy = jsb_get_js_proxy(obj); TestJSB* cobj = (TestJSB *)(proxy ? proxy->ptr : NULL); JSB_PRECONDITION2( cobj,cx,false,"js_TestJSB_TestJSB_testString : Invalid Native Object"); if (argc == 1) { const char* arg0 = nullptr; std::string arg0_tmp; ok &= jsval_to_std_string(cx,args.get(0),&arg0_tmp); arg0 = arg0_tmp.c_str(); JSB_PRECONDITION2(ok,"js_TestJSB_TestJSB_testString : Error processing arguments"); cobj->testString(arg0); args.rval().setUndefined();
/// c++ 调用 js 部分 JSContext* jc = ScriptingCore::getInstance()->getGlobalContext(); // jsval ret; ScriptingCore::getInstance()->evalString( "cpp_callback(5,100)" ); // js 全局方法 /// c++ 调用 js 部分 /// ScriptingCore::getInstance()->executeFunctionWithOwner(<#jsval owner#>,<#const char *name#>,<#uint32_t argc#>,<#jsval *vp#>) // 此方法可调用全局文件 return true; } JS_ReportError(cx,"js_TestJSB_TestJSB_testString : wrong number of arguments: %d,was expecting %d",argc,1); return false; } js 模块: function cpp_callback(a,b) { cc.log("cpp return two integer: " + a + " " b "ssssssssssssssssssssssssssssssssss"); } 模拟器与移动端运行正常打印; 13. 区分native与web: if(cc.sys.isNative) { "platform is native !!!"); var testJSB = new my.TestJSB(); testJSB.testprint(); testString("pppppppppppppppppppppppp"); testInt(123); testLong(999999999999); testBool(true); } else { "sys.platform is browser !!!"); } js binding 部分完结; 14. android版本编译部分; 编译android到当前项目下的proj.android中 控制台执行: cocos compile -p android 如果有jsb的部分要修改android.mk两处: - 第一处是在当前项目下runtime-src中的proj.android,导入classes文件夹下的cpp文件到android.mk中; - 第二处是在/cocos2d-x/cocos/scripting/js-bindings/proj.android/Android.mk进行binding.cpp文件添加; 完成后接续ndk编译尝试; 15. 疑难错误解答: error: JS: assets/src/app.js:36:ReferenceError: my is not defined 查看AppDelegate.cpp是否没有注册要jsb的cpp函数; 如: sc->addRegisterCallback(register_all_JSBindingIOSWXManager); error: cpp调用js方法传参问题: (这里可以放到任何一个cpp内:)
#include"scripting/js-bindings/manual/cocos2d_specifics.hpp" "jsapi.h" "jsfriendapi.h"
例子: c++:
JSC 进行cocos js代码加密: ter: cocos jscompile -s /Users/fox/Documents/js -d /Users/fox/Documents/jsc -s:js文件路径 -d:jsc输出路径
拷贝项目内的js原文件夹: js文件路径: /Users/xxx/xxx/ClientC2DJs/src /Users/xxx/xxx/ClientC2DJs/frameworks/cocos2d-x/cocos/scripting/js-bindings/script 执行代码: cocos jscompile -s /Users/fox/Documents/js -d /Users/fox/Documents/jsc 完成后替换项目中的两个文件夹: ...cocos2d/jsbinding/script 不要替换jsbinding中的auto文件夹,...逻辑部分src 但是不要替换main; 完成后运行测试; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |