原创作品,转载请标明:http://blog.csdn.net/jackystudio/article/details/11860007
飞机也登场了,子弹也可以正常发射了,但是不能动的飞机算神马回事,坑爹呢!!!
整个游戏的触摸事件处理我们把它放在GameLayer中,比较直观。
我们先看一下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这里就不进行讨论了。
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); } }
大家看到触摸事件的分派注册中,addTargetdDelegate第二个和第三个函参,又是什么意思呢?
A.第二个参数表示触摸事件的优先级,值越小,优先级越高,比如层1的优先级是-50,层2的优先级是-100,那么层2会先接收并处理触摸事件,然后才有机会轮到层1来接收处理。
B.第三个参数表示swallow事件,表示当前层是否吞噬掉这个触摸,即不往优先级更低的层传送。
要注意的是触摸事件的触发是根据添加的顺序依次触发的,后添加的层先捕获触摸事件,当然,这是没有设置事件优先级的情况下,若要是定义了事件的优先级,则先按照事件的优先级依次被触发,然后根据添加的顺序依次被触发。CCMenu的优先级是-128,而CCControlButton的优先级是0。
好了,这一节后,我们就可以控制飞机移动并且发射子弹了,而子弹一旦超出屏幕就会被回收,飞机也不会超出屏幕外。
效果图