【iOS-Cocos2d游戏开发之五】多触点与触屏事件详解(单一监听、事件分发)

本文主要是介绍【iOS-Cocos2d游戏开发之五】多触点与触屏事件详解(单一监听、事件分发),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 李华明Himi  原创,转载务必在明显处注明:
转载自 【黑米GameDev街区】  原文链接:  http://www.himigame.com/iphone-cocos2d/450.html


-----------------------------------本章补充开始!---------------------------------- 

          本篇对于多触点和触屏事件已经做了一个详细的说明,但是有一点忽略了,就是开启多触点的支持!步骤如下:

         首先进入AppDelegate.m 类中, 

[cpp]  view plain copy
  1. <strong>- (void) applicationDidFinishLaunching:(UIApplication*)application{}</strong>  

  在上面这个方法中添加如下一句开启多触点支持的代码:

[cpp]  view plain copy
  1. <strong>    //支持多触点  
  2.     [viewController.view setMultipleTouchEnabled:YES];</strong>  

其他类设置多触点:

[[[CCDirector sharedDirector]openGLView]setMultipleTouchEnabled:YES];

--------------------------本章补充完毕------------------------------------------------------------------------------


最近几天一直在啃cocos2d,消化了不少东西,基本可以有些把握下手写公司的游戏了;那么今天就把一些重点的拿出来分享下经验,给新童鞋们作为参考;

这篇就来详细介绍下cocos2d对用户触屏的监听事件进行下分析(cocos2d有很多详细的文章和教程,我这里只是出于自己的理解来说)

进入正题:从整体cocos2d对触屏的事件监听可以分为两种:

1.单一监听,所谓单一监听其实是跟cocos2d引擎框架有关,因为在cocos2d中每个游戏界面都可以使用一个CCLayout完成,那么当一个CCLayout在屏幕显示出来后,想要监听用户的按键事件,一般都会使用以下形式来进行监听:(注意:这里是CCLayout类进行监听的方式)

首先开启监听:

[cpp]  view plain copy
  1. self.isTouchEnabled=YES;  
然后重写监听函数即可:

[cpp]  view plain copy
  1. //监听首次触发事件  
  2. - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
  3. {  
  4. }  
  5. //触摸事件 - 当手指在屏幕上进行移动  
  6. - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event  
  7. {  
  8.       
  9. }  
  10. //触摸事件 - 当手指从屏幕抬起时调用的方法  
  11. -(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  
  12. {  
  13.           
  14. }  
此种监听狠eazy,但是要注意这里是对CCLayout类进行的监听方式;


2.监听分发; 刚才说了,游戏的每个界面可能都是一个CCLayout,但是如果我想让一个CCSprite精灵主角单独进行监听,或者说在CCLayout有很多个精灵我想单独监听其中的一种的时候,这时候就需要使用监听分发的形式了;

假设我们自定义了一个类XX继承CCSprite,还有一个YY类也继承CCSprite,而且XX类型与YY类的实例都存在于一个Layout上,那么我想对XX与YY类型分别单独监听的话;首先我们先让当前继承的CCSprite类的XX于YY类都使用 <CCTargetedTouchDelegate>协议;

(CCSprite中没有 self.isTouchEnabled=YES; 这个函数,别直接写这个哦~)
 

代码如下:

[cpp]  view plain copy
  1. @interface XX : CCSprite <CCTargetedTouchDelegate>{  
  2.   
  3. }  

然后在当前实现类中重写一个函数如下:

[cpp]  view plain copy
  1. -(void) registerWithTouchDispatcher  
  2. {  
  3.     [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES];  
  4. }  


或者将注册的这句代码,放在重写的onEnter函数中也可;


(此函数是注册监听,如果里面什么都不写,则当前不会相应任何触屏事件;)

重写触摸的各事件函数,如下:

[cpp]  view plain copy
  1. //监听首次触发事件  
  2. - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event  
  3. {   
  4.     return NO;  
  5. }  
  6. //监听移动事件  
  7. - (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event  
  8. {     
  9. }  
  10. //监听离开事件  
  11. - (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event  
  12. {  
  13.       
  14. }  
  15.    

大家可以看到,此种监听方式除了各种监听函数与第一种类似之外,在 ccTouchBegan的函数有个返回类型-布尔值;那么其作用下面详细介绍;如果XX与YY类都实现了第二种监听方式的话,那么当用户触屏后,(当前用户触发的是XX与YY类实例所在的CCLayout)首先会进入XX或者YY的其中的ccTouchBegan函数中,这里假设首先进入了XX类中,那么XX类中的ccTouchBegan将会被响应,如果return true;表示不再将用户触屏的消息传递给YY类中进行响应,也就是说不再响应YY类中的ccTouchBegan函数,那么如果 return false;则会将当前触屏信息传递给其他注册过的类型中;

一句话概括:return 的值,如果是真则表明用户触摸事件已经被处理,其他不会再去进行监听;如果为假,则会继续交给其他注册过的类型中进行处理;


那么第二种监听的方式比较常用,这样便于处理,那么至于注册,一般都是放在 onEnter函数中;onEnter函数是每个CCScene之间切换会被响应的函数,相当于是CCScene的生命周期函数,具体调用顺序如下:

[cpp]  view plain copy
  1. //使用[CCDirector replaceScene:XX],替换场景时,会调用以下3个方法  
  2. //调用顺序依次为:  
  3. //1.othterScene的+(id)Scene——>  
  4. //2.otherScene的init——>  
  5. //3.otherScene的onEnter——>  
  6. //4.运行过渡效果  
  7. //5.当前Scene的onExit函数——>  
  8. //6.otherLayout的onEnterTransitionDidFinish()  
  9. //7.当前Scene的dealoc函数  
  10. -(void) onEnter{  
  11.     //调用其他Scene的init方法以后会调用此方法  
  12.     //如果使用了CCTransitionScene,本方法将在过渡效果开始后调用  
  13.     //(如果不调用super onEnter新场景可能对触摸和加速计无发应)  
  14.     [super onEnter];  
  15. }  
  16. -(void) onEnterTransitionDidFinish{  
  17.     //调用onEnter后会调用此函数  
  18.     //如果使用了CCTransitionScene,将会在过渡效果完成时调用此方法  
  19.     [super onEnterTransitionDidFinish];  
  20. }  
  21. -(void)onExit{   
  22.     //在调用dealloc之前会调用此函数;  
  23.     //如果使用了CCTransitionScene,将会在过渡效果结束以后调用此方法  
  24.     //(如果不调用super onExit,当前场景可能不会从内存中释放)  
  25.     [super onExit];  
  26. }  

那么大概介绍了监听事件后,那么触屏中最关心的就应该是多触点啦;

[cpp]  view plain copy
  1. //-----获取多点触摸  
  2. NSSet *allTouches = [event allTouches];  
  3. UITouch *touchOne = [[allTouches allObjects]objectAtIndex:0];  
  4. UITouch *touchTwo = [[allTouches allObjects]objectAtIndex:1];  
  5. //...类推  

获取多点狠简单,那么下面再将基本常用到的几个判断写下:

1-判断用户单击还是双击(针对一个触点)

[cpp]  view plain copy
  1.   

[cpp]  view plain copy
  1. if([allTouches count]==1) {   
  2.     UITouch *touchOne = [[allTouches allObjects]objectAtIndex:0];  
  3.     switch ([touchOne tapCount]) {  
  4.         case 1:  
  5.              //单击  
  6.             CCLOG(@"%@",@"单击");  
  7.             break;  
  8.         case 2:  
  9.             //双击  
  10.             CCLOG(@"%@",@"双击");  
  11.             break;  
  12.     }  
  13. }  

1-判断用户两个触点之间是合拢还是分开(针对两个触点)

[cpp]  view plain copy
  1.   

[cpp]  view plain copy
  1.  <pre name="code" class="cpp">if([allTouches count]==2) {   
  2.     //适当修改处理,不能同时取,否则肯定一样的啦(可以一个在began 一个在end)  
  3.     UITouch *touchOne = [[allTouches allObjects]objectAtIndex:0];  
  4.     UITouch *touchTwo = [[allTouches allObjects]objectAtIndex:1];  
  5.     CGFloat *disFirst  =[self distance:[touchOne locationInView:[self view]]   
  6.                             todistance:[touchTwo locationInView:[self view]]];  
  7.       
  8.     UITouch *touchOne = [[allTouches allObjects]objectAtIndex:0];  
  9.     UITouch *touchTwo = [[allTouches allObjects]objectAtIndex:1];  
  10.     CGFloat *disFinal  =[self distance:[touchOne locationInView:[self view]]  
  11.                             todistance:[touchTwo locationInView:[self view]]];  
  12.     if (disFirst>disFinal) {  
  13.         CCLOG(@"%@",@"合拢");  
  14.     }else{  
  15.         CCLOG(@"%@",@"分开");  
  16.     }  
  17. }</pre><br><pre></pre><p></p><pre></pre><p></p><p class="p1">这里我就粗略的写在一起,判定两个触点是否合拢其实就是用户刚触屏时记录两点之间的距离记做disFirst,然后在两个触点离开屏幕(或者移动事件中)的时候计算</p><p class="p1">当前的两个触点的距离disFinal,那么最后根据disFirst与disFinal距离关系就能知道是合拢还是分开;</p><p class="p1">(CCLOG 是cocos2d封装的打印方法,此种打印在编译发布正式游戏程序的时候是不会编译到程序中的,但是NSLOG会一直存在!要注意!)</p><p class="p1"></p><p class="p1">最后给出两个函数,用于计算不同方式监听的函数中获取(转换)坐标的,因为cocos2d是openGL进行搭建的框架,所以需要坐标转换;</p><p class="p1"></p><pre name="code" class="cpp">+(CGPoint) locationFromTouches:(NSSet*)touches  
  18. {  
  19.     return [self locationFromTouch:[touches anyObject]];  
  20. }  
  21. +(CGPoint) locationFromTouch:(UITouch*)touch  
  22. {  
  23.     CGPoint touchLocation = [touch locationInView: [touch view]];  
  24.     return [[CCDirector sharedDirector] convertToGL:touchLocation];  
  25. }</pre><br>两个方法一看就能看出区别,一个是UITouch的,一个是NSSet,一个是单一监听,一个是分发监听;<p></p><p class="p1">ok,本章就到这里~~~(下周进入封闭开发了,吃睡都在公司了,咳咳,带上我的多啦a梦的小裤衩,娃哈哈~)</p><p class="p1"><br></p><p class="p1"><br></p><p class="p1"><br></p><p class="p1"><br></p><p class="p1"><br></p><br><pre></pre><pre></pre><pre></pre>  

这篇关于【iOS-Cocos2d游戏开发之五】多触点与触屏事件详解(单一监听、事件分发)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1049656

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

禁止平板,iPad长按弹出默认菜单事件

通过监控按下抬起时间差来禁止弹出事件,把以下代码写在要禁止的页面的页面加载事件里面即可     var date;document.addEventListener('touchstart', event => {date = new Date().getTime();});document.addEventListener('touchend', event => {if (new

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta