我在做一个简单的比赛,三场比赛,类似宝石迷阵,我只是想通过触摸精灵对象移动精灵对象,然后将其移动一步在四个方向像左,右,上,下。我通过与移动的X和Y值比较上向下的X和Y值执行此操作。它的工作,但它完美的远!它是如此容易得到错误的值,如果动作不直。我的问题是:是否有改善这一点,使之更好的方法吗?
我也看了一下姿态,但是这似乎很复杂的一个surfaceview,我不得不使用。
@覆盖公共布尔onTouch(视图V,MotionEvent事件){ 开关(event.getAction()){ 案例MotionEvent.ACTION_DOWN: Log.i(测试,下移); touchActionDownX =(int)的event.getX(); touchActionDownY =(int)的event.getY(); touchActionMoveStatus =真; gameLoop.touchX =(int)的event.getX(); gameLoop.touchY =(int)的event.getY(); gameLoop.touchActionDown = TRUE; 打破; 案例MotionEvent.ACTION_POINTER_UP: touchActionMoveStatus =真; 打破; 案例MotionEvent.ACTION_MOVE: //Log.i(\"test\",\"Move); gameLoop.touchActionMove = TRUE; 如果(touchActionMoveStatus){ touchActionMoveX =(int)的event.getX(); touchActionMoveY =(int)的event.getY(); 如果(touchActionMoveX< touchActionDownX) Log.i(测试,左移); 否则,如果(touchActionMoveX> touchActionDownX) Log.i(测试,右移); 否则,如果(touchActionMoveY< touchActionDownY) Log.i(测试,上移); 否则,如果(touchActionMoveY> touchActionDownY) Log.i(测试,下移); touchActionMoveStatus = FALSE; //将设置为true,当指针达 } 打破; } //返回false; 返回true; //这得到的坐标所有的时间}
解决方案
尝试是这样的:
@覆盖公共布尔onTouch(视图V,MotionEvent事件){ //你可能与价值发挥,并使其密度有关。 INT阈值= 10; 开关(event.getAction()){ 案例MotionEvent.ACTION_DOWN: Log.i(测试,下移); touchActionDownX =(int)的event.getX(); touchActionDownY =(int)的event.getY(); touchActionMoveStatus =真; gameLoop.touchX =(int)的event.getX(); gameLoop.touchY =(int)的event.getY(); gameLoop.touchActionDown = TRUE; 打破; 案例MotionEvent.ACTION_POINTER_UP: touchActionMoveStatus = FALSE; 打破; 案例MotionEvent.ACTION_MOVE: //Log.i(\"test\",\"Move); gameLoop.touchActionMove = TRUE; 如果(touchActionMoveStatus){ touchActionMoveX =(int)的event.getX(); touchActionMoveY =(int)的event.getY(); 如果(touchActionMoveX≤(touchActionDownX - 阈)及及(touchActionMoveY>(touchActionDownY - 阈值))及及(touchActionMoveY(touchActionDownY +阈值))){ Log.i(测试,左移); //如果离开,此举是大于阈值不小于阈值上下更大 touchActionMoveStatus = FALSE; } 否则如果(touchActionMoveX>(touchActionDownX +阈)及及(touchActionMoveY>(touchActionDownY - 阈值))及及(touchActionMoveY≤(touchActionDownY +阈值))){ Log.i(测试,右移); //如果此举权利是大于阈值大于阈值和不大于或 touchActionMoveStatus = FALSE; } 否则如果(touchActionMoveY≤(touchActionDownY - 阈)及及(touchActionMoveX>(touchActionDownX - 阈值))及及(touchActionMoveX≤(touchActionDownX +阈值))){ Log.i(测试,上移); //如果拉升明显高于左或右的门槛大于阈值不大于 touchActionMoveStatus = FALSE; } 否则如果(touchActionMoveY>(touchActionDownY +阈)及及(touchActionMoveX>(touchActionDownX - 阈值))及及(touchActionMoveX≤(touchActionDownX +阈值))){ Log.i(测试,下移); //如果向下移动比向左或向右的阈值大于阈值不大于 touchActionMoveStatus = FALSE; } } 打破; } //返回false; 返回true; //这得到的坐标所有的时间}
或者使用比例:
@覆盖公共布尔onTouch(视图V,MotionEvent事件){ //你可能与价值的发挥。 //两个值意味着您需要用户的两倍作为移动 远的方向//他们打算比任何垂直方向移动。 浮动阈值= 2.0; 开关(event.getAction()){ 案例MotionEvent.ACTION_DOWN: Log.i(测试,下移); touchActionDownX =(int)的event.getX(); touchActionDownY =(int)的event.getY(); touchActionMoveStatus =真; gameLoop.touchX =(int)的event.getX(); gameLoop.touchY =(int)的event.getY(); gameLoop.touchActionDown = TRUE; 打破; 案例MotionEvent.ACTION_POINTER_UP: touchActionMoveStatus =真; 打破; 案例MotionEvent.ACTION_MOVE: //Log.i(\"test\",\"Move); gameLoop.touchActionMove = TRUE; 如果(touchActionMoveStatus){ touchActionMoveX =(int)的event.getX(); touchActionMoveY =(int)的event.getY(); //我没有测试此所以你可能有几个错别字纠正。 浮ratioLeftRight = Math.abs(touchActionMoveX - touchActionDownX)/Math.abs(touchActionMoveY - touchActionDownY) 浮ratioUpDown = Math.abs(touchActionMoveY - touchActionDownY)/Math.abs(touchActionMoveX - touchActionDownX) 如果(touchActionMoveX< touchActionDownX&放大器;&安培; ratioLeftRight>阈值){ Log.i(测试,左移); touchActionMoveStatus = FALSE; } 否则,如果(touchActionMoveX> touchActionDownX和放大器;&安培; ratioLeftRight>阈值){ Log.i(测试,右移); touchActionMoveStatus = FALSE; } 否则,如果(touchActionMoveY< touchActionDownY&放大器;&安培; ratioUpDown>阈值){ Log.i(测试,上移); touchActionMoveStatus = FALSE; } 否则,如果(touchActionMoveY> touchActionDownY和放大器;&安培; ratioUpDown>阈值){ Log.i(测试,下移); touchActionMoveStatus = FALSE; } } 打破; } //返回false; 返回true; //这得到的坐标所有的时间}
I'm doing a simple match-three game, similar to Bejeweled and I just want to move sprite objects by touching the sprite object and then move it one step in four directions like left, right, up and down. I do this by comparing the X and Y values on Down with the X and Y values on Move. It's working but it's far from perfect! It's so easy to get a wrong value if the movement isn't straight. My questions is: is there a way to improve this and make it better?
I have also looked at gesture, but this seems very complicated to use with a surfaceview that I have.
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = true;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
if(touchActionMoveX < touchActionDownX)
Log.i("test","Move Left");
else if(touchActionMoveX > touchActionDownX)
Log.i("test","Move Right");
else if(touchActionMoveY < touchActionDownY)
Log.i("test","Move Up");
else if(touchActionMoveY > touchActionDownY)
Log.i("test","Move Down");
touchActionMoveStatus = false; // Will be set to true when pointer is up
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
解决方案
Try something like this:
@Override
public boolean onTouch(View v, MotionEvent event) {
//You may have to play with the value and make it density dependant.
int threshold = 10;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = false;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
if(touchActionMoveX < (touchActionDownX - threshold) && (touchActionMoveY > (touchActionDownY - threshold)) && (touchActionMoveY (touchActionDownY + threshold))){
Log.i("test","Move Left");//If the move left was greater than the threshold and not greater than the threshold up or down
touchActionMoveStatus = false;
}
else if(touchActionMoveX > (touchActionDownX + threshold) && (touchActionMoveY > (touchActionDownY - threshold)) && (touchActionMoveY < (touchActionDownY + threshold))){
Log.i("test","Move Right");//If the move right was greater than the threshold and not greater than the threshold up or
touchActionMoveStatus = false;
}
else if(touchActionMoveY < (touchActionDownY - threshold) && (touchActionMoveX > (touchActionDownX - threshold)) && (touchActionMoveX < (touchActionDownX + threshold))){
Log.i("test","Move Up");//If the move up was greater than the threshold and not greater than the threshold left or right
touchActionMoveStatus = false;
}
else if(touchActionMoveY > (touchActionDownY + threshold) && (touchActionMoveX > (touchActionDownX - threshold)) && (touchActionMoveX < (touchActionDownX + threshold))){
Log.i("test","Move Down");//If the move down was greater than the threshold and not greater than the threshold left or right
touchActionMoveStatus = false;
}
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}
Or use a ratio:
@Override
public boolean onTouch(View v, MotionEvent event) {
//You may have to play with the value.
//A value of two means you require the user to move twice as
//far in the direction they intend to move than any perpendicular direction.
float threshold = 2.0;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i("test","Down");
touchActionDownX = (int)event.getX();
touchActionDownY = (int)event.getY();
touchActionMoveStatus = true;
gameLoop.touchX = (int)event.getX();
gameLoop.touchY = (int)event.getY();
gameLoop.touchActionDown = true;
break;
case MotionEvent.ACTION_POINTER_UP:
touchActionMoveStatus = true;
break;
case MotionEvent.ACTION_MOVE:
//Log.i("test","Move");
gameLoop.touchActionMove = true;
if(touchActionMoveStatus) {
touchActionMoveX = (int)event.getX();
touchActionMoveY = (int)event.getY();
// I haven't tested this so you may have a few typos to correct.
float ratioLeftRight = Math.abs(touchActionMoveX - touchActionDownX)/Math.abs(touchActionMoveY - touchActionDownY)
float ratioUpDown = Math.abs(touchActionMoveY - touchActionDownY)/Math.abs(touchActionMoveX - touchActionDownX)
if(touchActionMoveX < touchActionDownX && ratioLeftRight > threshold){
Log.i("test","Move Left");
touchActionMoveStatus = false;
}
else if(touchActionMoveX > touchActionDownX && ratioLeftRight > threshold){
Log.i("test","Move Right");
touchActionMoveStatus = false;
}
else if(touchActionMoveY < touchActionDownY && ratioUpDown > threshold){
Log.i("test","Move Up");
touchActionMoveStatus = false;
}
else if(touchActionMoveY > touchActionDownY && ratioUpDown > threshold){
Log.i("test","Move Down");
touchActionMoveStatus = false;
}
}
break;
}
// return false;
return true; // This gets the coordinates all the time
}