您的位置:首页 > Web前端 > JavaScript

coco2d-js在HTML上可以运行,但是打包apk后会黑屏

2016-01-31 15:24 555 查看
刚开始学习cocos2d-js,在网页上运行或者调试自己做的游戏的时候没有任何问题,但是当我把程序发布到android上测试的时候会黑屏。也就是说运行在手机上的apk只有漆黑一片。如果我们看到logcat打印的日志就会发现其实是因为出错了。出错的原因涉及到js跟cocos2d-x的内存管理机制。

js的内存管理机制是使用两种策略-------引用计数跟标记清除。

cocos2d-x用的是一种更原始的半自动化方案

想要详细了解的话可以查询一下相关的资料

下面这个例子就是在html上可以运行,但是在手机上会黑屏:

var TestLayer = cc.Layer.extend({
ctor: function () {
this._super();

var sp = new cc.Sprite(res.test);
this.scheduleOnce(function () {
this.addChild(sp);
sp.x = cc.winSize.width/2;
sp.y = cc.winSize.height/2;
}.bind(this),2); //两秒后再添加到舞台
}
});

var Game = cc.Scene.extend({
onEnter: function () {
this._super();
var layer = TestLayer();
this.addChild(layer);
}
});
看logcat的打印的日志的话有Invalid Native Objext

就是因为内存机制的不同,在手机上运行的话新建的sp精灵没有马上添加到舞台上,sp就会马上被收回。两秒后再次使用的话就会报错。

解决方案就是:运用retain 跟 release配合

用retain可以让cocos2d-x的内存机制使sp的计数器变为2,然后内存就不会把sp对象回收,如果我们也不想让sp精灵一直存在的话在适当的地方要记得release方法

上面的例子这样改就不会出错了:

var TestLayer = cc.Layer.extend({
ctor: function () {
this._super();

var sp = new cc.Sprite(res.test);
sp.retain();    //计数器加一
this.scheduleOnce(function () {
this.addChild(sp);
this.release();   //计数器减一
sp.x = cc.winSize.width/2;
sp.y = cc.winSize.height/2;
}.bind(this),2); //两秒后再添加到舞台
}
});

var Game = cc.Scene.extend({
onEnter: function () {
this._super();
var layer = TestLayer();
this.addChild(layer);
}
});

一般我们需要在以下两中情况下注意内存管理:

1,新建的节点不马上添加到舞台中

2,舞台删除了这个节点,但是下一帧还要使用这个节点

因为节点在脱离了显示列表后就会被内存机制马上回收。需要用retain保存下来。在合适的地方release,不然该节点会永远存在。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: