全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

cocos creator Touch事件应用(触控选择多个子节点的实例)

最近参与了cocos creator的研究,开发小游戏,结果被一个事件坑得不行不行的。现在终于解决了,分享给大家。

原理

1.触控事件是针对节点的

2.触控事件的冒泡,是直接关系冒泡,父子可以,孙子不行,就是不能隔代冒泡

3.父节点不响应触控事件,肯定是被孩子节点遮挡了,只要孩子节点也监听一下事件,父节点就可以响应了

4.触控位置是绝对坐标,相对于整个canvas,节点位置相对于父节点,相对位置可以与绝对坐标相互转化

5.节点是否被触控到,touch start事件可以肯定被触摸到,但是一个节点触摸到必须等待其结束,另一个节点才能响应touch事件

6.判断是否框选中,根据坐标计算相互交叉即是选中。就是说我从触控起点->触控终点 构成的矩形区域,与节点的矩形存在重叠,就是被框选。本例中,采用比较粗略的算法实现,根据横坐标的范围是否包含子节点的横坐标判断是否选中。

7.计算某个数值是否在某一范围内,首先计算出范围的最大值、最小值,然后作比较即可。

核心代码

cc.Class({
 extends: cc.Component,

 properties: {
  // foo: {
  // default: null,  // The default value will be used only when the component attaching
  //       to a node for the first time
  // url: cc.Texture2D, // optional, default is typeof default
  // serializable: true, // optional, default is true
  // visible: true,  // optional, default is true
  // displayName: 'Foo', // optional
  // readonly: false, // optional, default is false
  // },
  // ...
   poker:{
    default:null,
    type:cc.Node
   },
   cardMask:{
    default:null,
    type: cc.Prefab
   }
 },

 // use this for initialization
 onLoad: function () {
   
   //牌
   this.cards = this.poker.children;

   //牌初始位置
   this.cardInitY = this.cards[0].y;

   //触摸选择到的牌
   this.touchedCards = [];

   //选中的牌
   this.selectedCards = [];

   console.info(this.cards);
  },
  
  start: function () {
   // this.cards = this.poker.children;
   // console.info(this.cards);
   
   this.addTouchEvent();
  },

  /**
   * 添加事件
   */
  addTouchEvent:function(){

   //父节点监听touch事件(直接子节点必须注册同样的事件方能触发)
   this.poker.on(cc.Node.EventType.TOUCH_START, function (event) {
    console.log('poker TOUCH_START');
    
    //牌
    var card = event.target;
    
    //起始触摸位置(和第一张card一样,相对于poker的位置)
    this.touchStartLocation = this.cards[0].convertTouchToNodeSpace(event);
    console.log('touch start Location:'+ JSON.stringify(this.touchStartLocation));
    
    //计算牌位置
    var index = 0;
    for(var i=0;i<this.cards.length;i++){
     var c = this.cards[i];
     if(c.name == card.name){
      index = i;
      break;
     }
    }

    //暂存第一次触摸到的牌
    var touchedCard = {
     index:index,
     card:card
    };
    this.firstTouchedCard = touchedCard;
    //暂存
    this.pushTouchedCards(touchedCard.index,touchedCard.card);

   }, this);
  
   //父节点监听touch事件(直接子节点必须注册同样的事件方能触发)
   this.poker.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
    console.log('poker TOUCH_MOVE');
    //先清除原先触摸到的牌
    this.clearTouchedCards();
    //保存第一张牌
    this.pushTouchedCards(this.firstTouchedCard.index,this.firstTouchedCard.card);

    //触摸点转换为card节点坐标
    var nodeLocation = this.cards[0].convertTouchToNodeSpace(event);
    console.log('touch nodeLocation:'+ JSON.stringify(nodeLocation));
    var x = nodeLocation.x;
    var y = nodeLocation.y; 

    //找到当前选中的牌
    var currentCard = null;
    for(var i=0;i< this.cards.length;i++){
     var card = this.cards[i];
     var cardX = card.x;
     var cardY = card.y;
     console.log('card x='+cardX+',y='+cardY);


     //某张牌范围包括了鼠标位置,选中此牌与触摸开头的所有牌
     var cardWidth = i==5 ? card.width:19;
     var cardHeight = card.height;
     if(cardX<=x && x <= cardX+cardWidth && cardY<=y && y<= cardY+cardHeight){
      currentCard = card;
    
      //暂存触摸到的牌
      this.pushTouchedCards(i,card);
      
      break;
     }
    }
    
    //添加开头与此牌直接的所有牌
    var startTouchLocation = this.touchStartLocation;
    for(var i=0;i< this.cards.length;i++){
     var card = this.cards[i];
     var cardX = card.x;
     //框选的范围包括了的牌
     var min,max;
     if(startTouchLocation.x < nodeLocation.x){
      min = startTouchLocation.x;
      max = nodeLocation.x;
     }else{
      min = nodeLocation.x;
      max = startTouchLocation.x;
     }
     console.log('min='+min+', max='+max);

     if(min <= cardX && cardX <= max){
      //暂存触摸到的牌
      this.pushTouchedCards(i,card);
     }
    }
    

   }, this);
  
  //父节点监听touch事件(直接子节点必须注册同样的事件方能触发)
  this.poker.on(cc.Node.EventType.TOUCH_END, function (event) {
   console.log('poker TOUCH_END');
   this.doSelectCard();
  }, this);
  
  //父节点监听touch事件(直接子节点必须注册同样的事件方能触发)
  this.poker.on(cc.Node.EventType.TOUCH_CANCEL, function (event) {
   console.log('poker TOUCH_CANCEL');
   this.doSelectCard();
  }, this);
  
  //给所有的牌注册事件,会自动冒泡到poker节点
  for(var i=0;i< this.cards.length;i++){
   var cards = this.cards;
   //闭包传递i值
   (function(i){
    var card = cards[i];
    card.on(cc.Node.EventType.TOUCH_START, function (event) {
     console.log('card TOUCH_START');
    }, card);
    
    card.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
     console.log('card TOUCH_MOVE');
    }, card);

    card.on(cc.Node.EventType.TOUCH_END, function (event) {
     console.log('card TOUCH_END');
    }, card);
 
    card.on(cc.Node.EventType.TOUCH_CANCEL, function (event) {
     console.log('card TOUCH_CANCEL');
    }, card);

   
   })(i)
   
  }
  
 },

 /**
  * 暂存触摸到的牌
  */
 pushTouchedCards:function(index,card){
  //构造牌对象
  var cardObj = {
   index:index,
   name:card.name,
   isSelected:card.y==this.cardInitY?false:true //高度不一样,表示选中
  };
  
  //防止重复添加
  var existCard = this.touchedCards.find(function(obj){
   if(obj.name == card.name){
    return obj;
   }else{
    return null;
   }
  });
  if(!existCard){
   //添加暂存
   this.touchedCards.push(cardObj);

   //包含提示
   this.addCardMask(card);
  }
 },

 /**
  * 清除原先暂存的触摸到的牌
  */
 clearTouchedCards:function(){
  for(var i=0;i<this.touchedCards.length;i++){
   var cardIndex = this.touchedCards[i].index;
   var card = this.cards[cardIndex];
   card.removeChild(card.children[0]);
  }
  this.touchedCards = [];
 },

 /**
  * 选择牌
  */
 doSelectCard:function(){
  this.selectedCards = [];

  console.log(this.touchedCards);

  //改变牌状态
  for(var i = 0; i< this.touchedCards.length;i++){
   var cardObj = this.touchedCards[i];
   var card = this.cards[cardObj.index];
   if(cardObj.isSelected){ //如果是选中改为不选中
    card.y = card.y - 30;
   }else{ //不选中改为选中状态
    card.y = card.y + 30;
   }
  }

  //重置
  this.clearTouchedCards();

  //显示选中的牌
  this.showSelectedCards();
 },

 /**
  * 包含牌遮罩
  */
 addCardMask:function(card){
  var cardMask = cc.instantiate(this.cardMask);
  cardMask.setPosition(cc.p(0, 0));
  card.addChild(cardMask);
  },

 /**
 * 显示选中的牌
 */
 showSelectedCards:function(){
  this.selectedCards = [];
  for(var i=0;i< this.cards.length;i++){
   var card = this.cards[i];
   var isSelected = card.y==this.cardInitY?false:true;
   if(isSelected){
    this.selectedCards.push(card.name);
   }
  }
  //输出
  console.info("selected cards is: "+ JSON.stringify(this.selectedCards));
 },

 
 // called every frame, uncomment this function to activate update callback
 // update: function (dt) {

 // },
});

