0

ユーザーが画面に触れたことに基づいて、移動する方向を決定する最良の方法を見つけようとしています。つまり、2 次元の位置 23x と 320y を取得すると、次の 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

4 に答える 4

2

古い位置と新しい位置に基づいてベクトルを計算できます: newX - oldX、newY - oldY。これを角度として使用して、方向を決定するために、範囲 0-360 (角度) を 0-3 (enum) に変換するだけです。値)。より正確な方法では、新しい位置に基づいて方向を決定する前に短い遅延 (0.1 秒) を作成します。

ベクトルを [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 }
于 2012-07-20T07:58:57.033 に答える
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;
}

もちろん、これはまだ見栄えの良いコードではありませんが、実行する必要があることを考えると、最悪のコードではないと思います。

于 2012-07-20T08:05:55.350 に答える
1

最も簡単な方法:

この構造体を宣言します。

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

次の 2 つのメンバー変数を使用します。

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;    
    }
}
于 2012-07-20T08:14:35.620 に答える
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するには、ポイントする必要があります。1 つは、現在のタッチ位置です。2 つ目は、prev touch position位置または固定点 (画面の中心など) にすることができます。

このポイントがある場合:

vec2 dir = currentTouchPoint - prevPoint; //or origin
于 2012-07-20T07:53:10.557 に答える