@gj_feixiang 写道:
本人需求,我们项目前期是做h5版本,但是目前要转app,所以要测试jsb.发现下面这个问题
这种情况两种解决办法1:游戏中用到的,换一种实现方式,显然不是很合适,! 2:改jsb层代码!
本人当然采用第二种实现方式
具体改法如下
jsb_cocos2dx_auto 中添加jsb构造接口
bool js_cocos2dx_ActionInterval_constructor(JSContext *cx, uint32_t argc, jsval *vp){
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
bool ok = true;
cocos2d::ActionInterval* cobj = new (std::nothrow) cocos2d::ActionInterval();
cocos2d::Ref *ccobj = dynamiccast(cobj);
if (_ccobj) {
_ccobj->autorelease();
}
TypeTest t;
js_type_class_t *typeClass = nullptr;
std::string typeName = t.s_name();
auto typeMapIter = jsglobal_type_map.find(typeName);
CCASSERT(typeMapIter != jsglobal_type_map.end(), "Can't find the class type!");
typeClass = typeMapIter->second;
CCASSERT(typeClass, "The value is null.");
// JSObject *obj = JS_NewObject(cx, typeClass->jsclass, typeClass->proto, typeClass->parentProto);
JS::RootedObject proto(cx, typeClass->proto.get());
JS::RootedObject parent(cx, typeClass->parentProto.get());
JS::RootedObject obj(cx, JS_NewObject(cx, typeClass->jsclass, proto, parent));
args.rval().set(OBJECT_TO_JSVAL(obj));
// link the native object with the javascript object
js_proxy_t* p = jsb_new_proxy(cobj, obj);
AddNamedObjectRoot(cx, &p->obj, "cocos2d::ActionInterval");
if (JS_HasProperty(cx, obj, "_ctor", &ok) && ok)
ScriptingCore::getInstance()->executeFunctionWithOwner(OBJECT_TO_JSVAL(obj), "_ctor", args);
return true;
}在注册jsb接口中作如下更改
void js_register_cocos2dx_ActionInterval(JSContext *cx, JS::HandleObject global) {
jsb_cocos2d_ActionInterval_class = (JSClass *)calloc(1, sizeof(JSClass));
jsb_cocos2d_ActionInterval_class->name = "ActionInterval";
jsb_cocos2d_ActionInterval_class->addProperty = JS_PropertyStub;
jsb_cocos2d_ActionInterval_class->delProperty = JS_DeletePropertyStub;
jsb_cocos2d_ActionInterval_class->getProperty = JS_PropertyStub;
jsb_cocos2d_ActionInterval_class->setProperty = JS_StrictPropertyStub;
jsb_cocos2d_ActionInterval_class->enumerate = JS_EnumerateStub;
jsb_cocos2d_ActionInterval_class->resolve = JS_ResolveStub;
jsb_cocos2d_ActionInterval_class->convert = JS_ConvertStub;
jsb_cocos2d_ActionInterval_class->finalize = js_cocos2d_ActionInterval_finalize;
jsb_cocos2d_ActionInterval_class->flags = JSCLASS_HAS_RESERVED_SLOTS(2);static JSPropertySpec properties[] = { JS_PSG("__nativeObj", js_is_native_obj, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_PS_END }; static JSFunctionSpec funcs[] = { JS_FN("getAmplitudeRate", js_cocos2dx_ActionInterval_getAmplitudeRate, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_FN("initWithDuration", js_cocos2dx_ActionInterval_initWithDuration, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_FN("setAmplitudeRate", js_cocos2dx_ActionInterval_setAmplitudeRate, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_FN("getElapsed", js_cocos2dx_ActionInterval_getElapsed, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE), JS_FS_END }; JSFunctionSpec *st_funcs = NULL; jsb_cocos2d_ActionInterval_prototype = JS_InitClass( cx, global, JS::RootedObject(cx, jsb_cocos2d_FiniteTimeAction_prototype), jsb_cocos2d_ActionInterval_class, js_cocos2dx_ActionInterval_constructor, 0, properties, funcs, NULL, // no static properties st_funcs); // make the class enumerable in the registered namespace // bool found; //FIXME: Removed in Firefox v27 // JS_SetPropertyAttributes(cx, global, "ActionInterval", JSPROP_ENUMERATE | JSPROP_READONLY, &found); // add the proto and JSClass to the type->js info hash table TypeTest<cocos2d::ActionInterval> t; js_type_class_t *p; std::string typeName = t.s_name(); if (_js_global_type_map.find(typeName) == _js_global_type_map.end()) { p = (js_type_class_t *)malloc(sizeof(js_type_class_t)); p->jsclass = jsb_cocos2d_ActionInterval_class; p->proto = jsb_cocos2d_ActionInterval_prototype; p->parentProto = jsb_cocos2d_FiniteTimeAction_prototype; _js_global_type_map.insert(std::make_pair(typeName, p)); } }
然后在js层中添加如下代码
if(!cc.ActionInterval.extend) {
cc.ActionInterval.extend = cc.Class.extend;
}项目中定义ActionInterval子类的方式如下
td.TruntableAction = cc.ActionInterval.extend(/** @lends cc.ScaleTo# */{_startPos: null, _endPos: null, _deltaPos: null, _poses: null, _timePassed: null, /** * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. * @param {Number} duration * @param {Number} sx scale parameter in X * @param {Number} [sy] scale parameter in Y, if Null equal to sx */ ctor:function () { cc.ActionInterval.prototype.ctor && cc.ActionInterval.prototype.ctor.call(this,duration); // jsb // this._super && this._super(); // js | html5 framework }, /** * Initializes the action. * @param {Number} duration * @param {Number} sx * @param {Number} [sy=] * @return {Boolean} */ initWithDuration:function (duration, poses, endPos) { //function overload here if (poses !== undefined && cc.ActionInterval.prototype.initWithDuration.call(this, duration)) { this._timePassed = 0; this._endPos = endPos; this._poses = poses; return true; } return false; }, /** * returns a new clone of the action * @returns {cc.ScaleTo} */ clone:function () { var action = new td.TruntableAction(); this._cloneDecoration(action); action.initWithDuration(this._duration, this._poses, this._endPos); return action; }, /** * Start the action with target. * @param {cc.Node} target */ startWithTarget:function (target) { cc.ActionInterval.prototype.startWithTarget.call(this, target); this._timePassed = 0; this._startPos = this._computeCurPos(); // cc.log("start pos is:" + this._startPos); var round = this._poses.length; var lastRoundSteps; if (this._endPos === this._startPos) { lastRoundSteps = round; } else { lastRoundSteps = (round + this._endPos - this._startPos) % round; } this._deltaPos = 2 * round + lastRoundSteps; // cc.log("delta pos is:" + this._deltaPos); }, _computeCurPos: function() { var pos = this.target.getPosition(); for (var i = 0; i < this._poses.length; i++) { var ipos = this._poses[i]; if (uf.utils.Math.distanceSQ(pos, ipos) <= 4) { return i; } } cc.error("pos error"); }, /** * Called once per frame. Time is the number of seconds of a frame interval. * @param {Number} dt */ update:function (dt) { dt = this._computeEaseTime(dt); if (this.target) { var targetPos = this._startPos + Math.floor(this._deltaPos * dt); // cc.log("dt: " + dt + ", targetPos:" + targetPos + ", real pos is:" + (targetPos % this._poses.length)); var position = this._poses[targetPos % this._poses.length]; this.target.setPosition(position); } }
});
但是,在new 的时候并没有调用js_cocos2dx_ActionInterval_constructor 这个接口导致报如下错误
TurntableActivityHome.js:293:Error: js_cocos2dx_ActionInterval_initWithDuration : Invalid Native Object还有一种方案就是在c++中实现该动画的自定义,然后到处到js中使用但是,本人对C++不是很熟,所以能导出ActionInterval直接在js中自定义最好!有哪位兄弟比较熟悉还望指教一二!
帖子: 2
参与者: 1