我正在尝试找出根据用户触摸屏幕确定要移动的方向的最佳方法。所以说我得到一个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;
}
答案 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;
}
}