如何在Android游戏中实现滑动操作而不使用View

13

我正在尝试在Android上制作一款贪吃蛇游戏,使蛇的移动通过滑动手势实现。

我尝试了很多方法来完成这个任务,但是似乎都不适用于我。 我还没有实现视图 - 这会成为问题吗?

这是我尝试根据之前的一个StackOverflow问题实现的样例 - Android:如何处理从右到左的滑动手势

我按照指示创建了OnSwipeTouchListener.java文件。 然而,我在使用中遇到了一点问题。

在GameScreen.java中(这里是所有触摸事件发生的地方),我添加了以下示例 -

onSwipeTouchListener = new OnSwipeTouchListener() {
public void onSwipeTop() {
    Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
  }
public void onSwipeRight() {
    Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show();
  }
public void onSwipeLeft() {
    Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show();
  }
public void onSwipeBottom() {
    Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show();
  }
};

imageView.setOnTouchListener(onSwipeTouchListener);

这会导致出现大量错误(主要涉及imageView),而且没有一个能够解决。

是否有人能提供适用于我的情况的其他滑动实现方式?


你能否贴出GameScreen类?还有哪些错误被抛出了?你能贴出logcat堆栈跟踪吗?......因此,如果你的问题还没有解决 - Nana Ghartey
4个回答

5
你可以通过两种方式完成此操作:
选项1:
在你的游戏底层活动类中实现:
class MyGestureDetector extends SimpleOnGestureListener {
        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {
            try {
                float slope = (e1.getY() - e2.getY()) / (e1.getX() - e2.getX());
                float angle = (float) Math.atan(slope);
                float angleInDegree = (float) Math.toDegrees(angle);
                // left to right
                if (e1.getX() - e2.getX() > 20 && Math.abs(velocityX) > 20) {
                    if ((angleInDegree < 45 && angleInDegree > -45)) {                      
          //code for left to right swipe should go here
        }
                    // right to left fling
                } else if (e2.getX() - e1.getX() > 20
                        && Math.abs(velocityX) > 20) {
                    if ((angleInDegree < 45 && angleInDegree > -45)) {
      //code for right to left swipe should go here

                    }
                }
                return true;
            } catch (Exception e) {
                // nothing
            }
            return false;
        }
    }

你可以注册任何视图以接收/监听手势:
 final GestureDetector  gestureDetector = new GestureDetector(new MyGestureDetector());
                gameView.setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });
         //the parent layout   
                findViewById(R.id.parent_layout).setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });
         //an image view
        findViewById(R.id.image_view).setOnTouchListener(new View.OnTouchListener() {
                    @Override
                    public boolean onTouch(View v, MotionEvent event) {
                        if (gestureDetector.onTouchEvent(event)) return false;
                        return false;
                    }
                });

选项2:

如果GameScreen类可以直接访问触摸事件,您可以读取它们并实现适用于滑动操作的逻辑。该代码与Mostafa Gazar的答案类似。


4

你应该将你的GameScreen发布为Nana Ghartey

假设你可以访问触摸数据,你可以执行以下操作

private static final int DEFAULT_THRESHOLD = 36;// Better to be something in dps.

... = new View.OnTouchListener() {

    int initialX = 0;
    int initialY = 0;
    final float slop = ViewConfiguration.get(context).getScaledTouchSlop();

    public boolean onTouch(final View view, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            initialX = (int) event.getX();
            initialY = (int) event.getY();
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            int currentX = (int) event.getX();
            int currentY = (int) event.getY();
            int offsetX = currentX - initialX;
            int offsetY = currentY - initialY;
            if (Math.abs(offsetX) > slop) {
                if (offsetX > DEFAULT_THRESHOLD) {
                    // TODO :: Do Right to Left action!
                } else if (offsetX < -DEFAULT_THRESHOLD) {
                    // TODO :: Do Left to Right action!
                }
            }
            if (Math.abs(offsetY) > slop) {
                if (offsetY > DEFAULT_THRESHOLD) {
                    // TODO :: Do Bottom to Top action!
                } else if (offsetY < -DEFAULT_THRESHOLD) {
                    // TODO :: Do Top to Bottom action!
                }
            }
        } else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
            // Do nothing!
        }
};

这种实现的好处在于用户在控制蛇的方向时不需要将手从屏幕上移开。


3

将超级方法放入您的代码中,示例如下:

public void onSwipeTop() {
    super.onSwipeTop();
    Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show();
}

2
如果您有触摸事件的访问权限,则可以尝试以下操作。
    int len = touchEvents.size();
    Graphics g = game.getGraphics();

    for (int i = 0; i < len; i++) {

        TouchEvent event = touchEvents.get(i);


        if (event.type == TouchEvent.TOUCH_DOWN)
        {
            x1=event.x;
            y1=event.y;
        }
        if (event.type == TouchEvent.TOUCH_UP)
        {
            x2=event.x;
            y2=event.y;
            dx=(x2-x1);
            dy=(y2-y1);
            tu=1;
        }

        if((tu==1) && (Math.abs(dx)>Math.abs(dy)))
        {
                if(dx>0)
                {
                    if(!(robot.getSpeedX()<0))
                    {
                    robot.stop();
                    robot.moveRight();
                    }
                }
                else
                {
                    if(!(robot.getSpeedX()>0))
                    {
                    robot.stop();
                    robot.moveLeft();
                    }
                }
                tu=0;
        }
        if((tu==1) && (Math.abs(dx)<=Math.abs(dy)))
        {
                if(dy>0)
                {
                    if(!(robot.getSpeedY()<0))
                    {
                    robot.stop();
                    robot.moveDown();
                    }
                }
                else
                {
                    if(!(robot.getSpeedY()>0))
                    {
                    robot.stop();
                    robot.moveUp();
                    }
                }
                tu=0;
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接