>웹 프론트엔드 >JS 튜토리얼 >코코스크리에이터 터치 이벤트 어플리케이션에 대한 자세한 설명

코코스크리에이터 터치 이벤트 어플리케이션에 대한 자세한 설명

巴扎黑
巴扎黑원래의
2017-09-11 09:32:025194검색

코코스 크리에이터 터치 이벤트 적용(터치하여 여러 자식 노드를 선택하는 예)에 대한 글은 아래 에디터에서 보실 수 있습니다. 편집자님도 꽤 괜찮다고 하셔서 이제라도 전해드리고 참고용으로 드리고 싶습니다. 에디터 따라가서 살펴볼까요

최근 코코스 크리에이터의 연구에 참여해 작은 게임들을 개발했는데, 사건에 속았네요. 이제 드디어 해결해서 모두와 공유하겠습니다.

Principle

1. 터치 이벤트는 노드를 위한 것입니다

2. 터치 이벤트의 버블링은 아버지와 아들이 할 수 있지만 손자가 할 수는 없습니다. 세대

3 .부모 노드가 터치 이벤트에 응답하지 않으면 자식 노드에 의해 차단되어야 합니다. 자식 노드도 이벤트를 수신하는 한 부모 노드는 터치 위치에 있습니다. 는 절대 좌표이며, 전체 캔버스를 기준으로 노드 위치는 상대적입니다. 상위 노드를 기준으로 상대 위치는 절대 좌표로 변환될 수 있습니다

5. 노드를 터치하든 터치 시작 이벤트는 확실히 터치될 수 있습니다. , 그러나 노드가 터치되면 다른 노드가 터치 이벤트에 응답하기 전에 노드가 끝날 때까지 기다려야 합니다

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(&#39;poker TOUCH_MOVE&#39;);
    //先清除原先触摸到的牌
    this.clearTouchedCards();
    //保存第一张牌
    this.pushTouchedCards(this.firstTouchedCard.index,this.firstTouchedCard.card);

    //触摸点转换为card节点坐标
    var nodeLocation = this.cards[0].convertTouchToNodeSpace(event);
    console.log(&#39;touch nodeLocation:&#39;+ 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(&#39;card x=&#39;+cardX+&#39;,y=&#39;+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(&#39;min=&#39;+min+&#39;, max=&#39;+max);

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

   }, this);
  
  //父节点监听touch事件(直接子节点必须注册同样的事件方能触发)
  this.poker.on(cc.Node.EventType.TOUCH_END, function (event) {
   console.log(&#39;poker TOUCH_END&#39;);
   this.doSelectCard();
  }, this);
  
  //父节点监听touch事件(直接子节点必须注册同样的事件方能触发)
  this.poker.on(cc.Node.EventType.TOUCH_CANCEL, function (event) {
   console.log(&#39;poker TOUCH_CANCEL&#39;);
   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(&#39;card TOUCH_START&#39;);
    }, card);
    
    card.on(cc.Node.EventType.TOUCH_MOVE, function (event) {
     console.log(&#39;card TOUCH_MOVE&#39;);
    }, card);

    card.on(cc.Node.EventType.TOUCH_END, function (event) {
     console.log(&#39;card TOUCH_END&#39;);
    }, card);
 
    card.on(cc.Node.EventType.TOUCH_CANCEL, function (event) {
     console.log(&#39;card TOUCH_CANCEL&#39;);
    }, 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) {

 // },
});

Effect

위 내용은 코코스크리에이터 터치 이벤트 어플리케이션에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.