Pull to refresh
0

Создание многопользовательского интерфейса с поддержкой сенсорного управления для Windows

Reading time 5 min
Views 6.3K
Original author: Stevan Rogers

Моноблоки впервые появились в середине 1990-х годов и с тех пор широко используются в различных сферах. К сожалению, в настоящий момент интерфейс прикладного программирования (API) Windows не располагает достаточными средствами для создания приложений для двух или более пользователей, использующих одновременно один моноблок. Однако это не значит, что разработчики не могут использовать свои собственные. При разработке интерфейса самое главное сделать так, чтобы приложением было легко пользоваться и чтобы оно правильно воспринимало команды ввода.
Ниже мы рассмотрим, какие средства API Windows можно использовать для разработки приложений с сенсорным управлением, а также продемонстрируем, как с их помощью создать простую многопользовательскую игру.

Создание интерфейса пользователя

Современные сенсорные экраны не способны определить, кто из пользователей (если их несколько) коснулся дисплея. В каких-то случаях этим можно пренебречь. Например, в настольной игре совсем не важно, кто из игроков перемещает фишки по полю, так как за этим следят сами пользователи.
Другое дело, когда необходимо правильно определять команды, поступающие от каждого игрока и обеспечить одновременное взаимодействие с интерфейсом. В этом случае разработчик должен создать наиболее эффективный способ определения того, кто из игроков коснулся экрана. Как правило, для этого делят экран на несколько частей (каждая часть для одного игрока). Пользователи должны сами следить за тем, чтобы не выходить за границы своей зоны. Естественно, существуют и другие методы создания многопользовательского интерфейса (например, с помощью эвристических средств), однако в этой статье они не освещаются.

API Windows
Windows поддерживает два основных формата сенсорных команд. Первый — это сообщения WM_TOUCH. Они отвечают только за первичные данные, поэтому приложение должно само обработать и выполнить поступающие команды.
Второй формат — WM_GESTURE. Это сообщение генерируется при использовании одного из жестов управления Windows, например масштабирования с помощью разведения и сведения пальцев, перетаскивания элементов и т. д. Благодаря их наличию задача разработчика существенно упрощается, поскольку операционная система может сама распознавать жесты управления и касания экрана и передавать их приложению в удобном для обработки виде.
В настоящий момент в Windows поддерживаются только сенсорные команды, поступающие от одного пользователя (руки), поэтому использовать сообщения WM_GESTURE для распознавания касаний нескольких игроков в нашем приложении не получится.
Кроме того, важно помнить, что API-интерфейс определяет координаты касаний по отношению ко всему экрану (они измеряются в сотых долях пикселя), а не только внутри окна программы. Если нужно получить именно координаты в окне, следует конвертировать их с помощью функции ScreenToClient().

Пример приложения
В качестве примера мы решили воссоздать классический симулятор настольного тенниса — игру Pong, и наделить ее сенсорным управлением. Игровой процесс состоит в том, что игроки передвигают ракетки по вертикали, отбивая мячик на сторону соперника. Когда мячик достигает одной из границ поля (по вертикали), игрок на противоположной стороне получает очко.
Мячик двигается по экрану по диагонали. После каждого движения приложение проверяет, не встретил ли он препятствие. Если мячик ударяется о верхнюю или нижнюю границы игрового поля, его вертикальная траектория изменяется в соответствии с углом столкновения. Если он ударяется о ракетку или о вертикальную границу окна, его горизонтальная траектория также изменяется на противоположную.
Обработка перемещения мяча происходит в отдельном потоке самого приложения для обеспечения плавности движения во время выполнения сенсорных команд.
Рендеринг графики осуществляется стандартными вызовами интерфейса графических устройств (GDI) Windows. В качестве ракеток служат обычные прямоугольники, в качестве мяча — круг. Счет матча отображается как текст на фоне. При создании этого приложения не использовались растровые отображения объектов или другие графические средства. Пример интерфейса показан на рисунке ниже. Нажмите на него, чтобы просмотреть видеоролик о работе приложения.


Рисунок 1. Стандартный интерфейс для двух пользователей

