GVKun编程网logo

cocos2dx 简介(cocos2d cocos2dx)

29

对于想了解cocos2dx简介的读者,本文将是一篇不可错过的文章,我们将详细介绍cocos2dcocos2dx,并且为您提供关于关于cocos2dx接Androidsdk的一些坑、Bullet(Coc

对于想了解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 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 随记> 关于cocos2dx接Android sdk的一些坑

关于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

Bullet(Cocos2dx)之交叉编译Android,集成到cocos2dx3.x

首先将src文件夹复制到jni文件夹,没有可以新建一个

新建两个文件Android.mkApplication.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


复制头文件

bullet3src的所有文件复制到新建的Bullet文件下


删除不是.h的所有文件

下一步任务繁重,

将所有用到BulletCollisionBulletDynamicsBulletSoftBodyLinearMath目录下的include都加上Bullet/,可以使用Notepad++Bullet目录搜索Bullet,并替换为Bullet/BulletLinearMath并替换为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教程(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

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){

void Eventdispatcher::dispatchTouchEvent(EventTouch* 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的讲解已经结束,谢谢您的阅读,如果想了解更多关于 关于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的相关知识,请在本站搜索。

本文标签: