Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Java программирование > Java Мобильная разработка (Android)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.10.2014, 22:57   #1
ruN00b
Почетный нуб
Форумчанин
 
Аватар для ruN00b
 
Регистрация: 07.05.2013
Сообщений: 155
По умолчанию Android и MultiTouch

Всем привет. Делаю тут игрульку под Android, пытаясь создать два джойстика, столкнулся с проблемой мультитача.

Если нажать сначала на первый джойстик, а затем на второй, после отпустить сначала второй, а потом первый, то все будет хорошо, однако если отпустить сначала первый, то приложение вылетит.

Код массивов тача:
Код:
PPointR[] mStartPointers=new PPointR[16]; //Массив с начальными координатами тача
PPointR[] mActivePointers=new PPointR[16]; //Массив с последними координатами тача
float scw; //Ширина экрана
float sch; //Высота экрана
float scaw; //Ширина виртуального пикселя (игра пиксельная, scaw=scw/320)
float scah; //Высота виртуального пикселя (игра пиксельная, scah=sch/180)
Код джойстика:
Код:
	public class PJoystick{
		int x,y; //Координаты джойстика
		PStick pstick; //Подвижная часть джойстика, внутри нее только координаты, так что она на вылет влиять не может
		boolean visible=false; //Видим ли джойстик
		int bc; //Цвет джойстика
		int tid=-1; //Индекс тача
		public PJoystick(int xx,int yy,int bbc){x=xx; y=yy; bc=bbc; pstick=new PStick(0,0,bbc);}
		public void TapInit(){tid=-1; int to; for (int i=0;i<16;i++) {to=i; if (to>-1) if (mStartPointers[to]!=null) if (CheckPress(mStartPointers[to].x,mStartPointers[to].y)) {tid=i; break;}}} //Поиск тача в первом массиве
		public void Draw(Canvas c){ //Обработка касания и отрисовка джойстика
			if (visible){
				Paint p=new Paint();
				p.setColor(bc);
				DrawBitmap(c,joystick,new Rect(x,y,x+64,y+64),p);
				c.save();
				c.translate((float)x,(float)y);
				TapInit(); //Обновляем индекс тача
				boolean b=tid==-1; 
				if (!b) b=mStartPointers[tid]==null; //Проверяем, не существует ли такого тача
				if (b) {pstick.x=0; pstick.y=0;} else //Если истинно, обнуляем координаты подвижной части тача
				pstick.Process((int)(mActivePointers[findPointR(mActivePointers,tid)].x/scaw-(x+32)),(int)(mActivePointers[findPointR(mActivePointers,tid)].y/scah-(y+32))); //Иначе обновляем координаты подвижной части тача
				pstick.Draw(c); 
				c.restore();
				}
		}
		public boolean CheckPress(float xx,float yy){ //Проверка тача на нахождение в круге
			double x1=(xx)/scaw-x-32,y1=(yy)/scah-y-32;
			return (Math.sqrt(x1*x1+y1*y1)<=32);
		}
	}
Код обновления тача внутри кастомного View:
Код:
public boolean onTouchEvent(MotionEvent event)
		{
			int pointerIndex = event.getActionIndex();

			// get pointer ID
			int pointerId = event.getPointerId(pointerIndex);

			// get masked (not specific to a pointer) action
			int maskedAction = event.getActionMasked();

			switch (maskedAction) {

				case MotionEvent.ACTION_DOWN:
				case MotionEvent.ACTION_POINTER_DOWN: {
						// We have a new pointer. Lets add it to the list of pointers

						PointR f = new PointR(event.getX(pointerIndex),event.getY(pointerIndex),pointerIndex);
						PointR p = new PointR(event.getX(pointerIndex),event.getY(pointerIndex),pointerIndex);
						
						mActivePointers[pointerIndex]=f;
						mStartPointers[pointerIndex]=p;
						break;
					}
				case MotionEvent.ACTION_MOVE: { // a pointer was moved
						for (int size = event.getPointerCount(), i = 0; i < size; i++) {
							int x=i;
							if (x != -1) {
							PointR point = mActivePointers[x];
								point.x = event.getX(i);
								point.y = event.getY(i);
							}
						}
						break;
					}
				case MotionEvent.ACTION_UP:
				case MotionEvent.ACTION_POINTER_UP:
				case MotionEvent.ACTION_CANCEL: {
						int pid=pointerId;
						PointR p=mActivePointers[pid];
						panel1.OnFingerUp((int)p.x,(int)p.y);
						status1.OnFingerUp((int)p.x,(int)p.y);
						mStartPointers[pid]=null;
						mActivePointers[pid]=null;
						break;
					}
			}
			return true;
		}
Если какой-то еще код понадобится, обращайтесь, надеюсь, хоть кто-то разберется в данной проблеме, т.к. я над ней думал 2 недели
ruN00b вне форума Ответить с цитированием
Старый 22.10.2014, 18:55   #2
ruN00b
Почетный нуб
Форумчанин
 
Аватар для ruN00b
 
Регистрация: 07.05.2013
Сообщений: 155
По умолчанию

Нашел ошибку, столько времени угробил на ее поиски, а проблема была всего в одной строке кода. В OnTouchEvent, в проверке тача на MotionEvent.ACTION_MOVE нужно было к условию x!=-1 добавить mActivePointers[x]!=null.
ruN00b вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Android deployment ZuBy Общие вопросы Delphi 0 08.01.2014 09:34
датчики Android SAMOUCHKA Мобильные ОС (Android, iOS, Windows Phone) 1 13.07.2013 23:37
android emulator blacktener Java Мобильная разработка (Android) 0 12.08.2012 17:39
C# & Android Prizrak86 C# (си шарп) 1 17.02.2012 09:52
C++ Builder MultiTouch SlavaGrishko C++ Builder 2 08.06.2011 13:10