根据触摸位置确定移动方向

时间:2012-07-20 07:50:31

标签: c++ ios

我正在尝试找出根据用户触摸屏幕确定要移动的方向的最佳方法。所以说我得到一个23x和320y的2d位置然后我需要返回以下LEFT,RIGHT,UP,DOWN中的一个。

目前我使用的代码不是很可靠,我想知道是否有人可以告诉我更好的方法。

由于

if (at_position.x <= width*2/3 && at_position.x >= width*1/3 && at_position.y <= this->screenHeight*2/3)
{
    return UP;

}
else if (at_position.x <= width*2/3 && at_position.x >= width*1/3 && at_position.y >= this->screenHeight*1/3)
{
    return DOWN;      
}
else if (at_position.x <= this->screenWidth*2/3 && at_position.y >= this->screenHeight*1/3 && at_position.y <= this->screenHeight*2/3)
{
   return LEFT;         
}
else if (at_position.x <= this->screenWidth*1/3 && at_position.y >= this->screenHeight*1/3 && at_position.y <= this->screenHeight*2/3)
{
   return RIGHT;        
}

4 个答案:

答案 0 :(得分:2)

你可以根据旧位置和新位置计算一个向量:newX - oldX,newY - oldY,这可以用作一个角度,用于确定方向只需将范围0-360(角度)转换为0- 3(枚举值)。对于更精确的方法,在根据新位置确定方向之前进行短暂延迟(0.1s)

用于将矢量转换为范围[0到2 * PI]的角度,使用

C#:
float angle = Math.Atan2(newY - oldY, newX - oldX) + Math.PI;

使用

将其转换为度数
C#:
angle = angle * (180 / Math.PI);

将其转换为枚举值

C#:
int e = (int)angle / 90; //will give 0 for 0-90, 1 for 90-180, 2 for 180-270...

然后你的枚举可能看起来像这样

C#:
enum dir {
    R = 0, D = 1, L = 2, U = 3 }

答案 1 :(得分:1)

我建议计算方向矢量的角度并根据它做出建议

vec2 dir = ...
float angle = atan2f(dir.y, dir.x) + M_PI; //angle is in range [0, 2*PI] now
if (angle > 7 * M_PI / 4 && angle <= M_PI / 4) {//right}
else if (angle > M_PI / 4 && angle <= 3 * M_PI / 4) {//top}
//and so on

要计算dir,您需要指出。一个是 - 您当前的触摸位置。第二个可以是prev touch position位置或某个固定点(例如屏幕的中心)

如果你有这一点:

vec2 dir = currentTouchPoint - prevPoint; //or origin

答案 2 :(得分:1)

我不会像其他人建议的那样使用复杂的解决方案(比如计算用户点击的向量)。你没有解决一个困难的数学问题,你只需要确定该点是否在某个区域内。所以不要过于复杂。

//lets you check if point a is between the boundaies, which in your case are either 
//X or Y coordinates. 
bool isBetween( int a, int firstBoundary, int secondBoundary)
{
   return (a >= firstBoundary && a <= secondBoundary);
}

if (isBetween(at_position.x, width*1/3, width*2/3))
{
    if(at_position.y <= this->screenHeight*2/3)
        return UP;
    else if(at_position.y >= this->screenHeight*1/3)
        return DOWN;      
}
else if (isBetween(at_position.y, this->screenHeight*1/3, this->screenHeight*2/3))
{
    if(at_position.x <= this->screenWidth*2/3)
       return LEFT;         
    else if(at_position.y <= this->screenHeight*2/3)
       return RIGHT;
}

当然,这仍然不是最好看的代码,但考虑到它需要做什么,我认为并不是最糟糕的。

答案 3 :(得分:1)

最简单的方法:

宣布这个结构。

typedef enum {
    kDirecLeft = 1,
    kDirecRight,
    kDirecUp,
    kDirecDown,
}SwipDirection;

使用这两个成员变量:

CGPoint             mSwipTouch1;
CGPoint             mSwipTouch2;

在TouchesBegan中初始化mSwipTouch1并在TouchesEnded中初始化mSwipTouch2

-(void)checkForDirection
{
    SwipDirection direction;

    bool isValidSwip = false;

    float swipXLength = ABS(mSwipTouch1.x-mSwipTouch2.x) ;
    float swipYLength = ABS(mSwipTouch1.y-mSwipTouch2.y) ;

    float swipDistance ; 

    if(swipXLength > swipYLength)  // Left/Right swip
    {
        swipDistance = swipXLength;

        if(swipXLength > MIN_SWIP_LENGHT)
        {
            if(mSwipTouch1.x > mSwipTouch2.x) //Left swip
            {
                DEBUG_LOG("Left swip\n") ;
                direction = kDirecLeft ; 
                isValidSwip = true;
            }
            else
            {
                DEBUG_LOG("Right swip\n") ;
                direction = kDirecRight ;
                isValidSwip = true;
            }
        }
    }
    else  // Up/Down Swip
    {
        swipDistance = swipYLength;

        if(swipYLength > MIN_SWIP_LENGHT)
        {
            if(mSwipTouch1.y > mSwipTouch2.y) //Left swip
            {
                DEBUG_LOG("Down swip\n") ;
                direction = kDirecDown ;
                isValidSwip = true;
            }
            else
            {
                DEBUG_LOG("Up swip\n") ;
                direction = kDirecUp ;
                isValidSwip = true;
            }
        }
    }

    if(isValidSwip)
        [self process:direction];
}

-(void)process:(SwipDirection)direc
{
    switch(direc)
    {
      case kDirecLeft:
           [self moveLeft];
            break;
        case kDirecRight:
            [self moveRight];
            break;

        case kDirecDown:
            [self moveDown];
            break;

        case kDirecUp:
            [self moveUp];
            break;
        default:
            break;    
    }
}