Android game Multitouch

I am currently developing a game in which a user controls a ship using the joystick on the screen on the left side of the screen and fires by pressing the right side of the screen. However, my attempts at multi-touch were unsuccessful. When the user first touches the joystick and then fires, it works fine, but when the user touches the stick during firing, the user cannot drag the joystick. I'm still new to android, so any help would be greatly appreciated. I will insert the code below.

@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; } 
+7
source share
1 answer

Given that you can manipulate the joystick and fire button separately, it is reasonable that you correctly evaluate the screen size, and everything else about finding a pointer next to your game object is correct. I read about problems with some versions of Android and multi touch, but let me assume that this is not a problem.

The tricky thing with MotionEvent is that it runs for multiple pointers, and if you're interested in touch and movement, you need to consider all possible pointers. I think the problem may be with your approach.

Instead of determining what the user is touching and then figuring out what to do, given the different types of events, you should find out what type of event is happening and then determine which object the user is interacting with. This will make your code a little cleaner and make it easier to identify problems in the future.

I took your example above and rewrote it as shown below. In this example, there will simply be text on the screen to show what / where the user is touching. It can detect the joystick touch after the fire button and vice versa.

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; } } } 
+1
source

All Articles