在这里,我们将给大家分享关于Cocos2dx之为什么会有自动内存池的知识,让您更了解cocos2dx定时器的本质,同时也会涉及到如何更有效地关于cocos2dx接Androidsdk的一些坑、Bull
在这里,我们将给大家分享关于Cocos2dx之为什么会有自动内存池的知识,让您更了解cocos2dx 定时器的本质,同时也会涉及到如何更有效地
- Cocos2dx之为什么会有自动内存池(cocos2dx 定时器)
关于cocos2dx接Android sdk的一些坑 - Bullet(Cocos2dx)之交叉编译Android,集成到cocos2dx3.x
- Cocos2d-X 学习笔记 15 cocos2dx之CCUserDefault及其数据进行加密解密
- Cocos2d-X 学习笔记 19 cocos2d-x学习之自动内存管理和常见宏
Cocos2dx之为什么会有自动内存池(cocos2dx 定时器)
对Cocos2dX的内存管理不了解的人会有这样的疑惑,Cocos2dX的自动内存池是干什么的?当调用一个对象的autorelease后,该对象就被加入到自动内存池中。那是否意味着我们可以不用再去对该对象进行retain,release了呢?
答案是错的。自动内存池只作用于那些”创建期“的对象,也就是说对于那些用create函数创建出来的对象,实际上是调用了autorelease,而autorelease会把该对象加入到自动内存池中,而在用create函数创建了对象后的那一帧,当前自动内存池中的所有对象都会被release一次,然后清空该自动内存池。下面是分析过程:
一.create函数的内幕
使用create函数创建对象实际上会调用autorelease,而autorelease又会将该对象加入到当前自动内存池中:
#define CREATE_FUNC(__TYPE__) \ static __TYPE__* create() \ { \ __TYPE__ *pRet = new(std::nothrow) __TYPE__(); \ if (pRet && pRet->init()) \ { \ pRet->autorelease(); \ return pRet; \ } \ else \ { \ delete pRet; \ pRet = NULL; \ return NULL; \ } \ }
Ref* Ref::autorelease() { PoolManager::getInstance()->getCurrentPool()->addobject(this); return this; }
二.为什么会有自动内存池
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdshow) { UNREFERENCED_ParaMETER(hPrevInstance); UNREFERENCED_ParaMETER(lpCmdLine); // create the application instance AppDelegate app; return Application::getInstance()->run(); }
int Application::run() { PVRFrameEnableControlWindow(false); // Main message loop: LARGE_INTEGER nLast; LARGE_INTEGER nNow; QueryPerformanceCounter(&nLast); initGLContextAttrs(); // Initialize instance and cocos2d. if (!applicationDidFinishLaunching()) { return 1; } auto director = Director::getInstance(); auto glview = director->getopenGLView(); // Retain glview to avoid glview being released in the while loop glview->retain(); while(!glview->windowShouldClose()) { QueryPerformanceCounter(&nNow); if (nNow.QuadPart - nLast.QuadPart > _animationInterval.QuadPart) { nLast.QuadPart = nNow.QuadPart - (nNow.QuadPart % _animationInterval.QuadPart); director->mainLoop(); glview->pollEvents(); } else { Sleep(1); } } // Director should still do a cleanup if the window was closed manually. if (glview->isOpenglready()) { director->end(); director->mainLoop(); director = nullptr; } glview->release(); return 0; }
run函数中有这么一句,director->mainLoop(),跟踪进去:
void displayLinkDirector::mainLoop() { if (_purgeDirectorInNextLoop) { _purgeDirectorInNextLoop = false; purgeDirector(); } else if (_restartDirectorInNextLoop) { _restartDirectorInNextLoop = false; restartDirector(); } else if (! _invalid) { drawScene(); // release the objects PoolManager::getInstance()->getCurrentPool()->clear(); } }
void AutoreleasePool::clear() { #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = true; #endif std::vector<Ref*> releasings; releasings.swap(_managedobjectArray); for (const auto &obj : releasings) { obj->release(); } #if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0) _isClearing = false; #endif }
调用releasings.swap(_managedobjectArray)后当前自动内存池中就被清空了。
for (const auto &obj : releasings) { obj->release(); }创建一个对象时,该对象的引用计数被初始化为1,如果我们没有对该对象进行retain操作,或者没有使用它(也就是没有其它对象引用它),那么该对象的引用计数则为1,调用上面的代码后,该对象的引用计数变为0,之后便不复存在。
结论:
关于cocos2dx接Android sdk的一些坑
简单说说UI线程 :在Android中,有个非常重要的家伙非常霸道,那就是UI线程。这霸道之一:不能被阻塞。 之二:系统对每一个组件的调用都从UI线程分发出去。
简单说说openGL线程:但凡cocos2dx 启动的绘制线程都是openGL线程。就这么多
任何SDK界面的调用,必须从UI线程中调用,所以需要放到主线程中。如果我们直接从GL线程中调用,轻则调用不了,重者程序蹦死。
解决办法:
得到主线程的handler,这里简单说一种,就是在onCreate中new一个静态handler。
或者new Handler(Looper.getMainLooper()),且叫mainHandler吧,
启动一个线程,
- ThreadsendThread=newThread(newRunnable(){
- publicvoidrun(){
- mainHandler.post(sendRun);
- }
- });
Bullet(Cocos2dx)之交叉编译Android,集成到cocos2dx3.x
首先将src文件夹复制到jni文件夹,没有可以新建一个
新建两个文件Android.mk,Application.mk
Application.mk内容如下:
APP_ABI:=armeabiarmeabi-v7ax86
APP_PLATFORM:=android-8
APP_STL:=stlport_static
Android.mk内容如下:
LOCAL_PATH:=$(callmy-dir)
include$(CLEAR_VARS)
LOCAL_MODULE :=bullet_static(可随便起)
LOCAL_MODULE_FILENAME:=libbullet(可随便起)
LOCAL_C_INCLUDES:=src/(头文件位置)
(源文件,要列出所有用到的,这里用到BulletSoftBodyBulletDynamics
BulletCollisionsLinearMath)
LOCAL_SRC_FILES := src/BulletSoftBody/btSoftBody.cpp\ src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp \ src/BulletSoftBody/btSoftBodyHelpers.cpp \ src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp \ src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp \ src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp \ src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp \ src/BulletSoftBody/btDefaultSoftBodySolver.cpp \ src/BulletDynamics/Character/btKinematicCharacterController.cpp \ src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp \ src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp \ src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp \ src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp \ src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp \ src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp \ src/BulletDynamics/Dynamics/btdiscreteDynamicsWorld.cpp \ src/BulletDynamics/Dynamics/btRigidBody.cpp \ src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp \ src/BulletDynamics/Vehicle/btRaycastVehicle.cpp \ src/BulletDynamics/Vehicle/btWheelInfo.cpp \ src/BulletDynamics/Featherstone/btMultiBody.cpp \ src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp \ src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp \ src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp \ src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp \ src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp \ src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp \ src/BulletDynamics/MLcpsolvers/btDantzigLCP.cpp \ src/BulletDynamics/MLcpsolvers/btMLcpsolver.cpp \ src/BulletDynamics/MLcpsolvers/btLemkeAlgorithm.cpp \ src/BulletCollision/broadphaseCollision/btAxisSweep3.cpp \ src/BulletCollision/broadphaseCollision/btbroadphaseProxy.cpp \ src/BulletCollision/broadphaseCollision/btCollisionAlgorithm.cpp \ src/BulletCollision/broadphaseCollision/btDbvt.cpp \ src/BulletCollision/broadphaseCollision/btDbvtbroadphase.cpp \ src/BulletCollision/broadphaseCollision/btdispatcher.cpp \ src/BulletCollision/broadphaseCollision/btMultiSapbroadphase.cpp \ src/BulletCollision/broadphaseCollision/btOverlappingPairCache.cpp \ src/BulletCollision/broadphaseCollision/btQuantizedBvh.cpp \ src/BulletCollision/broadphaseCollision/btSimplebroadphase.cpp \ src/BulletCollision/Collisiondispatch/btActivatingCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btBoxBoxCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btBox2dBox2dCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btBoxBoxDetector.cpp \ src/BulletCollision/Collisiondispatch/btCollisiondispatcher.cpp \ src/BulletCollision/Collisiondispatch/btCollisionObject.cpp \ src/BulletCollision/Collisiondispatch/btCollisionWorld.cpp \ src/BulletCollision/Collisiondispatch/btCollisionWorldImporter.cpp \ src/BulletCollision/Collisiondispatch/btCompoundCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btCompoundCompoundCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btConvexConcaveCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btConvexConvexAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btConvexPlaneCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btConvex2dConvex2dAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btDefaultCollisionConfiguration.cpp \ src/BulletCollision/Collisiondispatch/btEmptyCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btGhostObject.cpp \ src/BulletCollision/Collisiondispatch/btHashedSimplePairCache.cpp \ src/BulletCollision/Collisiondispatch/btInternalEdgeUtility.cpp \ src/BulletCollision/Collisiondispatch/btManifoldResult.cpp \ src/BulletCollision/Collisiondispatch/btSimulationIslandManager.cpp \ src/BulletCollision/Collisiondispatch/btSphereBoxCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btSphereSphereCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btSphereTriangleCollisionAlgorithm.cpp \ src/BulletCollision/Collisiondispatch/btUnionFind.cpp \ src/BulletCollision/Collisiondispatch/SphereTriangleDetector.cpp \ src/BulletCollision/CollisionShapes/btBoxShape.cpp \ src/BulletCollision/CollisionShapes/btBox2dShape.cpp \ src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp \ src/BulletCollision/CollisionShapes/btCapsuleShape.cpp \ src/BulletCollision/CollisionShapes/btCollisionShape.cpp \ src/BulletCollision/CollisionShapes/btCompoundShape.cpp \ src/BulletCollision/CollisionShapes/btConcaveShape.cpp \ src/BulletCollision/CollisionShapes/btConeshape.cpp \ src/BulletCollision/CollisionShapes/btConvexHullShape.cpp \ src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp \ src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp \ src/BulletCollision/CollisionShapes/btConvexpolyhedron.cpp \ src/BulletCollision/CollisionShapes/btConvexShape.cpp \ src/BulletCollision/CollisionShapes/btConvex2dShape.cpp \ src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp \ src/BulletCollision/CollisionShapes/btCylinderShape.cpp \ src/BulletCollision/CollisionShapes/btEmptyShape.cpp \ src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp \ src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp \ src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp \ src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp \ src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp \ src/BulletCollision/CollisionShapes/btpolyhedralConvexShape.cpp \ src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp \ src/BulletCollision/CollisionShapes/btShapeHull.cpp \ src/BulletCollision/CollisionShapes/btSphereShape.cpp \ src/BulletCollision/CollisionShapes/btStaticPlaneshape.cpp \ src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp \ src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp \ src/BulletCollision/CollisionShapes/btTriangleBuffer.cpp \ src/BulletCollision/CollisionShapes/btTriangleCallback.cpp \ src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp \ src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp \ src/BulletCollision/CollisionShapes/btTriangleMesh.cpp \ src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp \ src/BulletCollision/CollisionShapes/btUniformScalingShape.cpp \ src/BulletCollision/Gimpact/btContactProcessing.cpp \ src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp \ src/BulletCollision/Gimpact/btGImpactBvh.cpp \ src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp \ src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp \ src/BulletCollision/Gimpact/btGImpactShape.cpp \ src/BulletCollision/Gimpact/btTriangleShapeEx.cpp \ src/BulletCollision/Gimpact/gim_Box_set.cpp \ src/BulletCollision/Gimpact/gim_contact.cpp \ src/BulletCollision/Gimpact/gim_memory.cpp \ src/BulletCollision/Gimpact/gim_tri_collision.cpp \ src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp \ src/BulletCollision/NarrowPhaseCollision/btConvexCast.cpp \ src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp \ src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp \ src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp \ src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp \ src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp \ src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp \ src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp \ src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp \ src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp \ src/BulletCollision/NarrowPhaseCollision/btpolyhedralContactClipping.cpp \ src/LinearMath/btAlignedAllocator.cpp \ src/LinearMath/btConvexHull.cpp \ src/LinearMath/btConvexHullComputer.cpp \ src/LinearMath/btGeometryUtil.cpp \ src/LinearMath/btPolarDecomposition.cpp \ src/LinearMath/btQuickprof.cpp \ src/LinearMath/btSerializer.cpp \ src/LinearMath/btVector3.cpp
最后还要加上一句,表示生成静态库如果将STATIC该文SHARED则生成动态库
include$(BUILD_STATIC_LIBRARY)
然后进入命令行
进入jni所在目录
ndk-build
等待编译完成
将三个目录下的libbullet.a分别复制到cocos2dx的安装目录下的
安装目录\Cocos\frameworks\cocos2d-x\prebuilt\android\相应文件下
进入Cocos\frameworks\cocos2d-x\external
新建文件夹Bullet,在Bullet下新建prebuild-mk
将Box2D\prebuild-mk下的Android.mk复制到Bullet/prebuild-mk
修改如下3行
LOCAL_MODULE:=bullet_static
LOCAL_MODULE_FILENAME:=libbullet
LOCAL_SRC_FILES:=../../../prebuilt/android/$(TARGET_ARCH_ABI)/libbullet.a
复制头文件
将bullet3的src的所有文件复制到新建的Bullet文件下
删除不是.h的所有文件
下一步任务繁重,
将所有用到BulletCollisionBulletDynamicsBulletSoftBodyLinearMath目录下的include都加上Bullet/,可以使用Notepad++在Bullet目录搜索Bullet,并替换为Bullet/Bullet,LinearMath并替换为Bullet/LinearMath
进入Cocos\frameworks\cocos2d-x\cocos\prebuilt-mk
在Android.mk
在LOCAL_WHOLE_STATIC_LIBRARIES+=Box2d_static下面添加
LOCAL_WHOLE_STATIC_LIBRARIES+=bullet_static
$(callimport-module,Box2D/prebuilt-mk)下面添加
$(callimport-module,Bullet/prebuilt-mk)
至此已经完成编译静态库
下载地址
Cocos2d-X 学习笔记 15 cocos2dx之CCUserDefault及其数据进行加密解密
CCUserDefault是Cocos2d-x引擎提供的持久化方案,其作用是存储所有游戏通用的用户配置信息,例如音乐和音效配置等。为了方便起见,有时我们也可以用CCUserDefault来存储金币数目这种简单的数据项。 CCUserDefault可以看做一个永久存储的字典,本质是一个XML文件,将每个键及其对应的值以节点的形式存储到外存中。值只支持int和float等基本类型.
- CCUserDefault::sharedUserDefault()->setBoolForKey("exit",true);
- panstyle="color:#ff0000;">CCUserDefault::sharedUserDefault()->flush();</span>//这行一定要加上,不然下次启动游戏的时候,该数据就没有保存。
- boolbexit=CCUserDefault::sharedUserDefault()->getBoolForKey("exit");
这里要注意, CCUserDefault中有个 flush()的函数,这个用来将数据写入xml文件中,也就是说当你使用setXX的一些函数后记得提交(调用一下flush函数)
XML的一个很严重的问题是明文存储,存储在外部的数据一旦被截获,就将直接暴露在攻击者面前,小则篡改用户数据,大则泄露用户隐私信息。因此,对存储在文件中的信息加密不可忽视。
幸运的是,前面我们已经设计好了序列化和反序列化过程,只要在其中加入合适的加密和解密算法,即可保证我们的数据不会被轻易窃取。这里我们只使用一个简单的编码轮换来加密,相关代码如下:
Cocos2d-X 学习笔记 19 cocos2d-x学习之自动内存管理和常见宏
我们已经知道,调用了autorelease()方法的对象(下面简称"autorelease对象"),将会在自动回收池释放的时候被释放一次。虽然,Cocos2d-x已经保证每一帧结束后释放一次回收池,并在下一帧开始前创建一个新的回收池,但是我们也应该考虑到回收池本身维护着一个将要执行释放操作的对象列表,如果在一帧之内生成了大量的autorelease对象,将会导致回收池性能下降。因此,在生成autorelease对象密集的区域(通常是循环中)的前后,我们最好可以手动创建并释放一个回收池。
我们可以通过回收池管理器CCPoolManager的push()或pop()方法来创建或释放回收池,其中的CCPoolManager也是一个单例对象。在这里,我们通过这段简单的代码来分析自动回收池的嵌套机制:
CCPoolManager::sharedPoolManager()->push();
for(int i=0; i<n; i++)
{
CCString* dataItem = CCString::createWithFormat("%d",Data[i]);
stringArray->addobject(dataItem);
}
CCPoolManager::sharedPoolManager()->pop();
其实我们在游戏开发中 注意一些内存的管理,对游戏有很大的帮助!一点一点积攒起来!就会对游戏内存吃紧的问题!有本质的解决! 1,如场景切换 在内存吃紧的情况下 我们可以选择 先清理一下缓存! // 清空缓存 CCDirector::sharedDirector()->purgeCachedData(); 2,场景切换也有注意的地方!场景切换 有压入式加入!替换式加入! 这里说一下压入场景(pushScene)和弹出场景(popScene)。它们都可以用来显示场景 和保留当前场景并显示新场景 ;不同的是它们不把旧场景从内存中释放掉,这样可以提高加 载速度,这时需要注意,如果内存不足以支撑的话,建议采用replaceScene 函数。 以上过程分为以下三步: 1)调用 CCDirector::sharedDirector()->purgeCachedData() 清空缓存。 2)新建场景。 3)调用 CCDirector::sharedDirector()->replaceScene(this) 替换新场景。Cocos2D-x 提供了 场景间切换的特效,下一节将会介绍这些内容。
关于Cocos2dx之为什么会有自动内存池和cocos2dx 定时器的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于
本文标签: