【问题标题】:How to Implement Swipe In Android Game Without View如何在没有视图的情况下在 Android 游戏中实现滑动
【发布时间】:2014-12-30 08:22:59
【问题描述】:

我正在尝试在 Android 上制作一个 Snake 游戏,其中蛇通过滑动手势移动。

我已经尝试了很多方法来完成这项工作,但它们似乎都不适合我。 我还没有实现视图 - 这会是个问题吗?

这是我尝试根据之前的 StackOverflow 问题 - Android: How to handle right to left swipe gestures 实现的示例。

我按照指示创建了 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 堆栈跟踪吗? ...因此,如果您的问题尚未解决

标签: android user-interface android-view swipe gesture-recognition


【解决方案1】:

您可以通过两种方式做到这一点:

选项 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 的回答。

【讨论】:

    【解决方案2】:

    您应该将您的 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();
      }
      

      【讨论】:

        【解决方案4】:

        如果你可以访问触摸事件,那么试试这个

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-29
          • 1970-01-01
          • 1970-01-01
          • 2014-10-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多