Cocos Creator JSB [Lv.1]
Posted VermillionTear
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cocos Creator JSB [Lv.1] 相关的知识,希望对你有一定的参考价值。
摘要
承接上文 Cocos Creator JSB [Lv.1] (1)
在上文中我们已经找到了小姐姐,本文在此基础上终于可以跟小姐姐进行互动啦~
系列文章
正式开始
小姐姐的昵称以及芳龄
创建两个文本框,用来显示小姐姐的昵称以及芳龄。
在JSBController.js
中实现功能。
...
cc.Class({
...
properties: {
nickname: cc.Label, // 昵称
age: cc.Label, // 芳龄
},
...
start () {
_goddess.nickname = 'Honey' // 实际调用 Goddess 的 setName 函数。
this.nickname.string = _goddess.nickname // 实际调用 Goddess 的 getName 函数。
_goddess.age = 20 // 实际调用 Goddess 的 setAge 函数。
this.age.string = _goddess.age // 实际调用 Goddess 的 getAge 函数。
},
});
将节点挂载到脚本对应变量上。
接下来,要在C++
层面实现相应的函数。
Goddess.h
...
class CC_DLL Goddess
{
public:
...
// 对应成员变量的 set 和 get 方法。
inline const std::string& getNickName() const { return _nickname; };
inline void setNickName(std::string& nickname) { _nickname = nickname; };
inline const unsigned int getAge() const { return _age; };
inline void setAge(unsigned int age) { _age = age; };
protected:
...
std::string _nickname = "goddess"; // 昵称,随便写了个初始值。
unsigned int _age = 18; // 芳龄,随便写了个初始值。
};
...
jsb_cocos2dx_myjsb_auto.hpp
...
// 声明作为桥梁的函数。
// 桥梁函数的作用:
// 1、将js层面传递过来的参数从se::Value类型转换为C++的类型。
// 2、调用对应的(在js_register_xxx中绑定的)C++类的成员函数,并传递转换后的的参数。
// 3、得到返回值,并将其转换为se::Value类型。
// 4、存入s.rval中,s.rval中的值就是返回给js层面的返回值。
SE_DECLARE_FUNC(js_cocos2d_myjsb_Goddess_getNickName);
SE_DECLARE_FUNC(js_cocos2d_myjsb_Goddess_setNickName);
SE_DECLARE_FUNC(js_cocos2d_myjsb_Goddess_getAge);
SE_DECLARE_FUNC(js_cocos2d_myjsb_Goddess_setAge);
...
jsb_cocos2dx_myjsb_auto.cpp
...
// 桥梁函数,let foo = goddess.nickname 时,实际会调用到这里。
static bool js_cocos2d_myjsb_Goddess_get_nickname(se::State& s) {
// s.nativeThisObject() 可以获取到绑定的 C++ 类的实例。
cocos2d::myjsb::Goddess* cobj = (cocos2d::myjsb::Goddess*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2d_myjsb_Goddess_get_nickname : Invalid Native Object");
const auto& args = s.args(); // 传递的参数。
size_t argc = args.size(); // 参数的数量。
CC_UNUSED bool ok = true; // 参数转换是否成功的标志。
if (argc == 0) { // 需要0个参数。
// 不需要参数,也就没有了参数的转换部分。
std::string result = cobj->getNickName(); // 调用类的成员函数,并得到返回值。
// 将返回值转换为 se::Value 类型,并赋值到s.rval,s.rval中的值就是返回给js层面的返回值。
ok &= std_string_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2d_myjsb_Goddess_get_nickname : Error processing arguments");
return true;
}
// 传递的参数不正确时,打印的提示信息。
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_cocos2d_myjsb_Goddess_get_nickname);
// 桥梁函数,goddess.nickname = "foo" 时,实际会调用到这里。
static bool js_cocos2d_myjsb_Goddess_set_nickname(se::State& s) {
// s.nativeThisObject() 可以获取到绑定的 C++ 类的实例。
cocos2d::myjsb::Goddess* cobj = (cocos2d::myjsb::Goddess*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2d_myjsb_Goddess_set_nickname : Invalid Native Object");
const auto& args = s.args(); // 传递的参数。
size_t argc = args.size(); // 参数的数量。
CC_UNUSED bool ok = true; // 参数转换是否成功的标志。
if (argc == 1) { // 需要1个参数。
std::string nickname;
// 传递过来的昵称是 se::Value 的形式,将其转换为 std::string 。
ok &= seval_to_std_string(args[0], &nickname);
SE_PRECONDITION2(ok, false, "js_cocos2d_myjsb_Goddess_set_nickname : Error processing new value");
cobj->setNickName(nickname); // 调用类的成员函数,并传递转换后的参数。
// 因为此成员函数没有返回值,所以不用对 s.rval 赋值。
return true;
}
// 传递的参数不正确时,打印的提示信息。
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return true;
}
SE_BIND_PROP_SET(js_cocos2d_myjsb_Goddess_set_nickname);
// 桥梁函数,let foo = goddess.age 时,实际会调用到这里。
static bool js_cocos2d_myjsb_Goddess_get_age(se::State& s) {
// s.nativeThisObject() 可以获取到绑定的 C++ 类的实例。
cocos2d::myjsb::Goddess* cobj = (cocos2d::myjsb::Goddess*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2d_myjsb_Goddess_get_age : Invalid Native Object");
const auto& args = s.args(); // 传递的参数。
size_t argc = args.size(); // 参数的数量。
CC_UNUSED bool ok = true; // 参数转换是否成功的标志。
if (argc == 0) { // 需要0个参数。
// 不需要参数,也就没有了参数的转换部分。
unsigned int result = cobj->getAge(); // 调用类的成员函数,并得到返回值。
// 将返回值转换为 se::Value 类型,并赋值到s.rval,s.rval中的值就是返回给js层面的返回值。
ok &= uint32_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2d_myjsb_Goddess_get_age : Error processing arguments");
return true;
}
// 传递的参数不正确时,打印的提示信息。
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_PROP_GET(js_cocos2d_myjsb_Goddess_get_age);
// 桥梁函数,goddess.age = 123 时,实际会调用到这里。
static bool js_cocos2d_myjsb_Goddess_set_age(se::State& s) {
// s.nativeThisObject() 可以获取到绑定的 C++ 类的实例。
cocos2d::myjsb::Goddess* cobj = (cocos2d::myjsb::Goddess*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2d_myjsb_Goddess_set_age : Invalid Native Object");
const auto& args = s.args(); // 传递的参数。
size_t argc = args.size(); // 参数的数量。
CC_UNUSED bool ok = true; // 参数转换是否成功的标志。
if (argc == 1) { // 需要1个参数。
unsigned int age = 0;
// 传递过来的年龄值是 se::Value 的形式,将其转换为 unsigend int 。
ok &= seval_to_uint32(args[0], (uint32_t*)&age);
SE_PRECONDITION2(ok, false, "js_cocos2d_myjsb_Goddess_set_age : Error processing new value");
cobj->setAge(age); // 调用类的成员函数,并传递转换后的参数。
// 因为此成员函数没有返回值,所以不用对 s.rval 赋值。
return true;
}
// 传递的参数不正确时,打印的提示信息。
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 1);
return true;
}
SE_BIND_PROP_SET(js_cocos2d_myjsb_Goddess_set_age);
bool js_register_cocos2d_myjsb_Goddess(se::Object* obj) {
...
// 这里就是定义,jsb.Goddess要暴露出一个nickname属性,
// let foo = goddess.nickname 时,在JSB中要调用 js_cocos2d_myjsb_Goddess_get_nickname
// goddess.nickname = "foo" 时,在JSB中要调用 js_cocos2d_myjsb_Goddess_set_nickname
cls->defineProperty("nickname", _SE(js_cocos2d_myjsb_Goddess_get_nickname), _SE(js_cocos2d_myjsb_Goddess_set_nickname));
// 这里就是定义,jsb.Goddess要暴露出一个age属性,
// let foo = goddess.age 时,在JSB中要调用 js_cocos2d_myjsb_Goddess_get_age
// goddess.age = 123 时,在JSB中要调用 js_cocos2d_myjsb_Goddess_set_age
cls->defineProperty("age", _SE(js_cocos2d_myjsb_Goddess_get_age), _SE(js_cocos2d_myjsb_Goddess_set_age));
...
}
...
构建工程,然后就可以在Visual Studio
中编译运行起来了。
可以看到,我们在JSBController.js
中为小姐姐设置的昵称以及芳龄都显示出来了。
打个招呼
创建一个文本框,用来显示小姐姐说的话。
创建一个按钮,用来跟小姐姐打招呼。
在JSBController.js
中实现功能。
...
cc.Class({
...
properties: {
...
txt: cc.Label,
},
...
sayHi() {
this.txt.string = _goddess.sayHi()
},
});
将节点挂载到脚本对应变量上。
指定按钮点击后的回调函数。
接下来,要在C++层面实现相应的函数。
Goddess.h
...
class CC_DLL Goddess
{
public:
...
std::string sayHi(); // 打招呼的成员方法。
protected:
...
};
...
Goddess.cpp
...
namespace cocos2d { namespace myjsb {
...
// 就是简单返回一句话。
std::string Goddess::sayHi() {
std::string s = "Hi! Cutie~";
return s;
}
}} // namespace cocos2d::myjsb
jsb_cocos2dx_myjsb_auto.hpp
...
// 声明作为桥梁的函数。
// 桥梁函数的作用:
// 1、将js层面传递过来的参数从se::Value类型转换为C++的类型。
// 2、调用对应的(在js_register_xxx中绑定的)C++类的成员函数,并传递转换后的的参数。
// 3、得到返回值,并将其转换为se::Value类型。
// 4、存入s.rval中,s.rval中的值就是返回给js层面的返回值。
SE_DECLARE_FUNC(js_cocos2d_myjsb_Goddess_sayHi);
...
jsb_cocos2dx_myjsb_auto.cpp
...
// 桥梁函数,jsb.Goddess.sayHi() 时,实际会调用到这里。
static bool js_cocos2d_myjsb_Goddess_sayHi(se::State& s) {
// s.nativeThisObject() 可以获取到绑定的 C++ 类的实例。
cocos2d::myjsb::Goddess* cobj = (cocos2d::myjsb::Goddess*)s.nativeThisObject();
SE_PRECONDITION2(cobj, false, "js_cocos2d_myjsb_Goddess_sayHi : Invalid Native Object");
const auto& args = s.args(); // 传递的参数。
size_t argc = args.size(); // 参数的数量。
CC_UNUSED bool ok = true; // 参数转换是否成功的标志。
if (argc == 0) { // 需要0个参数。
// 不需要参数,也就没有了参数的转换部分。
std::string result = cobj->sayHi(); // 调用类的成员函数,并得到返回值。
// 将返回值转换为 se::Value 类型,并赋值到s.rval,s.rval中的值就是返回给js层面的返回值。
ok &= std_string_to_seval(result, &s.rval());
SE_PRECONDITION2(ok, false, "js_cocos2d_myjsb_Goddess_sayHi : Error processing arguments");
return true;
}
// 传递的参数不正确时,打印的提示信息。
SE_REPORT_ERROR("wrong number of arguments: %d, was expecting %d", (int)argc, 0);
return false;
}
SE_BIND_FUNC(js_cocos2d_myjsb_Goddess_sayHi);
bool js_register_cocos2d_myjsb_Goddess(se::Object* obj) {
...
// 这里就是定义,jsb.Goddess要暴露出一个sayHi函数,
// jsb.Goddess.sayHi() 时,在JSB中要调用 js_cocos2d_myjsb_Goddess_sayHi
cls->defineFunction("sayHi", _SE(js_cocos2d_myjsb_Goddess_sayHi));
...
}
...
构建工程,然后就可以在Visual Studio中编译运行起来了。
点击打招呼
按钮,小姐姐真的回应我们了~
划重点
- 桥梁函数的作用(4个步骤)。
- 绑定成员变量作为JS对象的属性的写法(
SET
,GET
)。 - 绑定成员函数(无参数,有返回值)的写法。
以上是关于Cocos Creator JSB [Lv.1] 的主要内容,如果未能解决你的问题,请参考以下文章