cocos creator Touch事件應(yīng)用(觸控選擇多個子節(jié)點的實例)
最近參與了cocos creator的研究,開發(fā)小游戲,結(jié)果被一個事件坑得不行不行的?,F(xiàn)在終于解決了,分享給大家。
原理
1.觸控事件是針對節(jié)點的
2.觸控事件的冒泡,是直接關(guān)系冒泡,父子可以,孫子不行,就是不能隔代冒泡
3.父節(jié)點不響應(yīng)觸控事件,肯定是被孩子節(jié)點遮擋了,只要孩子節(jié)點也監(jiān)聽一下事件,父節(jié)點就可以響應(yīng)了
4.觸控位置是絕對坐標(biāo),相對于整個canvas,節(jié)點位置相對于父節(jié)點,相對位置可以與絕對坐標(biāo)相互轉(zhuǎn)化
5.節(jié)點是否被觸控到,touch start事件可以肯定被觸摸到,但是一個節(jié)點觸摸到必須等待其結(jié)束,另一個節(jié)點才能響應(yīng)touch事件
6.判斷是否框選中,根據(jù)坐標(biāo)計算相互交叉即是選中。就是說我從觸控起點->觸控終點 構(gòu)成的矩形區(qū)域,與節(jié)點的矩形存在重疊,就是被框選。本例中,采用比較粗略的算法實現(xiàn),根據(jù)橫坐標(biāo)的范圍是否包含子節(jié)點的橫坐標(biāo)判斷是否選中。
7.計算某個數(shù)值是否在某一范圍內(nèi),首先計算出范圍的最大值、最小值,然后作比較即可。
核心代碼
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(){
//父節(jié)點監(jiān)聽touch事件(直接子節(jié)點必須注冊同樣的事件方能觸發(fā))
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);
//父節(jié)點監(jiān)聽touch事件(直接子節(jié)點必須注冊同樣的事件方能觸發(fā))
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);
//觸摸點轉(zhuǎn)換為card節(jié)點坐標(biāo)
var nodeLocation = this.cards[0].convertTouchToNodeSpace(event);
console.log('touch nodeLocation:'+ JSON.stringify(nodeLocation));
var x = nodeLocation.x;
var y = nodeLocation.y;
//找到當(dāng)前選中的牌
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);
//某張牌范圍包括了鼠標(biāo)位置,選中此牌與觸摸開頭的所有牌
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);
//父節(jié)點監(jiān)聽touch事件(直接子節(jié)點必須注冊同樣的事件方能觸發(fā))
this.poker.on(cc.Node.EventType.TOUCH_END, function (event) {
console.log('poker TOUCH_END');
this.doSelectCard();
}, this);
//父節(jié)點監(jiān)聽touch事件(直接子節(jié)點必須注冊同樣的事件方能觸發(fā))
this.poker.on(cc.Node.EventType.TOUCH_CANCEL, function (event) {
console.log('poker TOUCH_CANCEL');
this.doSelectCard();
}, this);
//給所有的牌注冊事件,會自動冒泡到poker節(jié)點
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){
//構(gòu)造牌對象
var cardObj = {
index:index,
name:card.name,
isSelected:card.y==this.cardInitY?false:true //高度不一樣,表示選中
};
//防止重復(fù)添加
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);
//改變牌狀態(tài)
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{ //不選中改為選中狀態(tài)
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事件應(yīng)用(觸控選擇多個子節(jié)點的實例)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaScript 模塊的循環(huán)加載實現(xiàn)方法
本文介紹JavaScript語言如何處理"循環(huán)加載"。目前,最常見的兩種模塊格式CommonJS和ES6,處理方法是不一樣的,返回的結(jié)果也不一樣2015-12-12
頁面下沉抖動效果-網(wǎng)站HTTP連接沒有效果-PC上有效果
頁面下沉抖動效果實現(xiàn)代碼,代碼少,功能還可以2008-05-05
JavaScript數(shù)組去重算法實例小結(jié)
這篇文章主要介紹了JavaScript數(shù)組去重算法,結(jié)合實例形式總結(jié)分析了JavaScript數(shù)組去重相關(guān)的讀寫、遍歷、比較、排序等操作及算法改進相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2018-05-05
使用iframe window的scroll方法控制iframe頁面滾動
在頁面中如何控制內(nèi)嵌的iframe滾動呢?方法是使用iframe window的scroll方法,大家可以參考下面的示例2014-03-03
JavaScript大數(shù)相加相乘的實現(xiàn)方法實例
這篇文章主要給大家介紹了關(guān)于JavaScript大數(shù)相加相乘的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
JavaScript統(tǒng)計字符串中每個字符出現(xiàn)次數(shù)完整實例
這篇文章主要介紹了JavaScript統(tǒng)計字符串中每個字符出現(xiàn)次數(shù)的方法,以完整實例形式分析了JavaScript針對字符串中字符的遍歷操作相關(guān)技巧,需要的朋友可以參考下2016-01-01

