对于想了解cocos2dx简介的读者,本文将是一篇不可错过的文章,我们将详细介绍cocos2dcocos2dx,并且为您提供关于关于cocos2dx接Androidsdk的一些坑、Bullet(Coc
对于想了解cocos2dx 简介的读者,本文将是一篇不可错过的文章,我们将详细介绍cocos2d cocos2dx,并且为您提供关于
- cocos2dx 简介(cocos2d cocos2dx)
关于cocos2dx接Android sdk的一些坑 - Bullet(Cocos2dx)之交叉编译Android,集成到cocos2dx3.x
- Cocos2d-x教程(19)-cocos2d-x.xcodeproj-2.2.x版本对cocos2dx文件的引用以及Cocos2d-x 2.2.0版本后项目拷贝出来无法运行的原因
- cocos2dx 3.x 自学笔记 <二> cocos2dx 中注册触摸事件touchEvent 2.x 与 3.x
cocos2dx 简介(cocos2d cocos2dx)
学习笔记用 -------------------
简介
cocos2dx是一款跨平台的游戏开发引擎,它的前身是cocos2d iphone,主要用于苹果平台手机游戏的开发,基于oc语言完成,没有跨平台特性,但是使用此框架的开发者非常多,后面推出的cocos2dx版本就是基于cocos2d iphone风格开发,2.x版本完全MFC风格.比如到处的CCxxxx风格,3.x版本转成C++0x11风格,具有跨Android,iPhone,win平台的特性,且支持lua,js脚本语言的嵌入,做到了性能和方便的结合。
cocos2d版本在中国发展壮大,其中主要由触控科技公司更新维护,cocos中又产生了cocos2dx,cocos_lua,cocos_js,后面两个版本采用脚本语言开发,对于跨平台和热更新支持的更为广泛。
cocos2dx也经历了众多版本的变更,从1.0到现在的3.9,功能越来越强大,配套的开发工具越来越多,包括:
a,cocos2dx粒子编辑器mac环境下推荐使用Particle designer,
win系统推荐使用软件ParticleEditor.
b.场景编辑工具
cocos studio
cocos builder
c. 物理编辑工具
PHPsicsEditor
d. 纹理编辑工具
TexturePacker
cocos studio 2.0+
e,瓦片地图编辑工具
Tiled Map Editor
f,位图字体工具
BMFont
g,声音特效编辑工具
cfxr
h,背景音乐编辑工具
GarageBand
采用cocos引擎开发的手机游戏越来越多,目前cocos2d-x引擎在国内手机游戏开发使用的份额接近70%,而国外使用份额则是接近25%,在苹果APP排行榜top10理面,有7个都是用cocos2d-x引擎开发的。
关于cocos2dx接Android sdk的一些坑
简单说说UI线程 :在Android中,有个非常重要的家伙非常霸道,那就是UI线程。这霸道之一:不能被阻塞。 之二:系统对每一个组件的调用都从UI线程分发出去。
简单说说openGL线程:但凡cocos2dx 启动的绘制线程都是openGL线程。就这么多
任何SDK界面的调用,必须从UI线程中调用,所以需要放到主线程中。如果我们直接从GL线程中调用,轻则调用不了,重者程序蹦死。
解决办法:
得到主线程的handler,这里简单说一种,就是在onCreate中new一个静态handler。
或者new Handler(Looper.getMainLooper()),且叫mainHandler吧,
启动一个线程,
Thread sendThread=new Thread(new Runnable(){ public void run() { mainHandler.post(sendRun); } });
public Runnable sendRun=new Runnable() { @Override public void run() { // //这里就可以调用sdk里面的东西了
} };
</pre><pre name="code"><span>如何从UI线程中调用OpenGL线程呢,直接调用,我以前也干过,感觉没什么问题被发现(he he),如果发现了问题我觉得还是这么调用的好</span>
</pre><pre name="code">Cocos2dxGLSurfaceView.getInstance().queueEvent(new Runnable() { public void run() { <span> </span>//回调什么马的 } });至于想知道,jni native什么的 还请出门右拐,不送
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教程(19)-cocos2d-x.xcodeproj-2.2.x版本对cocos2dx文件的引用以及Cocos2d-x 2.2.0版本后项目拷贝出来无法运行的原因
欢迎加入 Cocos2d-x 交流群:193411763
转载时请注明原文地址:http://blog.csdn.net/u012945598/article/details/17954549
今天在使用Cocos2d-x 2.2.1版本中的"curl.h"头文件时遇到了一个问题
提示文件没有找到。
之后笔者对比了一下Cocos2d-x 2.1.5版本,发现在2.1.5的版本中cocos2dx文件(curl文件夹位于cocos2dx文件夹目录下)是以groups(黄色文件夹)的形式存在于项目中的,而在2.2.x版本中采用了新的引入方式,也就是我们所见到的cocos2d-x.xcodeproj
(不理解groups形式请参考http://blog.csdn.net/u012945598/article/details/17955215)
2.1.5版本:
2.2.x版本:
这也就解释了,为什么在2.2.0之后的版本中,如果将你的项目拷贝到了别的电脑上,项目将无法运行的原因。
因为2.2.0之后的版本中,cocos2dx文件夹不再存在于项目的目录下了,而是位于你的系统中的某个位置(下载完之后扔哪了就是哪),当编译器对cocos2dx文件做路径搜索时,会按照创建项目的机器中的cocos2dx文件的路径去搜索,而在另外一台电脑中,路径是不一样的,所以自然会找不到。搜索路径如下图:
我们常用的解决办法就是新建一个项目,将之前项目的Classes文件夹与Resources文件夹拷贝出来,再重新添加到项目中。
从形式上来说,在2.1.5版本中的cocos2dx的文件夹的作用与2.2.x版本中的cocos2dx.xcodeproj的作用是相同的,因为他们都是对cocos2d-x文件夹目录下的cocos2dx文件中的源码的引用。但是在使用过程中,又略有一些区别。
由于在2.1.5的版本中cocos2dx文件是以groups的形式被添加到项目中的,所以在使用的时候,我们可以没有任何顾忌的引用文件中的任何头文件 #include "xxx.h",原因我们在之前的参考文章中已经提过,是因为以groups形式添加到项目中的文件都是会被编译的。
编译的资源文件位置位于Compile Sources如下图:
然而还有一部分文件仍然是以引用的方式存在于项目中,类似于 curl.h,这些文件在使用的过程中并不能直接通过#include "xxx.h"方式获取到它们的头文件,而是要通过其上级目录索引到,例如我们要使用curl文件夹中curl.h的头文件:
#include "curl/curl.h"
又或者我们需要使用到platform中的CCThread类,需要引入头文件
#include "platform/CCThread"
若不加上级目录,就会出现文章开篇中的错误,这就是Cocos2d-x-2.1.5版本与2.2.x版本中cocos2dx中源码使用的区别
cocos2dx 3.x 自学笔记 <二> cocos2dx 中注册触摸事件touchEvent 2.x 与 3.x
cocos2.2.5还在编译依赖库,还是先看3.2的吧
环境:win8 +vs2013
时间有限还是先说说这个把
#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MInor__ >= 1))) #define CC_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) #elif _MSC_VER >= 1400 //vs 2005 or higher #define CC_DEPRECATED_ATTRIBUTE __declspec(deprecated) #else #define CC_DEPRECATED_ATTRIBUTE #endif看不懂也没关系,主要是提醒大家但凡函数加了
CC_DEPRECATED_ATTRIBUTE表示废弃了的意思,也只能在3.x中才能看到,想跟下去看看怎么实现,水平有限,跟不了。谁知道告诉我一声,先谢了。
但是有些函数没有加这个修饰,但是在编译的过程中也提示废弃,以后再深入研究。
CC_DEPRECATED_ATTRIBUTE virtual bool ccTouchBegan(Touch *pTouch,Event *pEvent) final {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent); return false;}; CC_DEPRECATED_ATTRIBUTE virtual void ccTouchMoved(Touch *pTouch,Event *pEvent) final {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent);} CC_DEPRECATED_ATTRIBUTE virtual void ccTouchEnded(Touch *pTouch,Event *pEvent) final {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent);} CC_DEPRECATED_ATTRIBUTE virtual void ccTouchCancelled(Touch *pTouch,Event *pEvent) final {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent);} CC_DEPRECATED_ATTRIBUTE virtual void cctouchesBegan(__Set *ptouches,Event *pEvent) final {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);} CC_DEPRECATED_ATTRIBUTE virtual void cctouchesMoved(__Set *ptouches,Event *pEvent) final {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);} CC_DEPRECATED_ATTRIBUTE virtual void cctouchesEnded(__Set *ptouches,Event *pEvent) final {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);} CC_DEPRECATED_ATTRIBUTE virtual void cctouchesCancelled(__Set *ptouches,Event *pEvent) final {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);}被废弃了,为什么被废弃了(还是可以用吧),下面会讲的
virtual bool onTouchBegan(Touch *touch,Event *unused_event); virtual void onTouchMoved(Touch *touch,Event *unused_event); virtual void onTouchEnded(Touch *touch,Event *unused_event); virtual void onTouchCancelled(Touch *touch,Event *unused_event); virtual void ontouchesBegan(const std::vector<Touch*>& touches,Event *unused_event); virtual void ontouchesMoved(const std::vector<Touch*>& touches,Event *unused_event); virtual void ontouchesEnded(const std::vector<Touch*>& touches,Event *unused_event); virtual void ontouchesCancelled(const std::vector<Touch*>&touches,Event *unused_event);
注册监听:
auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(MainLayer::onTouchBegan,this); listener->onTouchEnded = CC_CALLBACK_2(MainLayer::onTouchEnded,this); listener->onTouchMoved = CC_CALLBACK_2(MainLayer::onTouchMove,this);//其实这里也可以用lambda去写 listener->onTouchMoved = [](const std::vector<Touch*>&touches,Event *unused_event)->bool{ /* 函数体*/} _eventdispatcher->addEventListenerWithSceneGraPHPriority(listener,this);//默认优先级0 ,创建listener对象,根据listenerID映射listeners容器,将listener对象存入容器中
void Eventdispatcher::addEventListener(EventListener* listener) { if (_indispatch == 0) { forceAddEventListener(listener); } else { _toAddedListeners.push_back(listener); } listener->retain(); }
之后,在_nodeListenersMap中建立node(target)与关联的listener的映射
void Eventdispatcher::associateNodeAndEventListener(Node* node,EventListener* listener) { std::vector<EventListener*>* listeners = nullptr; auto found = _nodeListenersMap.find(node); if (found != _nodeListenersMap.end()) { listeners = found->second; } else { listeners = new std::vector<EventListener*>(); _nodeListenersMap.insert(std::make_pair(node,listeners)); } listeners->push_back(listener); }
另一个种
_eventdispatcher->addEventListenerWithFixedPriority(listener,Priority);// 我这里发现了个问题 void Eventdispatcher::addEventListenerWithFixedPriority(EventListener* listener,int fixedPriority) { CCASSERT(listener,"Invalid parameters."); CCASSERT(!listener->isRegistered(),"The listener has been registered."); CCASSERT(fixedPriority != 0,"0 priority is forbidden for fixed priority since it's used for scene graph based priority."); if (!listener->checkAvailable()) return; listener->setAssociatednode(nullptr); listener->setFixedPriority(fixedPriority); listener->setRegistered(true); listener->setPaused(false); addEventListener(listener); }//我 TM的超级郁闷 ,设置非0吧,assert了,设置〇吧,没有node ,甭的更厉害 //无奈之下注释了第三行,OK了 唉只能说 被白fuck了一个小时,还能说了什么呢此不绑定target,所以需要手动释放
_eventdispatcher->removeEventListener(listener),此处没有根据nonde
第三
_eventdispatcher->addCustomEventListener("custom",[](EventCustom*)->void{ log("a event");}); EventListenerCustom* Eventdispatcher::addCustomEventListener(const std::string &eventName,const std::function<void(EventCustom*)>& callback) { EventListenerCustom *listener = EventListenerCustom::create(eventName,callback);//在这里创建listener addEventListenerWithFixedPriority(listener,1); return listener; }测试了下,编译过了,但是点击没有反应,知道这个意思就好了以后在看了
现在看看事件分发:
glview->pollEvents();
。。。。。。//物理事件传递
class GLFWEventHandler { public: static void onGLFWError(int errorID,const char* errorDesc) { if (_view) _view->onGLFWError(errorID,errorDesc); } static void onGLFWMouseCallBack(GLFWwindow* window,int button,int action,int modify) { if (_view) _view->onGLFWMouseCallBack(window,button,action,modify); } static void onGLFWMouseMoveCallBack(GLFWwindow* window,double x,double y) { if (_view) _view->onGLFWMouseMoveCallBack(window,x,y); } static void onGLFWMouseScrollCallback(GLFWwindow* window,double y) { if (_view) _view->onGLFWMouseScrollCallback(window,y); } static void onGLFWKeyCallback(GLFWwindow* window,int key,int scancode,int mods) { if (_view) _view->onGLFWKeyCallback(window,key,scancode,mods); } static void onGLFWCharCallback(GLFWwindow* window,unsigned int character) { if (_view) _view->onGLFWCharCallback(window,character); } static void onGLFWWindowPosCallback(GLFWwindow* windows,int x,int y) { if (_view) _view->onGLFWWindowPosCallback(windows,y); } static void onGLFWframebuffersize(GLFWwindow* window,int w,int h) { if (_view) _view->onGLFWframebuffersize(window,w,h); } static void onGLFWWindowSizefunCallback(GLFWwindow *window,int width,int height) { if (_view) _view->onGLFWWindowSizefunCallback(window,width,height); } static void setGLView(GLView* view) { _view = view; } private: static GLView* _view; };我是用鼠标点的响应了鼠标的那个函数调用,根据鼠标事件调用了
void GLViewProtocol::handletouchesEnd(int num,intptr_t ids[],float xs[],float ys[]) { handletouchesOfEndOrCancel(EventTouch::EventCode::ENDED,num,ids,xs,ys); }接下来才到我们之前注册的事件TouchEvent
void Eventdispatcher::dispatchEvent(Event* event){
这里面干的是
对事件排序,按优先级。
auto oneByOneListeners = getListeners(EventListenerTouchOneByOne::LISTENER_ID); auto allAtOnceListeners = getListeners(EventListenerTouchAllAtOnce::LISTENER_ID);
得到各个TouchMode的Listeners:
auto oneByOneListeners = getListeners(EventListenerTouchOneByOne::LISTENER_ID); auto allAtOnceListeners = getListeners(EventListenerTouchAllAtOnce::LISTENER_ID);就是各种超找匹配找出是否有注册的Event:
if (oneByOneListeners) { auto mutabletouchesIter = mutabletouches.begin(); auto touchesIter = originaltouches.begin(); for (; touchesIter != originaltouches.end(); ++touchesIter) { bool isSwallowed = false; auto onTouchEvent = [&](EventListener* l) -> bool { // Return true to break EventListenerTouchOneByOne* listener = static_cast<EventListenerTouchOneByOne*>(l); // Skip if the listener was removed. if (!listener->_isRegistered) return false; event->setCurrentTarget(listener->_node); bool isClaimed = false; std::vector<Touch*>::iterator removedIter; EventTouch::EventCode eventCode = event->getEventCode(); if (eventCode == EventTouch::EventCode::BEGAN) { if (listener->onTouchBegan) { isClaimed = listener->onTouchBegan(*touchesIter,event); if (isClaimed && listener->_isRegistered) { listener->_claimedtouches.push_back(*touchesIter); } } } else if (listener->_claimedtouches.size() > 0 && ((removedIter = std::find(listener->_claimedtouches.begin(),listener->_claimedtouches.end(),*touchesIter)) != listener->_claimedtouches.end())) { isClaimed = true; switch (eventCode) { case EventTouch::EventCode::MOVED: if (listener->onTouchMoved) { listener->onTouchMoved(*touchesIter,event); } break; case EventTouch::EventCode::ENDED: if (listener->onTouchEnded) { listener->onTouchEnded(*touchesIter,event); } if (listener->_isRegistered) { listener->_claimedtouches.erase(removedIter); } break; case EventTouch::EventCode::CANCELLED: if (listener->onTouchCancelled) { listener->onTouchCancelled(*touchesIter,event); } if (listener->_isRegistered) { listener->_claimedtouches.erase(removedIter); } break; default: CCASSERT(false,"The eventcode is invalid."); break; } } // If the event was stopped,return directly. if (event->isstopped()) { updateListeners(event); return true; } CCASSERT((*touchesIter)->getID() == (*mutabletouchesIter)->getID(),""); if (isClaimed && listener->_isRegistered && listener->_needSwallow) { if (isNeedsMutableSet) { mutabletouchesIter = mutabletouches.erase(mutabletouchesIter); isSwallowed = true; } return true; } return false; }; // dispatchEventToListeners(oneByOneListeners,onTouchEvent);//主要在这里 这里用了lambda,执行循序要搞清楚了 if (event->isstopped()) { return; } if (!isSwallowed) ++mutabletouchesIter; } }
void Eventdispatcher::dispatchEventToListeners(EventListenerVector* listeners,const std::function<bool(EventListener*)>& onEvent)这个函数告诉我们了若匹配到了不想下分发了
然后进入那个lambda函数里执行注册过的touch系列函数了。执行完了还会在下一个循环删除这一事件
现在讲讲ccs 2.2.x ,一直在发布新版本,ccs现在完善了不少,我们就拿最新的来将好了,ccs 3.0x之前的版本大家都熟悉了,不熟悉,网上教程一大把,我这里略微补充下
类:CCTouchdispatcher
void CCTouchdispatcher::addStandardDelegate(CCTouchDelegate *pDelegate,int nPriority) { CCTouchHandler *pHandler = CCStandardTouchHandler::handlerWithDelegate(pDelegate,nPriority); if (! m_bLocked) { forceAddHandler(pHandler,m_pStandardHandlers); } else { /* If pHandler is contained in m_pHandlersToRemove,if so remove it from m_pHandlersToRemove and return. * Refer issue #752(cocos2d-x) */ if (ccCArrayContainsValue(m_pHandlersToRemove,pDelegate)) { ccCArrayRemoveValue(m_pHandlersToRemove,pDelegate); return; } m_pHandlersToAdd->addobject(pHandler); m_bToAdd = true; } }
我们经常重写void cclayer::registerWithTouchdispatcher(),然后调用上面的注册函数,
void cclayer::registerWithTouchdispatcher() { CCTouchdispatcher* pdispatcher = CCDirector::sharedDirector()->getTouchdispatcher(); // Using LuaBindings if (m_pScriptTouchHandlerEntry) { if (m_pScriptTouchHandlerEntry->isMultitouches()) { pdispatcher->addStandardDelegate(this,0); LUALOG("[LUA] Add multi-touches event handler: %d",m_pScriptTouchHandlerEntry->getHandler()); } else { pdispatcher->addTargetedDelegate(this,m_pScriptTouchHandlerEntry->getPriority(),m_pScriptTouchHandlerEntry->getSwallowstouches()); LUALOG("[LUA] Add touch event handler: %d",m_pScriptTouchHandlerEntry->getHandler()); } } else { if( m_etouchMode == kCCtouchesAllAtOnce ) { pdispatcher->addStandardDelegate(this,0); } else { pdispatcher->addTargetedDelegate(this,m_nTouchPriority,true); } } }
从上面代码可以看出如果我们改变m_etouchMode就可以修改注册模式,完成这个使命的函数cclayer::setTouchMode( ... )
但是一定要注意调用的顺序,我们都知道在layer切换的时候先是init(),然后onEnter(),onEnterTransitionDidFinish()
在CCDirect类中有这样的一代码可以看出
m_pRunningScene->onEnter(); m_pRunningScene->onEnterTransitionDidFinish();
我们都知道registerWithTouchdispatch()是在cclayer的onEnter里面调用,我们只需init()或者重写onEnter(){ setTouchMode(...),cclayer::onEnter();},OK!
还有一点:
void CCTouchdispatcher::addStandardDelegate(CCTouchDelegate *pDelegate,pDelegate); return; } m_pHandlersToAdd->addobject(pHandler); m_bToAdd = true; } }从参数类型看,
class CC_DLL CCTouchDelegate { public: CCTouchDelegate() {} virtual ~CCTouchDelegate() { } virtual bool ccTouchBegan(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent); return false;}; // optional virtual void ccTouchMoved(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent);} virtual void ccTouchEnded(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent);} virtual void ccTouchCancelled(CCTouch *pTouch,CCEvent *pEvent) {CC_UNUSED_ParaM(pTouch); CC_UNUSED_ParaM(pEvent);} // optional virtual void cctouchesBegan(CCSet *ptouches,CCEvent *pEvent) {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);} virtual void cctouchesMoved(CCSet *ptouches,CCEvent *pEvent) {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);} virtual void cctouchesEnded(CCSet *ptouches,CCEvent *pEvent) {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);} virtual void cctouchesCancelled(CCSet *ptouches,CCEvent *pEvent) {CC_UNUSED_ParaM(ptouches); CC_UNUSED_ParaM(pEvent);} };我们已经知道他们想干什么事情了。
protected: CCArray* m_pTargetedHandlers; CCArray* m_pStandardHandlers; bool m_bLocked; ... CCArray* m_pHandlersToAdd; struct _ccCArray *m_pHandlersToRemove; ...
从CCTouchdispatcher的数据结构来看,主要是两个容器CCArray* m_pTargetedHandlers; CCArray* m_pStandardHandlers;m_bLocked
m_pHandlersToAdd;m_pHandlersToRemove主要是同步安全机制
注册好了就是分发了,主要算法都在 CCTouchdispatcher::touches(cocos2d::CCSet * ptouches,cocos2d::CCEvent * pEvent,unsigned int uIndex) ,分类处理
switch (sHelper.m_type) { case CCTOUCHBEGAN: pHandler->getDelegate()->cctouchesBegan(pMutabletouches,pEvent); break; case CCTOUCHMOVED: pHandler->getDelegate()->cctouchesMoved(pMutabletouches,pEvent); break; case CCTOUCHENDED: pHandler->getDelegate()->cctouchesEnded(pMutabletouches,pEvent); break; case CCTOUCHCANCELLED: pHandler->getDelegate()->cctouchesCancelled(pMutabletouches,pEvent); break; }暂时就写到这了,若有错误,还请留言指出,谢谢
今天关于cocos2dx 简介和cocos2d cocos2dx的讲解已经结束,谢谢您的阅读,如果想了解更多关于
本文标签: