Розробка програм для Windows Phone/Акселерометр

Матеріал з Вікіпідручника

Розробка програм для Windows Phone[ред.]

Апарат Windows Phones містить у собі акселерометр — це невеликий електромеханічний пристрій який безпосередньо вимірює силу, яка у фізиці має назву — сила прискорення.

Загальні відомості[ред.]

Коли телефон знаходиться у положенні спокою, акселерометр також фіксує силу тяжіння, отже акселерометр також може дати інформацію про положення телефону відносно землі. Акселерометр також реагує на рухи телефону, такі як струси та ривки, що може бути використане як інформативний сигнал для вашої гри чи програми.

Вимірювання акселерометра зручно представляти у вигляді тривимірного вектора (x, y, z), який вказує напрям прискорення у просторі і його величину. Значення довжини вектора можна отримати із тривимірного вектора за допомогою теореми Піфагора:

XNA має визначення типу для тривимірного вектора ; Silverlight — ні.

Використовується тривимірна система координат, така сама як використовується для створення ігор на основі XNA — це правостороння декартова система координат. При будь-якому розташуванні телефону, позитивний напрямок осі Y вказує на верх, вісь X направлена зліва направо у площині екрана телефону. Вісь Z буде направлено прямо на вас.

Якщо ви повернете телефон на 90° за годинниковою стрілкою вектор акселерометра матиме значення (–1, 0, 0), якщо ви перевернете низом до гори — отримаєте значення (0, 1, 0), якщо ви опустите руки вниз тримаючи телефон дисплеєм вверх до себе, отримаєте вектор (0, 0, –1).

Звичайно, значення вектора рідко будуть мати цілі значення, і його довжина буде різною.

Теоретично, якщо ваш телефон буде здійснювати вільне падіння вектор буде нульовим.

Робота з акселерометром в програмі[ред.]

Для того, щоб мати змогу працювати з акселерометром, вам необхідно під'єднати бібліотеку Microsoft.Devices.Sensors, і прописати директиву using для простору імен Microsoft.Devices.Sensors. А у файлі WMAppManifest.xml, вам необхідно прописати наступне:

<Capability Name="ID_CAP_SENSORS" />


Це зроблено по замовченню у проєкті.

Далі вам необхідно створити екземпляр класу Accelerometer, назначити обробник події для ReadingChanging і викликати метод Start.

public MainPage() 
{ 
   InitializeComponent(); 
   Accelerometer acc = new Accelerometer(); acc.ReadingChanged += OnAccelerometerReadingChanged; 
   try 
   { 
      acc.Start(); 
   } 
   catch (Exception exc) 
   { 
      txtblk.Text = exc.Message; 
   } 
}


Клас Accelerometer також має методи Stop і Dispose.

У Silvrlight програмі метод обробки події ReadingChanged отримує аргументи зібрані у класі AccelerometerReadingEventArgs. Об’єкт має поля X, Y, and Z типу double, які несуть в собі значення вектора і поле DateTimeOffset типу TimeStamp.

Для прикладу напишемо простий код для Silverlight програми, яка виконує прості дії по реєстрації інформації отриманої з акселерометра і відображенню її у текстовому полі TextBlock на екрані.

Слід зазначити, що із методу OnAccelerometerReadingChanged ви не маєте прямого доступу до елементу TextBlock і до його поля Text, оскільки обробник події виконується в іншому потоці.

Для розв'язання цієї задачі існує клас Dispatcher об’явлений у просторі System.Windows.Threading. За допомогою цього класу ви можете ставити в чергу задачі від іншого потоку, основному потоку в якому створено графічні елементи. Екземпляр класу Dispatcher, доступний як поле класу DependencyObject, від якого унаслідуються графічні компоненти.

Для того, щоб працювати з диспетчером вам необхідно створити делегат і метод який буде виконувати дії по зміні тексту і який відповідає формату описаному за допомогою делегату. Делегат і метод нічого не мають повертати.

delegate void SetTextBlockTextDelegate(TextBlock txtblk, string text);

void SetTextBlockText(TextBlock txtblk, string text) 
{ 
   txtblk.Text = text; 
}


У методі OnAccelerometerReadingChanged, перше що вам необхідно виконати метод CheckAccess, щоб перевірити можливість виклику методу SetTextBlockText напряму, якщо ні, то викликати метод диспетчера – BeginInvoke, першим аргументом якого буде екземпляр делегату для методу SetTextBlockText за яким слідують усі необхідні для цього методу параметри:

void OnAccelerometerReadingChanged(object sender, AccelerometerReadingEventArgs args) 
{ 
   string str = String.Format("X = {0:F2}\n" + 
                              "Y = {1:F2}\n" + 
                              "Z = {2:F2}\n\n" + 
                              "Magnitude = {3:F2}\n\n" + "{4}", 
                              args.X, args.Y, args.Z, 
                              Math.Sqrt(args.X * args.X + args.Y * args.Y + args.Z * args.Z), args.Timestamp); 

   if (txtblk.CheckAccess()) { 
      SetTextBlockText(txtblk, str); 
   } 
   else 
   { 
      txtblk.Dispatcher.BeginInvoke(new SetTextBlockTextDelegate(SetTextBlockText), txtblk, str); 
   } 
}


Література[ред.]