2012-02-24 20 views
7

Actualmente estoy en el proceso de hacer un juego donde el usuario controla un barco con un joystick en pantalla en el lado izquierdo de la pantalla y dispara tocando el lado derecho de la pantalla. Sin embargo, mis intentos de multitouch han sido infructuosos. Cuando el usuario toca el joystick primero y luego lo dispara, funciona perfectamente, pero cuando el usuario toca el stick mientras dispara, el usuario no puede arrastrar el joystick. Todavía soy nuevo en Android, por lo que cualquier ayuda sería muy apreciada. Pegaré el código a continuación.Android Multitouch Game

@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; 
} 
+0

Por favor, intente si es una cosa de hardware. Algunos dispositivos de Google tienen problemas extraños con multitouch: https://play.google.com/store/apps/details?id=multitouchpro.tests&hl=de – devsnd

+0

No creo que sea una cosa de hardware. El toque múltiple funciona bien en mi teléfono. Lo he estado probando en mi galaxy s2 – user1229888

Respuesta

1

considerando que se puede manipular el botón de la palanca y el fuego de forma aislada, es lógico pensar que te van a dar las dimensiones de la pantalla correcta y todo lo demás en la detección de proximidad de un puntero al objeto del juego es la correcta. He leído sobre problemas con ciertas versiones de Android y multitáctiles, pero supongamos que ese no es el problema.

Lo difícil con un MotionEvent es que se dispara para punteros múltiples y que si está interesado en los toques y el movimiento debe tener en cuenta todos los punteros posibles. Creo que el problema puede estar en su enfoque.

En lugar de determinar qué está tocando el usuario y luego averiguar qué hacer dados los diferentes tipos de eventos, debe averiguar qué tipo de evento está ocurriendo y luego determinar con qué objeto está interactuando el usuario. Esto hará que su código sea un poco más limpio y hará que sea más fácil detectar problemas en el futuro.

Tomé su ejemplo anterior y lo reescribí como se muestra a continuación. Este ejemplo solo escribirá texto en la pantalla para mostrar qué/dónde está tocando el usuario. Puede determinar los toques del joystick después del botón de disparo y viceversa.

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

}