效果

以上这篇cocos creator Touch事件应用(触控选择多个子节点的实例)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# cocos  # creator  # 事件  # iOS开发中使用cocos2d添加触摸事件的方法  # Cocos2d-x触摸事件实例  # 详解CocosCreator优化之DrawCall  # CocosCreator实现技能冷却效果  # 详解cocoscreater预制体prefab  # 如何在CocosCreator中利用常驻节点做图层管理  # 游戏开发中如何使用CocosCreator进行音效处理  # CocosCreator ScrollView优化系列之分帧加载  # 详解CocosCreator系统事件是怎么产生及触发的  # 触控  # 给大家  # 相对于  # 第一张  # 判断是否  # 鼠标  # 多个  # 说我  # 希望能  # 与此  # 即是  # 这篇  # 转换为  # 小编  # 大家多多  # 计算出  # 就可以  # 直接关系  # 本例  # 在某一 


相关文章: 如何通过二级域名建站提升品牌影响力?  Python多线程使用规范_线程安全解析【教程】  高防网站服务器:DDoS防御与BGP线路的AI智能防护方案  如何在景安服务器上快速搭建个人网站?  XML的“混合内容”是什么 怎么用DTD或XSD定义  专业网站建设制作报价,网页设计制作要考什么证?  c# Task.Yield 的作用是什么 它和Task.Delay(1)有区别吗  如何在香港免费服务器上快速搭建网站?  5种Android数据存储方式汇总  教学网站制作软件,学习*后期制作的网站有哪些?  如何获取开源自助建站系统免费下载链接?  建站三合一如何选?哪家性价比更高?  小程序网站制作需要准备什么资料,如何制作小程序?  哈尔滨网站建设策划,哈尔滨电工证查询网站?  如何用搬瓦工VPS快速搭建个人网站?  枣阳网站制作,阳新火车站打的到仙岛湖多少钱?  哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?  建站之星如何配置系统实现高效建站?  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  建站之星后台密码遗忘如何找回?  太平洋网站制作公司,网络用语太平洋是什么意思?  高性价比服务器租赁——企业级配置与24小时运维服务  大连 网站制作,大连天途有线官网?  如何用美橙互联一键搭建多站合一网站?  网站海报制作教学视频教程,有什么免费的高清可商用图片网站,用于海报设计?  如何选择服务器才能高效搭建专属网站?  如何通过山东自助建站平台快速注册域名?  Swift中switch语句区间和元组模式匹配  c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】  如何通过wdcp面板快速创建网站?  微信小程序制作网站有哪些,微信小程序需要做网站吗?  昆明网站制作哪家好,昆明公租房申请网上登录入口?  制作网站哪家好,cc、.co、.cm哪个域名更适合做网站?  上海网站制作开发公司,上海买房比较好的网站有哪些?  怀化网站制作公司,怀化新生儿上户网上办理流程?  制作营销网站公司,淘特是干什么用的?  电视网站制作tvbox接口,云海电视怎样自定义添加电视源?  建站主机选购指南:核心配置优化与品牌推荐方案  建站主机空间推荐 高性价比配置与快速部署方案解析  网站图片在线制作软件,怎么在图片上做链接?  定制建站如何定义?其核心优势是什么?  武汉网站制作费用多少,在武汉武昌,建面100平方左右的房子,想装暖气片,费用大概是多少啊?  黑客如何通过漏洞一步步攻陷网站服务器?  大同网页,大同瑞慈医院官网?  如何在阿里云虚拟服务器快速搭建网站?  网站建设设计制作营销公司南阳,如何策划设计和建设网站?  相亲简历制作网站推荐大全,新相亲大会主持人小萍萍资料?  如何批量查询域名的建站时间记录?  如何自定义建站之星模板颜色并下载新样式?  C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。