精灵的触摸群选择(有回退功能)的简单实现

请教三个个触摸事件问题 继续讨论:

经过两天的研究,今天终于实现了这个滑动选取功能。
我主要是实现卡牌滑动选取的功能。比如一共20张牌,我触摸起点是第10张,继续向左滑,经过的卡牌都会被选中,往回返的话原来选中的又会重新取消选中,最后松手,选中的牌弹起。
cocos2dx里面本身没有这个功能,但是靠我这个笨蛋的取巧实现了,现在贴上部分代码分享下:

		auto listener = EventListenerTouchOneByOne::create();
		listener->setSwallowTouches(false);
		//触摸开始
		listener->onTouchBegan = [=](Touch *touch, Event *event)
		{
			//把触摸牌组置为0,数量置为0;
			memset(m_bTouchCard, 0, 25);
			TouchCardIndex = 0;

			auto target = static_cast<FKDSCardLayout *>(event->getCurrentTarget());
			Point locationInNode = target->convertToNodeSpace(touch->getLocation());
			Size size = target->getContentSize();
			Rect rect = Rect(0, 0, size.width, size.height);
			if (rect.containsPoint(locationInNode))
			{
				//得到卡牌的位置编号
				int cardIndex = (int)(locationInNode.x / gameData->m_cardDistance);
				if (cardIndex > target->getTag() - 1)
					cardIndex = target->getTag() - 1;
				cocos2d::log("触摸开始的牌是: %d", cardIndex);

				//把触摸到的第一张牌加入触摸牌组
				m_bTouchCard[0] = cardIndex;
				TouchCardIndex = 1;
				m_viewCard[cardIndex]->setOpacity(180);
				return true;
			}
			return false;
		};
		//触摸经过
		listener->onTouchMoved = [=](Touch *touch, Event *event)
		{
			auto target = static_cast<FKDSCardLayout *>(event->getCurrentTarget());		
			Point locationInNode = target->convertToNodeSpace(touch->getLocation());
			Size size = target->getContentSize();
			Rect rect = Rect(0, 0, size.width, size.height);
			if (rect.containsPoint(locationInNode))
			{
				//得到卡牌的位置编号
				int cardIndex = (int)(locationInNode.x / gameData->m_cardDistance);
				if (cardIndex > target->getTag() - 1)
					cardIndex = target->getTag() - 1;

				//触摸点移动到了开始点左边
				if(cardIndex - m_bTouchCard[0] <= 0)
				{
					//之前卡牌恢复原来透明度
					for (BYTE i = 0; i < TouchCardIndex; ++i)
					{
						m_viewCard[m_bTouchCard[i]]->setOpacity(255);
					}
					for (BYTE i = 0; i <= m_bTouchCard[0] - cardIndex; ++i)
					{
						m_bTouchCard[i] = m_bTouchCard[0] - i;
						m_viewCard[m_bTouchCard[0] - i]->setOpacity(180);
					}
					TouchCardIndex = m_bTouchCard[0] - cardIndex + 1;
				}
				//触摸点移动到了开始点右边
				else if(cardIndex - m_bTouchCard[0] > 0)
				{
					//之前卡牌恢复原来透明度
					for (BYTE i = 0; i < TouchCardIndex; ++i)
					{
						m_viewCard[m_bTouchCard[i]]->setOpacity(255);
					}
					for (BYTE i = 0; i <= cardIndex - m_bTouchCard[0]; ++i)
					{
						m_bTouchCard[i] = m_bTouchCard[0] + i;
						m_viewCard[m_bTouchCard[0] + i]->setOpacity(180);
					}
					TouchCardIndex = cardIndex - m_bTouchCard[0] + 1;
				}
			}
		};

		//触摸结束
		listener->onTouchEnded = [=](Touch *touch, Event *event)
		{
			//如果触摸到卡牌
			EventBus::postEvent(FKDSEvent::TouchCardEndEvent(m_bTouchCard, TouchCardIndex));
			//卡牌恢复原来透明度
			for (BYTE i = 0; i < 25 - gameData->m_bCardCount[0]; ++i)
			{
				m_viewCard[i]->setOpacity(255);
			}
		};
		_eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

希望对有需要的人有所帮助吧,自己一个人琢磨好费时间哒

2赞

我也有差不多的问题,找了很久也找不到答案,
但我的问题更大,因为要经过的那些是不固定位置,位置是随机生成的,
一直想不到解决放法…

记录滑动的起始位置和每一帧的当前位置,生成一个touch的rect,转换到world坐标,然后取每一个你要检测的物体的boundingbox,转换到world坐标,根据你的需求判断和touch的rect是否相交或者是否被包含,来决定物体是否被框选。