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);

以上就大概是判断方向的一些个人想法了。留着备用,希望以后能找到更好的方法;
posted @ 2013-11-21 09:39  Le Ciel  阅读(535)  评论(0编辑  收藏  举报