cocos2d-x 3.0  触摸注册函数下面先来详细的介绍一下。

cocos2d-x 3.0版本的事件分发的机制较之之前的版本进行了修改,把事件处理的逻辑分离出来,并通过不同的事件监听器来监听不同的事件。当一个节点收到了事件,就会指派一个事件分发器_eventDispatcher专门来分发这些事件。对于触摸来说,大概的过程就是我们先创建一个对应触摸事件的监听器,然后覆盖触摸事件的函数,并把它们绑定到监听器,然后可以设置一下这个监听器的属性,最后把监听器添加到分发器之中,系统就会自动进行触摸事件的处理。    

我们先看看单点触摸的使用,下面是源代码中关于单点触摸监听器的类,可以看到

这个Unity3D批量修改贴图 导入设置工具脚本十分小巧,但是威力大。特别针对大批量贴图要调整尺寸等等的时候作用尤为明显。

在菜单中添加“Custom→Texture”的方式来批 量改变所选的贴图导入设置。Unity本身只能一次打开一张图片进行导入设置,目前这个脚本可以批量更改贴图格式,是否开启MipMap,调整纹理最大尺 寸,是否可读等等。 

    用法是把脚本放在你项目的资源目录的Editor文件夹下。然后选择你要批处理的纹理。到菜单中选择要处理的类型就可以了。 

    ChangeTextureImportSettings。csforUnity2.x 