Интерфейс для двух пользователей с поддержкой сенсорного управления

Чтобы игра воспринимала касания каждого пользователя, мы разделили экран на две части: игрок 1 находится слева, игрок 2 — справа.
Каждый раз, когда происходит событие WM_TOUCH, программа получает полный список точек касания (пример кода 1). В нем может содержаться от одной до нескольких записей (максимальное количество точек зависит от возможностей устройства). Затем производится итерация, которая позволяет определить координаты каждого касания по осям X и Y.

Пример кода 1
1	…
2	bret = GetTouchInputInfo(
3	(HTOUCHINPUT)lparam,
4	data.geometry_data.touch_inputs_count,
5	data.geometry_data.touch_inputs,
6	sizeof(TOUCHINPUT)
7	);
8	assert(bret != FALSE);
9	// 	
10	// обработка сенсорных команд
11	// 	
12	for(i = 0; i < data.geometry_data.touch_inputs_count; i++)
13	{
14	touch_input = &data.geometry_data.touch_inputs[i];
15	// 	
16	//преобразование сотых долей пикселя в пиксели
17	// 	
18	x = touch_input->x / 100;
19	y = touch_input->y / 100;)
20	{
21	…

Далее необходимо определить, с какой стороны произошло касание, после чего обновить вертикальное расположение ракетки так, чтобы оно совпадало с положением пальца игрока (пример кода 2). Таким образом будет происходить перемещение ракетки по полю.

Пример кода 2
1	…
2	if (x < (ULONG)((data.graphic_data.rect.right – data.graphic_data.rect.left) /
	2))
3	{
4	// 	
5	// разделение экрана для двух пользователей
6	// 	
7	Data.geometry_data.p1y = y;
8	}else{
9	Data.geometry_data.p2y = y;
10	}
11	bret = move_paddles(&data);
12	assert(bret == TRUE);
13	{

Так как приложение обрабатывает все команды ввода, игроки могут не только одновременно нажимать на экран, но и выполнять несколько касаний. При этом положение ракетки будет определяться по последнему зарегистрированному касанию.

Адаптация приложения для четырех пользователей
Чтобы адаптировать приложение для четырех пользователей, необходимо изменить игровое поле и активные зоны игроков.
Мы добавили две ракетки и два табло со счетом внизу и вверху экрана. Разграничительные линии игровых зон приобрели форму буквы «Х», разделив окно приложения на четыре треугольника (рисунок 2).


Рисунок 2. Разделение игровых зон для четырех игроков

На рисунке 3 показано, как приложение определяет, в какой из зон произошло касание экрана.


Рисунок 3. Определение зоны сенсорной команды

При разделении экрана на четыре зоны определить, в какой из них произошло касание, становится сложнее (пример кода 3).

Пример кода 3
1
2	if(touch point.y > (LONG)(((float)data.graphic data.rect.bottom /
data.graphic data.rect.right) * touch point.x)) {
3	if(touch point.y > (LONG)((((float)data.graphic data.rect.bottom /
data.graphic data.rect.right) * -1) * touch point.x) +
data.graphic data.rect.bottom){
4	data.geometry data.p4x = touch point.x;
5	}else{
6	data.geometry data.ply = touch point.y;}
7	}else{
8	if(touchpoint.y < (LONG)((((float)data.graphicdata.rect.bottom /
data.graphic data.rect.right) * -1) * touch point.x) +
data.graphicdata.rect.bottom)
9	{
10	data.geometry data.p3x = touch point.x;
11	}else{
12	data.geometry data.p2y = touch point.y;
13	}
14	}
15	...


Заключение

При создании многопользовательских приложений с сенсорным управлением для Windows 7 и более поздних версий используйте сообщения WM_TOUCH и WM_GESTURES. Если вы найдете наиболее эффективный способ, как определить, в какой из игровых зон происходит касание, разработка приложения даже для четырех одновременно играющих пользователей не составит большого труда.
Tags:
Hubs:
+9
Comments 7
Comments Comments 7

Articles

Information

Website
www.intel.ru
Registered
Founded
Employees
5,001–10,000 employees
Location
США
Representative
Анастасия Казантаева