Cocos2dx学习之-----关于拖动缓冲,点击屏幕获取方向
写在前面::因为还不是很熟练,这些方法只是自己想到的而已,或许有更好的方法,现在只是写下来,备用。
1、关于拖动缓冲
我的思路是根据拖动方向,在触摸结束后,创建一个动作moveTo,目标点是精灵当前坐标加上根据拖动方向设置的一个点。因此这里涉及到点的计算;
首先,在ccTouchBegin里面获取开始触摸的点 beginPos,在ccTouchEnded里面获取结束的触摸点 endPos;
接着,根据这两个点就可以获得移动/拖动的方向,也可以说endPos相对于beginPos的坐标;
最后,获得了方向之后,在精灵被拖动后的位置的基础上加上这个方向,创建一个动作,让这个精灵运行这个动作就有简单的缓冲效果。直接上代码:
//touch开始,获得开始点的坐标 void TestLayer::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator ite=pTouches->begin(); CCTouch* pTouch=(CCTouch*)(*ite); beginPos=pTouch->getLocation(); }
//touch结束,获得结束点的坐标 void TestLayer::ccTouchesEnded(CCSet *pTouches, CCEvent *pEvent){ CCSetIterator ite=pTouches->begin(); CCTouch* pTouch=(CCTouch*)(*ite); CCPoint endPos=pTouch->getLocation(); CCPoint pos=this->moveToPos(beginPos, endPos); //拖动缓冲 pTileMap->runAction(CCMoveTo::create(0.5f, pos)); }
//计算拖动缓冲的方法,其中涉及到了边界 //计算移动缓冲 CCPoint TestLayer::moveToPos(CCPoint begin,CCPoint end){ float x=(end.x-begin.x)*0.5; float y=(end.y-begin.y)*0.5; CCPoint pos=ccpAdd(pTileMap->getPosition(), ccp(x,y)); //获取锚点 CCPoint ancho=pTileMap->getAnchorPoint(); scale=pTileMap->getScale(); CCSize tileSize=pTileMap->getContentSize(); //判断移动缓冲距离 //左 if (pos.x-tileSize.width*ancho.x*scale>=winSize.width*0.2) { pos.x=tileSize.width*ancho.x*scale+winSize.width*0.2; } //右 if (pos.x+tileSize.width*(1-ancho.x)*scale<=winSize.width-winSize.width*0.2) { pos.x=winSize.width-tileSize.width*(1-ancho.x)*scale-winSize.width*0.2; } //下 if(pos.y-tileSize.height*ancho.y*scale>=0){ pos.y=tileSize.height*ancho.y*scale; } //上 if (pos.y+tileSize.height*(1-ancho.y)*scale<=winSize.height){ pos.y=winSize.height-tileSize.height*(1-ancho.y)*scale; } return pos; }
代码中的tileSize指的是拖动的精灵或者啥的大小,这里主要是为了做边界计算,设置边界用到的。
以上便是我自己想的关于拖动缓冲的一些想法;
2、关于点击某个精灵周边的点然后获得点击方向(上下左右四个)的一些想法
需求源于:在游戏中,我们在一个地图上要控制一个精灵移动,有这样一种操作方法,就是在精灵周边点击,假如点击的点在精灵的左边,那么精灵就往左边移动,如果是右边,精灵就往右边移动。看起来挺简单的,但是要实现这个方向的判断,着实花了我这个新手一些时间。下面来看看我的想法:
思路:获得触摸点相对于精灵位置的坐标,然后再计算这个坐标点相对于精灵位置的角度。再在精灵的四周设置四个象限(顺时针旋转)
右方向的触发条件:当角度位于-45度到45度之间;
上方向的触发条件:当角度位于45度到135度之间;
左方向的触发条件:当角度位于45度到-135度之间;
下方向的触发条件:当角度位于-135度到-45度之间;
大概的意思就是如下图所示:
当位于相应的区域后,就发出响应的方向消息,返回一个方向值;
具体的做法:
首先,在ccTouchEnded方法中获得触摸结束后的点,(意思就是触摸结束后,精灵要开始移动了)endPos。然后获取精灵的当前坐标pos。二者相减,将endPos
减去pos,是不是获取了触摸点相对于精灵的坐标位置??
然后就是根据这个坐标获得角度值了。cocos2dx自带了相关的方法,可以获得某个点的弧度值。因为我们之前已经做了点的处理,触摸点已经转化为了相对于pos的坐标,因此在这里计算弧度值得到的就是之前我们要求的这个角度;
最后就是判断啦,根据弧度值的大小,判定所在的区域,代码:
//首先获得四个角度的弧度值 one=CC_DEGREES_TO_RADIANS(45); two=CC_DEGREES_TO_RADIANS(135); three=CC_DEGREES_TO_RADIANS(-135); four=CC_DEGREES_TO_RADIANS(-45);
//这是计算方向的方法 Direction TestLayer::getDirction(cocos2d::CCPoint pos){ float ang=ccpToAngle(pos); //右 if (four<ang&&ang<one) { CCLog("右"); return dir_Right; } //上 if (one<ang&&ang<two) { CCLog("上"); return dir_Up; } //左 if ((two<ang||ang<three)) { CCLog("左"); return dir_Left; } //下 if (three<ang&&ang<four) { CCLog("下"); return dir_Down; } }
//当然四个方向是已经定义好了的typedef enum{ dir_Right =0, dir_Up, dir_Left, dir_Down }Direction;
//这样在触摸结束后,计算触摸点相对于精灵的坐标,再调用计算方向的方法,就可以实现判断方向的功能了 CCPoint touchEndToTile=ccpSub(endPos,player->getPosition()); CCLog("end pos=%f,end pos=%f",touchEndToTile.x,touchEndToTile.y); int i=this->getDirction(touchEndToTile); CCLog("dir==%d",i);
以上就大概是判断方向的一些个人想法了。留着备用,希望以后能找到更好的方法;