程序代码csharp代码:   

  1. using UnityEngine; using UnityEditor;   
  2. // ///////////////////////////////////////////////////////////////////////////////////////////////////////// // 
  3. // Batch Texture import settings modifier. // 
  4. // Modifies all selected textures in the project window and applies the requested modification on the 
  5. // textures. Idea was to have the same choices for multiple files as you would have if you open the // import settings of a single texture. Put this into Assets/Editor and once compiled by Unity you find 
  6. // the new functionality in Custom -> Texture. Enjoy! :-) // 
  7. // Based on the great work of benblo in this thread: // 
  8. http://forum.unity3d.com/viewtopic.php?t=16079&start=0&postdays=0&postorder=asc&highlight=textureimporter // 
  9. // Developed by Martin Schultz, Decane in August 2009 // e-mail: ms@decane.net // 
  10. // ///////////////////////////////////////////////////////////////////////////////////////////////////////// public class ChangeTextureImportSettings : ScriptableObject {   
  11.     [MenuItem ("Custom/Texture/Change Texture Format/Auto")]     static void ChangeTextureFormat_Auto() { 
  12.         SelectedChangeTextureFormatSettings(TextureImporterFormat.Automatic);     }   
  13.     [MenuItem ("Custom/Texture/Change Texture Format/RGB Compressed DXT1")]     static void ChangeTextureFormat_RGB_DXT1() { 
  14.         SelectedChangeTextureFormatSettings(TextureImporterFormat.DXT1);     } 
  15. [MenuItem ("Custom/Texture/Change Texture Format/RGB Compressed DXT5")]     static void ChangeTextureFormat_RGB_DXT5() { 
  16.         SelectedChangeTextureFormatSettings(TextureImporterFormat.DXT5);     }   
  17.     [MenuItem ("Custom/Texture/Change Texture Format/RGB 16 bit")]     static void ChangeTextureFormat_RGB_16bit() { 
  18.         SelectedChangeTextureFormatSettings(TextureImporterFormat.RGB16);     }   
  19.     [MenuItem ("Custom/Texture/Change Texture Format/RGB 24 bit")]     static void ChangeTextureFormat_RGB_24bit() { 
  20.         SelectedChangeTextureFormatSettings(TextureImporterFormat.RGB24);     }   
  21.     [MenuItem ("Custom/Texture/Change Texture Format/Alpha 8 bit")]     static void ChangeTextureFormat_Alpha_8bit() { 
  22.         SelectedChangeTextureFormatSettings(TextureImporterFormat.Alpha8);     }   
  23.     [MenuItem ("Custom/Texture/Change Texture Format/RGBA 16 bit")]     static void ChangeTextureFormat_RGBA_16bit() { 
  24.         SelectedChangeTextureFormatSettings(TextureImporterFormat.ARGB16);     }   
  25.     [MenuItem ("Custom/Texture/Change Texture Format/RGBA 32 bit")]     static void ChangeTextureFormat_RGBA_32bit() { 
  26.         SelectedChangeTextureFormatSettings(TextureImporterFormat.ARGB32);     }   
  27.     // ----------------------------------------------------------------------------   
  28.     [MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/32")]     static void ChangeTextureSize_32() {         SelectedChangeMaxTextureSize(32);     }   
  29.     [MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/64")]     static void ChangeTextureSize_64() {         SelectedChangeMaxTextureSize(64);     }   
  30.     [MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/128")] 
  31. static void ChangeTextureSize_128() {         SelectedChangeMaxTextureSize(128);     }   
  32.     [MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/256")]     static void ChangeTextureSize_256() {         SelectedChangeMaxTextureSize(256);     }   
  33.     [MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/512")]     static void ChangeTextureSize_512() {         SelectedChangeMaxTextureSize(512);     } 
  34.     //Unity3D教程:www.unitymanual.com 
  35.     [MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/1024")]     static void ChangeTextureSize_1024() {         SelectedChangeMaxTextureSize(1024);     }   
  36.     [MenuItem ("Custom/Texture/Change Texture Size/Change Max Texture Size/2048")]     static void ChangeTextureSize_2048() {         SelectedChangeMaxTextureSize(2048);     }   
  37.     // ----------------------------------------------------------------------------   
  38.     [MenuItem ("Custom/Texture/Change MipMap/Enable MipMap")]     static void ChangeMipMap_On() {         SelectedChangeMimMap(true);     }   
  39.     [MenuItem ("Custom/Texture/Change MipMap/Disable MipMap")]     static void ChangeMipMap_Off() {         SelectedChangeMimMap(false);     }   
  40.     // ----------------------------------------------------------------------------   
  41.     static void SelectedChangeMimMap(bool enabled) {   
  42.         Object[] textures = GetSelectedTextures();         Selection.objects = new Object[0]; 
  43.         foreach (Texture2D texture in textures)  { 
  44.             string path = AssetDatabase.GetAssetPath(texture); 



  45.   


  46.             TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; 
  47.             textureImporter.mipmapEnabled = enabled;                 AssetDatabase.ImportAsset(path);         }     } 
  48.     //Unity3D教程手册:www.unitymanual.com 
  49.     static void SelectedChangeMaxTextureSize(int size) {   
  50.         Object[] textures = GetSelectedTextures();         Selection.objects = new Object[0]; 
  51.         foreach (Texture2D texture in textures)  { 
  52.             string path = AssetDatabase.GetAssetPath(texture); 
  53.             TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; 
  54.             textureImporter.maxTextureSize = size;               AssetDatabase.ImportAsset(path);         }     }   
  55.     static void SelectedChangeTextureFormatSettings(TextureImporterFormat newFormat) {   
  56.         Object[] textures = GetSelectedTextures();         Selection.objects = new Object[0]; 
  57.         foreach (Texture2D texture in textures)  { 
  58.             string path = AssetDatabase.GetAssetPath(texture);             //Debug.Log("path: " + path); 
  59.             TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter; 
  60.             textureImporter.textureFormat = newFormat;               AssetDatabase.ImportAsset(path);         }     }   
  61.     static Object[] GetSelectedTextures()     { 
  62.         return Selection.GetFiltered(typeof(Texture2D), SelectionMode.DeepAssets);     } class EventListenerTouchOneByOne: public EventListener  
  63. {  
  64. public:  
  65.     static const std::string LISTENER_ID;  
  66.     static EventListenerTouchOneByOne* create();  
  67.     virtual~EventListenerTouchOneByOne();  
  68.     void setSwallowTouches(bool needSwallow);  
  69.     bool isSwallowTouches();  
  70.     ///Overrides  
  71.     virtual EventListenerTouchOneByOne* clone() override;  
  72.     virtual bool checkAvailable() override;  
  73.     //  
  74. public:  
  75.     std::function<bool(Touch*, Event*)>onTouchBegan;  
  76.     std::function<void(Touch*, Event*)>onTouchMoved;  
  77.     std::function<void(Touch*, Event*)>onTouchEnded;  
  78.     std::function<void(Touch*, Event*)> onTouchCancelled;  
  79. private:  
  80.     EventListener TouchOneByOne();  
  81.     bool init();  
  82.     std::vector<Touch*>_claimedTouches;  
  83.     bool _needSwallow;  
  84.     friend class EventDispatcher;  
  85. };</span>  
这个类看上去比较容易理解,下面我们用代码来演示一下怎么使用。在HelloWorld的init函数中注册监听器并添加到事件分发器中去。

//添加一个测试的精灵  
  1.     autoonion = Sprite::create("onion.png");  
  2.     onion->setPosition(Point(visibleSize.width/2, visibleSize.height/2));  
  3.     onion->setScale(0.2);  
  4.     this->addChild(onion);  
  5.    
  6.     //创建一个触摸监听器,这里使用单点触摸事件  
  7.     autoTouchListenr = EventListenerTouchOneByOne::create();  
  8.     //设置吞噬为true,不让触摸往下传递  
  9.     TouchListenr->setSwallowTouches(true);  
  10.     //和回调函数绑定  
  11.     TouchListenr->onTouchBegan= CC_CALLBACK_2(HelloWorld::onTouchBegan,this);  
  12.     TouchListenr->onTouchMoved= CC_CALLBACK_2(HelloWorld::onTouchMoved,this);  
  13.     TouchListenr->onTouchEnded= CC_CALLBACK_2(HelloWorld::onTouchEnded,this);  
  14.     //添加监听器到事件分发器中  
  15.     _eventDispatcher->addEventListenerWithSceneGraphPriority(TouchListenr,onion);  
  16. 下面我们覆盖单点触摸中提供的触摸函数:

  17. [cpp] view plaincopy
  18. bool HelloWorld::onTouchBegan(Touch* touch, Event* event)  
  19. {  
  20.     //获取精灵对象并取得精灵的矩阵  
  21.     autosprite = static_cast<Sprite*>(event->getCurrentTarget());  
  22.     Rect rect = sprite->getBoundingBox();  
  23.     //获取触摸点的坐标  
  24.     Point point = touch->getLocation();  
  25.     //判断触摸点是否在精灵的矩阵范围内  
  26.     if(rect.containsPoint(point))  
  27.     {  
  28.        return true;  
  29.     }  
  30.     return false;  
  31. }  
  32. void HelloWorld::onTouchMoved(Touch* touch, Event* event)  
  33. {  
  34.     //获取精灵对象  
  35.     autosprite = static_cast<Sprite*>(event->getCurrentTarget());  
  36.     //改变精灵的位置  
  37.     sprite->setPosition(sprite->getPosition()+ touch->getDelta());  
  38. }  
  39. void HelloWorld::onTouchEnded(Touch* touch, Event* event)  
  40. {  
  41.     CCLog("touch end!");  
  42. }  
点击调试运行,可以在屏幕中拉动所测试的精灵,如下图:


在上面的例子中我们看到了,传递过来的参数主要有Touch* touch和Event* event,我们可以进入源代码中查看他们的作用。Touch类是继承了REF,查看源代码中的主要成员如下:

  1. /**returns the current touch location in OpenGL coordinates */  
  2.     Point getLocation() const;  
  3.     /**returns the previous touch location in OpenGL coordinates */  
  4.     Point getPreviousLocation() const;  
  5.     /**returns the start touch location in OpenGL coordinates */  
  6.     Point getStartLocation() const;  
  7.     /**returns the delta of 2 current touches locations in screen coordinates */  
  8.     Point getDelta() const;  
  9.     /**returns the current touch location in screen coordinates */  
  10.     Point getLocationInView() const;  
  11.     /**returns the previous touch location in screen coordinates */  
  12.     Point getPreviousLocationInView() const;  
  13.     /**returns the start touch location in screen coordinates */  
  14.     Point getStartLocationInView() const;  
       也就是Touch传入的是触摸点的坐标位置,并且Touch类为我们提供一些坐标的写法,那么我们就方便很多了。譬如上面例子中的触摸移动时,Touch就为我提供一个getDelta()来计算点的位移。

而对于Event类,主要是传入处理的对象,看源代码有以下主要成员:

  1. /**Gets the event type */  
  2.    inline Type getType() const { return_type; };  
  3.    /**Stops propagation for current event */  
  4.    inline void stopPropagation() { _isStopped = true; };  
  5.     
  6.    /**Checks whether the event has been stopped */  
  7.    inline bool isStopped() const { return_isStopped; };  
  8.     
  9.    /**@brief Gets current target of the event 
  10.     *  @return The target with which the eventassociates. 
  11.     *  @note It onlys be available when the eventlistener is associated with node. 
  12.     *        It returns 0 when the listener isassociated with fixed priority. 
  13.     */  
  14.    inline Node* getCurrentTarget() { return_currentTarget; };  
         那么我们在处理触摸对象的时候和例子那样通过getCurrentTarget()来获取对象并处理即可。

         另一方面,我们在把监听器添加到事件分发器的时候,会看到代码提示两种方法,一个为:addEventListenerWithSceneGraphPriority,另一个为addEventListenerWithFixedPriority。同样可以查看源代码如下:

  1. /**Adds a event listener for a specified event with the priority of scene graph. 
  2.     *  @param listener The listener of a specifiedevent. 
  3.     *  @param node The priority of the listener isbased on the draw order of this node. 
  4.     *  @note The priority of scene graph will be fixed value 0. So the order oflistener item 
  5.     *          in the vector will be ' <0, scenegraph (0 priority), >0'. 
  6.     */  
  7.    voidaddEventListenerWithSceneGraphPriority(EventListener*listener, Node* node);  
  8.   
  9.    /**Adds a event listener for a specified event with the fixed priority. 
  10.     *  @param listener The listener of a specifiedevent. 
  11.     *  @param fixedPriority The fixed priority ofthe listener. 
  12.     *  @note A lower priority will be called beforethe ones that have a higher value. 
  13.     *        0 priority is forbidden for fixedpriority since it's used for scene graph based priority. 
  14.     */  
  15.    voidaddEventListenerWithFixedPriority(EventListener*listener, int fixedPriority);  
       根据注释可以知道,前者的触发优先级是按照第二个参数中的node的显示顺序来确定的,而且默认的fixedPriority为0,也就是如果精灵位置靠前,则会优先响应触摸。而后者按照第二个参数的整形变量值的大小来确定的,而且不能为0,值越小那么优先响应触摸。两者除了优先级不一样,移除的过程也有差异。前者会在触摸对象对应的node析构之后系统会帮我们调用移除触摸,但是后者就需要我们手动移除,这一点要注意。

       下面我们可以修改上述例子的代码,添加多两个精灵,然后在分发事件代码中添加:

  1. _eventDispatcher->addEventListenerWithSceneGraphPriority(TouchListenr->clone(),onion2);  
  2. _eventDispatcher->addEventListenerWithSceneGraphPriority(TouchListenr->clone(),onion3);  
       点击运行可以测试一下,没有问题。要是想使用addEventListenerWithFixedPriority的方式的话,虽然可以自定义优先级,但是由于没有绑定node对象,所以还需要在触摸函数中引入需要控制的对象才行。但是最后别忘了使用_eventDispatcher->removeEventListener(listerName);来实现监听器的移除。
       多点触摸和单点触摸类似,看下面多点触摸监听器的源码。

  1. class EventListenerTouchAllAtOnce: public EventListener  
  2. {  
  3. public:  
  4.     static const std::string LISTENER_ID;  
  5.      
  6.     static EventListenerTouchAllAtOnce* create();  
  7.     virtual ~EventListenerTouchAllAtOnce();  
  8.      
  9.     ///Overrides  
  10.     virtua lEventListenerTouchAllAtOnce* clone() override;  
  11.     virtual bool checkAvailable() override;  
  12.     //  
  13. public:  
  14.     std::function<void(conststd::vector<Touch*>&,Event*)> onTouchesBegan;  
  15.     std::function<void(conststd::vector<Touch*>&,Event*)> onTouchesMoved;  
  16.     std::function<void(conststd::vector<Touch*>&,Event*)> onTouchesEnded;  
  17.     std::function<void(conststd::vector<Touch*>&,Event*)> onTouchesCancelled;  
  18.      
  19. private:  
  20.    EventListener TouchAllAtOnce();  
  21.     bool init();  
  22. private:  
  23.      
  24.     friend class EventDispatcher;  
  25. };  
    可以发现多点触摸就是传入多个Touch对象而已,然后处理的时候可以遍历vector<Touch*>来逐个处理每一个点,例子可以参考源码自带的例子MutiTouchTest。