【cocos2d-x入门实战】微信飞机大战之七:触摸事件和优先级

原创作品,转载请标明http://blog.csdn.net/jackystudio/article/details/11860007

飞机也登场了,子弹也可以正常发射了,但是不能动的飞机算神马回事,坑爹呢!!!

整个游戏的触摸事件处理我们把它放在GameLayer中,比较直观。


1.CCTargetedTouch

我们先看一下CCLayer的声明:

class CC_DLL CCLayer : public CCNode, public CCTouchDelegate, public CCAccelerometerDelegate, public CCKeypadDelegate
它是从CCNode继承来的,同时也继承了3个硬件相关接口事件,分别是触摸事件,加速器事件和键盘事件。

所以我们可以直接在CCLayer中进行触摸事件的处理。

触摸事件中有两个类,CCStandradTouch,CCTargetedTouch。前者为多点触摸,后者为单点触摸,而系统默认注册前者分发事件,我们这里要进行继续重载虚函数registerWithTouchSpatcher,对单点有效。

//init()中设置可触摸
this->setTouchEnabled(true);

void GameLayer::registerWithTouchDispatcher()
{
	CCDirector *pDirector=CCDirector::sharedDirector();
	pDirector->getTouchDispatcher()->addTargetedDelegate(this,0,true);
}

CCStandradTouch这里就不进行讨论了。


2.触摸的回调函数

virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);//触摸开始调用
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);//触摸移动调用
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);//触摸结束调用
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);//一般是系统级调用,比如触摸过程中来电之类的
这里我们只要重写前两个就够了。

其中ccTouchBegan返回的是bool值。

A.如果返回true,表示当前层接收触摸事件,同时允许ccTouchMoved,ccTouchEnded和ccTouchCancelled的调用。

B.如果返回false,表示当前层不接受触摸事件,后面的ccTouchMoved等等也就不往下走了。

而ccTouchMoved就是我们进行飞机移动处理的主战场了。

//GameLayer.cpp
bool GameLayer::ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent)
{
	return true;//表示当前层接收触摸事件处理
}

void GameLayer::ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent)
{
	if (this->planeLayer->isAlive)//isAlive是AirPlane的一个成员属性,表示飞机是否还活着
	{
		CCPoint beginPoint=pTouch->locationInView(); 
		beginPoint=CCDirector::sharedDirector()->convertToGL(beginPoint); //获取触摸坐标
		//juggle the area of drag 
		CCRect planeRect=this->planeLayer->getChildByTag(AIRPLANE)->boundingBox();//获取飞机当前位置形状位置
		planeRect.origin.x-=15;
		planeRect.origin.y-=15;
		planeRect.size.width+=30;
		planeRect.size.height+=30;//允许稍微加大一点触摸位置,游戏实际需要
		if(CCRect::CCRectContainsPoint(planeRect,
			this->getParent()->convertTouchToNodeSpace(pTouch))==true) //判断触摸点是否在飞机范围内
		{ 
			CCPoint endPoint=pTouch->previousLocationInView();//获取触摸的前一个位置
			endPoint=CCDirector::sharedDirector()->convertToGL(endPoint); 

			CCPoint offSet =ccpSub(beginPoint,endPoint);//获取offset
			CCPoint toPoint=ccpAdd(this->planeLayer->getChildByTag(AIRPLANE)->getPosition(),offSet); //获取真正移动位置
			this->planeLayer->MoveTo(toPoint); //移动飞机
		} 
	}
}
//PlaneLayer.cpp
void PlaneLayer::MoveTo(CCPoint location)
{
	//飞机及游戏状态判断
	if(isAlive && !CCDirector::sharedDirector()->isPaused())
	{
		//进行边界判断,不可超出屏幕
		CCPoint actualPoint;
		CCSize winSize=CCDirector::sharedDirector()->getWinSize();
		CCSize planeSize=this->getChildByTag(AIRPLANE)->getContentSize();
		if (location.x<planeSize.width/2)
		{
			location.x=planeSize.width/2;
		}
		if (location.x>winSize.width-planeSize.width/2)
		{
			location.x=winSize.width-planeSize.width/2;
		}
		if (location.y<planeSize.height/2)
		{
			location.y=planeSize.height/2;
		}
		if (location.y>winSize.height-planeSize.height/2)
		{
			location.y=winSize.height-planeSize.height/2;
		}
		this->getChildByTag(AIRPLANE)->setPosition(location);
	}
}

3.触摸优先级和触摸事件的吞噬

大家看到触摸事件的分派注册中,addTargetdDelegate第二个和第三个函参,又是什么意思呢?

A.第二个参数表示触摸事件的优先级,值越小,优先级越高,比如层1的优先级是-50,层2的优先级是-100,那么层2会先接收并处理触摸事件,然后才有机会轮到层1来接收处理。

B.第三个参数表示swallow事件,表示当前层是否吞噬掉这个触摸,即不往优先级更低的层传送。

要注意的是触摸事件的触发是根据添加的顺序依次触发的,后添加的层先捕获触摸事件,当然,这是没有设置事件优先级的情况下,若要是定义了事件的优先级,则先按照事件的优先级依次被触发,然后根据添加的顺序依次被触发。CCMenu的优先级是-128,而CCControlButton的优先级是0。


好了,这一节后,我们就可以控制飞机移动并且发射子弹了,而子弹一旦超出屏幕就会被回收,飞机也不会超出屏幕外。

效果图


  • 16
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 37
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值