2012-07-20 105 views
0

我正在嘗試找出根據用戶在屏幕上觸摸來確定移動哪個方向的最佳方法。所以說我得到一個二維位置23x和320y我需要然後返回以下左,右,上,下。根據觸摸位置確定移動方向

目前我使用的代碼不是非常可靠,我想知道如果有人可以建議我一個更好的方式做到這一點。

感謝

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

回答

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

這,當然,仍然不是最好看的代碼,但由於它所需要做的,這不是最糟糕的,我想。

+0

謝謝,完美的作品 – 2012-07-20 08:14:37

+0

感謝大家幫助 – 2012-07-20 08:14:50

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 
+0

給出原始問題,如何計算'dir'不是微不足道的(只有一個樣本,而不是兩個)。 – KillianDS 2012-07-20 07:54:58

+0

@KillianDS:如果只有一次觸摸,就無法確定方向。第二點應該以任何方式選擇 – Andrew 2012-07-20 07:59:16

+0

對不起,我可能沒有讓自己清楚。根據他們觸摸的屏幕區域,我想確定是左移,右移,上移還是下移,如果他們點擊大部分朝向屏幕的左側,並且不顯着上下,我會返回左側,這是否會使感? – 2012-07-20 08:03:02

2

就可以計算出基於舊的和新的位置的矢量:newX - oldX,newY - oldY,這可以用作角度,用於確定方向,只需將範圍0-360(角度)轉換爲0-3(枚舉值)即可。對於更精確的方法中,確定基於所述新的位置

方向有效範圍內的矢量變換爲角度[0〜2 * PI]之前作簡短的延遲(0.1秒)使用

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

最簡單的方法:

聲明這個結構。在TouchesEnded

CGPoint    mSwipTouch1; 
CGPoint    mSwipTouch2; 

初始化mSwipTouch1中的touchesBegan和mSwipTouch2:

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

使用這兩個成員變量。

-(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;  
    } 
}