【问题标题】:Android Multitouch issue with game controllers游戏控制器的 Android 多点触控问题
【发布时间】:2013-06-20 18:59:27
【问题描述】:

我正在编写一个在屏幕上有两个软方向键的应用程序。我在尝试捕获和理解两个同时触摸的所有触摸事件时遇到了极大的困难,因为每个 ACTION_MOVE 事件都表示 id 等于 0。

我有两个“触摸”对象,当有触摸时,它们会通过管道进入碰撞检测系统。请记住,我有两个方向键,并且都需要同时具有控制能力。

有没有人有什么建议。这是我的 onTouchEvent 方法。请记住,可能很难理解上下文,因为我使用 cusomt 'touch' 游戏对象来检测与方向键的碰撞。

@Override
public void onTouchEvent(MotionEvent e)
{   
    int index = e.getActionIndex();


    int action = MotionEventCompat.getActionMasked(e);
    // Get the index of the pointer associated with the action.
    //index = MotionEventCompat.getActionIndex(e);

    int id = e.getPointerId(index);


    if(touch1.pointerID<0)
        touch1.pointerID = id;
    else
        touch2.pointerID = id;

    switch(action)
    {
        case MotionEvent.ACTION_DOWN:
        {
            if(id == touch1.pointerID)
            {
                touch1.setCollideable(true);
                touch1.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch1.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();
            }
            else if(id==touch2.pointerID)
            {
                touch2.setCollideable(true);
                touch2.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch2.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();

            }

            break;  
        }
        case MotionEvent.ACTION_POINTER_DOWN:
        {
            if(id == touch1.pointerID)
            {
                touch1.setCollideable(true);
                touch1.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch1.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();
            }
            else if(id==touch2.pointerID)
            {
                touch2.setCollideable(true);
                touch2.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch2.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();

            }
            break;
        }
        case MotionEvent.ACTION_UP:
        {
            if(id == touch1.pointerID)
            {
                touch1.setCollideable(false);
                touch1.pointerID = -1;
                touch1.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch1.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();
            }
            else if(id==touch2.pointerID)
            {
                touch2.setCollideable(false);
                touch2.pointerID = -1;
                touch2.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch2.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();

            }
            break;
        }
        case MotionEvent.ACTION_POINTER_UP:
        {
            if(id == touch1.pointerID)
            {
                touch1.setCollideable(false);
                touch1.pointerID = -1;
                touch1.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch1.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();
            }
            else if(id==touch2.pointerID)
            {
                touch2.setCollideable(false);
                touch2.pointerID = -1;
                touch2.getPosition().x = e.getX(index)*GameWorldProperties.getWidthRatio();
                touch2.getPosition().y = e.getY(index)*GameWorldProperties.getHeightRatio();

            }
            break;
        }
        case MotionEvent.ACTION_MOVE:
        {
                Log.d("pointer",String.format("Move index=%s id=%s", index,id));

                for(int i=0;i<e.getPointerCount();i++)
                {
                    Log.d("pointer",String.format("i=%s id=%s",i,e.getPointerId(i)));

                    touch1.setCollideable(true);
                    touch1.getPosition().x = e.getX(i)*GameWorldProperties.getWidthRatio();
                    touch1.getPosition().y = e.getY(i)*GameWorldProperties.getHeightRatio();

                    touch2.setCollideable(true);
                    touch2.getPosition().x = e.getX(i)*GameWorldProperties.getWidthRatio();
                    touch2.getPosition().y = e.getY(i)*GameWorldProperties.getHeightRatio();
                }

            break;
        }
        default:
        {
            break;
        }
    }

【问题讨论】:

    标签: android touch touch-event motionevent


    【解决方案1】:

    希望这会有所帮助。这是来自《Android 游戏编程入门》一书。

    public boolean onTouch(View v, MotionEvent event) {
        synchronized (this) {
            int action = event.getAction() & MotionEvent.ACTION_MASK;
            int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_ID_MASK) >> MotionEvent.ACTION_POINTER_ID_SHIFT;
            int pointerId = event.getPointerId(pointerIndex);
            TouchEvent touchEvent;
    
            switch (action) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN:
                touchEvent = touchEventPool.newObject();
                touchEvent.type = TouchEvent.TOUCH_DOWN;
                touchEvent.pointer = pointerId;
                touchEvent.x = touchX[pointerId] = (int) (event
                        .getX(pointerIndex) * scaleX);
                touchEvent.y = touchY[pointerId] = (int) (event
                        .getY(pointerIndex) * scaleY);
                isTouched[pointerId] = true;
                touchEventsBuffer.add(touchEvent);
                break;
    
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_CANCEL:
                touchEvent = touchEventPool.newObject();
                touchEvent.type = TouchEvent.TOUCH_UP;
                touchEvent.pointer = pointerId;
                touchEvent.x = touchX[pointerId] = (int) (event
                        .getX(pointerIndex) * scaleX);
                touchEvent.y = touchY[pointerId] = (int) (event
                        .getY(pointerIndex) * scaleY);
                isTouched[pointerId] = false;
                touchEventsBuffer.add(touchEvent);
                break;
    
            case MotionEvent.ACTION_MOVE:
                int pointerCount = event.getPointerCount();
                for (int i = 0; i < pointerCount; i++) {
                    pointerIndex = i;
                    pointerId = event.getPointerId(pointerIndex);
    
                    touchEvent = touchEventPool.newObject();
                    touchEvent.type = TouchEvent.TOUCH_DRAGGED;
                    touchEvent.pointer = pointerId;
                    touchEvent.x = touchX[pointerId] = (int) (event
                            .getX(pointerIndex) * scaleX);
                    touchEvent.y = touchY[pointerId] = (int) (event
                            .getY(pointerIndex) * scaleY);
                    touchEventsBuffer.add(touchEvent);
                }
                break;
            }
    
            return true;
        }
    }
    

    【讨论】:

    • 实际上,这确实有帮助!这告诉我,我不应该维护对触摸对象的引用,而应该简单地为每个动作生成一个新对象!说得通!谢谢!
    • 不客气。我真的推荐这本书。我从中学到了很多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-02
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多