Android多点触控游戏

7

我正在制作一款游戏,用户通过屏幕左侧的虚拟摇杆控制飞船,并在屏幕右侧点击来发射武器。然而,我的多点触控尝试一直不成功。当用户先触摸摇杆再发射时,它可以完美工作,但是当用户在发射过程中触摸摇杆时,用户无法拖动摇杆。由于我对安卓还不熟悉,所以非常感谢任何帮助。下面是代码:

@Override
public boolean onTouch(View v, MotionEvent event) {
    int action = event.getAction() & MotionEvent.ACTION_MASK;
    int pointerIndex=(event.getAction()&MotionEvent.ACTION_POINTER_ID_MASK) 
    >>MotionEvent.ACTION_POINTER_ID_SHIFT;
    int pI = event.getPointerId(pointerIndex);
    //On screen joystick
    if(event.getX(pI)<pad.getWidth()+(screenWidth*.18)&&event.getX(pI)>0&&event.getY(pI)<(screenHeight)&&event.getY(pI)>(screenHeight-(0.42*screenHeight))){
        sx2=event.getX(pI)-(stick.getWidth()/2);
        sy2=event.getY(pI);
        angle=(Math.atan2((sy2-sy),(sx2-sx)));
    }
    //firing system
    if(event.getX(pI)>screenWidth/3){
        switch(action){
        case MotionEvent.ACTION_DOWN:
            incrementRunnable.run();
            break;
        case MotionEvent.ACTION_POINTER_DOWN:
            incrementRunnable.run();
            break;
        case MotionEvent.ACTION_UP:
            handler.removeCallbacks(incrementRunnable);
            break;
        case MotionEvent.ACTION_POINTER_UP:
            handler.removeCallbacks(incrementRunnable);
            break;
        }

    }
    //reset joystick
    if(event.getAction()==MotionEvent.ACTION_UP||event.getAction()==MotionEvent.ACTION_POINTER_UP){
        sx2=sx;
        sy2=sy;
        handler.removeCallbacks(incrementRunnable);
    }
    return true;
}

请尝试检查是否是硬件问题。有些谷歌设备在多点触控方面存在奇怪的问题:https://play.google.com/store/apps/details?id=multitouchpro.tests&hl=de - devsnd
我认为这不是硬件问题。在我的手机上,多点触控效果很好。我已经在我的Galaxy S2上进行了测试。 - user1229888
1个回答

1

考虑到您可以独立操作操纵杆和射击按钮,因此可以推断您正确获取了屏幕尺寸以及检测指针靠近游戏对象的其他所有内容。我已经阅读过关于某些Android版本和多点触摸的问题,但让我们假设这不是问题所在。

MotionEvent 的棘手之处在于它会为多个指针触发,如果您对触摸和移动感兴趣,则需要考虑所有可能的指针。我认为问题可能在于您的方法。

与其确定用户正在触摸什么,然后根据不同类型的事件确定要执行的操作,您应该确定正在发生的事件类型,然后确定用户正在与哪个对象交互。这将使您的代码更加简洁,并使未来更容易发现问题。

我采用了您上面的示例,并按如下所示进行了重写。此示例将只向屏幕写入文本,以显示用户触摸的内容/位置。它能够在射击按钮触碰后,确定操纵杆触碰,反之亦然。

MultiTouchGame.java

package com.droidhut.stackoverflow;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.TextView;

public class MultiTouchGame extends Activity implements OnTouchListener {
    StringBuilder builder = new StringBuilder();
    TextView textView;

    boolean[] joystickTouched = new boolean[10];
    boolean[] fireButtonTouched = new boolean[10];
    int joyX = 0;
    int joyY = 0;

    int screenHeight;
    int screenWidth;
    Pad pad = new Pad();

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView = new TextView(this);
        textView.setText("Touch and drag (multiple fingers supported)!");
        textView.setOnTouchListener(this);
        setContentView(textView);

        WindowManager mWinMgr = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics dm = new DisplayMetrics();
        mWinMgr.getDefaultDisplay().getMetrics(dm);
        screenHeight = dm.heightPixels;
        screenWidth = dm.widthPixels;

    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        int action = event.getAction() & MotionEvent.ACTION_MASK;
        int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
        int pI = event.getPointerId(pointerIndex);
        switch (action) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_POINTER_DOWN:
                joystickTouched[pI] = isPointerOnJoystick(event, pointerIndex);
                fireButtonTouched[pI] = isPointerOnFireButton(event, pointerIndex);
                break;
            case MotionEvent.ACTION_UP:        
            case MotionEvent.ACTION_POINTER_UP:
            case MotionEvent.ACTION_CANCEL:
                joystickTouched[pI] = false;
                fireButtonTouched[pI] = false;
                break;
            case MotionEvent.ACTION_MOVE:
                joystickTouched[pI] = isPointerOnJoystick(event, pointerIndex);
                fireButtonTouched[pI] = isPointerOnFireButton(event, pointerIndex);
                if (isTouchingJoystick()){
                    int index = getJoystickPointer();
                    if (index != -1 && index < event.getPointerCount()){
                        joyX = (int)event.getX(index);
                        joyY = (int)event.getY(index);
                    }
                }
                break;
        }

        updateTextView();       
        return true;
    }

    private boolean isPointerOnJoystick(MotionEvent event, int pointerIndex){
         return (event.getX(pointerIndex)<pad.getWidth()+(screenWidth*.18)&&event.getX(pointerIndex)>0&&
                 event.getY(pointerIndex)<(screenHeight)&&event.getY(pointerIndex)>(screenHeight-(0.42*screenHeight)));
    }

    private boolean isPointerOnFireButton(MotionEvent event, int pointerIndex){
        return (event.getX(pointerIndex)>screenWidth/3);
    }

    private boolean isTouchingJoystick(){
        for (int i = 0; i < joystickTouched.length; i++){
            if (joystickTouched[i]){
                return true;
            }
        }
        return false;
    }

    private boolean isTouchingFireButton(){
        for (int i = 0; i < fireButtonTouched.length; i++){
            if (fireButtonTouched[i]){
                return true;
            }
        }
        return false;
    }

    private int getJoystickPointer(){
        for (int i = 0; i < joystickTouched.length; i++){
            if (joystickTouched[i]){
                return i;
            }
        }

        return -1;
    }

    private void updateTextView() {
        builder.setLength(0);
        builder.append(String.format("screenWidth[%d], screenHeight[%d]\n",screenWidth, screenHeight));
        builder.append(String.format("joystickTouched[%s]\n", isTouchingJoystick()));
        builder.append(String.format("fireButtonTouched[%s]\n", isTouchingFireButton()));
        builder.append(String.format("joystickMovement[%d,%d]",joyX,joyY));

        textView.setText(builder.toString());
    }

    private static class Pad {
      public int getWidth(){
        return 200;
      }
    }

}

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